#[repr(u8)]pub enum GridRotation {
Show 48 variants
RXYZ = 0,
RXYz = 1,
RXyZ = 2,
RXyz = 3,
RxYZ = 4,
RxYz = 5,
RxyZ = 6,
Rxyz = 7,
RXZY = 8,
RXZy = 9,
RXzY = 10,
RXzy = 11,
RxZY = 12,
RxZy = 13,
RxzY = 14,
Rxzy = 15,
RYXZ = 16,
RYXz = 17,
RYxZ = 18,
RYxz = 19,
RyXZ = 20,
RyXz = 21,
RyxZ = 22,
Ryxz = 23,
RYZX = 24,
RYZx = 25,
RYzX = 26,
RYzx = 27,
RyZX = 28,
RyZx = 29,
RyzX = 30,
Ryzx = 31,
RZXY = 32,
RZXy = 33,
RZxY = 34,
RZxy = 35,
RzXY = 36,
RzXy = 37,
RzxY = 38,
Rzxy = 39,
RZYX = 40,
RZYx = 41,
RZyX = 42,
RZyx = 43,
RzYX = 44,
RzYx = 45,
RzyX = 46,
Rzyx = 47,
}Expand description
Represents a discrete (grid-aligned) rotation, or exchange of axes.
Compared to a GridMatrix, this cannot specify scale, translation, or skew;
it is used for identifying the rotations of blocks.
Each of the variant names specifies the three unit vectors which (x, y, z), respectively, should be multiplied by to perform the rotation. Lowercase refers to a negated unit vector.
See also:
Face6is less general, in that it specifies a single axis but not rotation about that axis.Face6::clockwise()andFace6::counterclockwise()can be used to obtainGridRotationvalues.
GridMatrixis more general, specifying an affine transformation.
§Serialization stability warning
This type implements [serde::Serialize] and [serde::Deserialize], but serialization
support is still experimental (as is the game data model in general). We do not guarantee that future versions of all-is-cubes
will be able to deserialize data which is serialized by this version.
Additionally, the serialization schema is designed with serde_json in mind. It is not
guaranteed that using a different data format crate, which may use a different subset of
the information exposed via [serde::Serialize], will produce stable results.
Variants§
RXYZ = 0
RXYz = 1
RXyZ = 2
RXyz = 3
RxYZ = 4
RxYz = 5
RxyZ = 6
Rxyz = 7
RXZY = 8
RXZy = 9
RXzY = 10
RXzy = 11
RxZY = 12
RxZy = 13
RxzY = 14
Rxzy = 15
RYXZ = 16
RYXz = 17
RYxZ = 18
RYxz = 19
RyXZ = 20
RyXz = 21
RyxZ = 22
Ryxz = 23
RYZX = 24
RYZx = 25
RYzX = 26
RYzx = 27
RyZX = 28
RyZx = 29
RyzX = 30
Ryzx = 31
RZXY = 32
RZXy = 33
RZxY = 34
RZxy = 35
RzXY = 36
RzXy = 37
RzxY = 38
Rzxy = 39
RZYX = 40
RZYx = 41
RZyX = 42
RZyx = 43
RzYX = 44
RzYx = 45
RzyX = 46
Rzyx = 47
Implementations§
Source§impl GridRotation
impl GridRotation
Sourcepub const ALL: [Self; 48]
pub const ALL: [Self; 48]
All 48 possible rotations.
Warning: TODO: The ordering of these rotations is not yet stable. The current ordering is based on the six axis permutations followed by rotations.
Sourcepub const ALL_BUT_REFLECTIONS: [Self; 24]
pub const ALL_BUT_REFLECTIONS: [Self; 24]
All possible rotations that are not reflections.
Warning: TODO: The ordering of these rotations is not yet stable.
Sourcepub fn from_basis(basis: impl Into<[Face6; 3]>) -> Self
pub fn from_basis(basis: impl Into<[Face6; 3]>) -> Self
Constructs a rotation from a basis: that is, the returned rotation will
rotate PX into basis[0], PY into basis[1], and PZ into basis[2].
Panics if the three provided axes are not mutually perpendicular.
Sourcepub fn from_to(source: Face6, destination: Face6, up: Face6) -> Option<Self>
pub fn from_to(source: Face6, destination: Face6, up: Face6) -> Option<Self>
Find the rotation (without reflection) which rotates source to destination.
and leaves up unaffected. (This might also be considered a “look at” operation).
If it is not possible to leave up unaffected, returns None. (Trying two
perpendicular up directions will always succeed.)
Sourcepub const fn to_positive_octant_transform(self, size: GridCoordinate) -> Gridgid
pub const fn to_positive_octant_transform(self, size: GridCoordinate) -> Gridgid
Expresses this rotation as a Gridgid transform which rotates “in place” the
points within the volume defined by coordinates in the range [0, size].
That is, a GridAab of that volume will be unchanged by rotation:
use all_is_cubes::block::Resolution;
use all_is_cubes::math::{Face6, GridAab, GridRotation};
let b = GridAab::for_block(Resolution::R8);
let rotation = Face6::PY.clockwise().to_positive_octant_transform(8);
assert_eq!(b.transform(rotation), Some(b));Such matrices are suitable for rotating the voxels of a block, provided
that the voxel coordinates are then transformed with GridMatrix::transform_cube,
not GridMatrix::transform_point
(due to the lower-corner format of cube coordinates).
let rotation = Face6::PY.clockwise().to_positive_octant_transform(4);
assert_eq!(rotation.transform_cube(Cube::new(0, 0, 0)), Cube::new(3, 0, 0));
assert_eq!(rotation.transform_cube(Cube::new(3, 0, 0)), Cube::new(3, 0, 3));
assert_eq!(rotation.transform_cube(Cube::new(3, 0, 3)), Cube::new(0, 0, 3));
assert_eq!(rotation.transform_cube(Cube::new(0, 0, 3)), Cube::new(0, 0, 0));Sourcepub fn to_rotation_matrix(self) -> GridMatrix
pub fn to_rotation_matrix(self) -> GridMatrix
Expresses this rotation as a matrix without any translation.
Sourcepub fn transform_vector(self, vector: GridVector) -> GridVector
pub fn transform_vector(self, vector: GridVector) -> GridVector
Rotate the vector by this rotation.
May panic or wrap if vector has any components equal to GridCoordinate::MIN.
Sourcepub fn checked_transform_vector(self, vector: GridVector) -> Option<GridVector>
pub fn checked_transform_vector(self, vector: GridVector) -> Option<GridVector>
Rotate the vector by this rotation.
Returns None if vector has any components equal to GridCoordinate::MIN,
which would overflow.
Sourcepub fn transform_size(self, size: GridSize) -> GridSize
pub fn transform_size(self, size: GridSize) -> GridSize
Rotate the size value by this rotation.
This is similar to GridRotation::transform_vector() except that the components
are only swapped, not negated, and there is no possibility of numeric overflow.
Sourcepub const fn is_reflection(self) -> bool
pub const fn is_reflection(self) -> bool
Returns whether this is a reflection.
use all_is_cubes::math::{GridRotation, Face6::*};
assert!(!GridRotation::IDENTITY.is_reflection());
assert!(!GridRotation::from_basis([PX, PZ, NY]).is_reflection());
assert!(GridRotation::from_basis([PX, PZ, PY]).is_reflection());Sourcepub const fn inverse(self) -> Self
pub const fn inverse(self) -> Self
Returns the inverse of this rotation; the one which undoes this.
use all_is_cubes::math::GridRotation;
for &rotation in &GridRotation::ALL {
assert_eq!(rotation * rotation.inverse(), GridRotation::IDENTITY);
}Sourcepub fn iterate(self) -> impl Iterator<Item = Self>
pub fn iterate(self) -> impl Iterator<Item = Self>
Generates the sequence of rotations that may be obtained by concatenating/multiplying this rotation with itself repeatedly.
The first element of the iterator will always be the identity, i.e. this rotation applied zero times. The iterator ends when the sequence would repeat itself, i.e. just before it would produce the identity again.
§Example results of iteration
use all_is_cubes::math::{Face6::*, GridRotation};
// The identity rotation remains itself when iterated.
assert_eq!(
GridRotation::IDENTITY.iterate().collect::<Vec<_>>(),
vec![GridRotation::IDENTITY],
);
// Any reflection or 180° rotation will produce itself and the identity.
let x_reflection = GridRotation::from_basis([NX, PY, PZ]);
assert_eq!(
x_reflection.iterate().collect::<Vec<_>>(),
vec![GridRotation::IDENTITY, x_reflection],
);
// Any 90° rotation produces four distinct rotations.
assert_eq!(
PY.clockwise().iterate().collect::<Vec<_>>(),
vec![
GridRotation::IDENTITY,
PY.clockwise(),
PY.r180(),
PY.counterclockwise(),
],
);Trait Implementations§
Source§impl Clone for GridRotation
impl Clone for GridRotation
Source§fn clone(&self) -> GridRotation
fn clone(&self) -> GridRotation
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for GridRotation
Source§impl Debug for GridRotation
impl Debug for GridRotation
impl Eq for GridRotation
Source§impl From<GridRotation> for Gridgid
impl From<GridRotation> for Gridgid
Source§fn from(value: GridRotation) -> Self
fn from(value: GridRotation) -> Self
Source§impl Hash for GridRotation
impl Hash for GridRotation
Source§impl Mul for GridRotation
impl Mul for GridRotation
Source§fn mul(self, rhs: Self) -> Self::Output
fn mul(self, rhs: Self) -> Self::Output
Multiplication is concatenation: self * rhs is equivalent to
applying rhs and then applying self.
use all_is_cubes::math::{Face6, Face6::*, GridRotation, GridPoint};
let transform_1 = GridRotation::from_basis([NY, PX, PZ]);
let transform_2 = GridRotation::from_basis([PY, PZ, PX]);
// Demonstrate the directionality of concatenation.
for face in Face6::ALL {
assert_eq!(
(transform_1 * transform_2).transform(face),
transform_1.transform(transform_2.transform(face)),
);
}Source§type Output = GridRotation
type Output = GridRotation
* operator.Source§impl One for GridRotation
impl One for GridRotation
Source§impl PartialEq for GridRotation
impl PartialEq for GridRotation
Source§fn eq(&self, other: &GridRotation) -> bool
fn eq(&self, other: &GridRotation) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for GridRotation
Auto Trait Implementations§
impl Freeze for GridRotation
impl RefUnwindSafe for GridRotation
impl Send for GridRotation
impl Sync for GridRotation
impl Unpin for GridRotation
impl UnsafeUnpin for GridRotation
impl UnwindSafe for GridRotation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.