Enum all_is_cubes::math::GridRotation
source · #[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.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: [GridRotation; 48] = _
pub const ALL: [GridRotation; 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: [GridRotation; 24] = _
pub const ALL_BUT_REFLECTIONS: [GridRotation; 24] = _
All possible rotations that are not reflections.
Warning: TODO: The ordering of these rotations is not yet stable.
sourcepub const IDENTITY: GridRotation = Self::RXYZ
pub const IDENTITY: GridRotation = Self::RXYZ
The identity rotation, also known as RXYZ.
sourcepub const CLOCKWISE: GridRotation = Self::RZYx
pub const CLOCKWISE: GridRotation = Self::RZYx
The rotation that is clockwise in our Y-up right-handed coordinate system.
use all_is_cubes::math::{Face6::*, GridRotation};
assert_eq!(GridRotation::CLOCKWISE.transform(PX), PZ);
assert_eq!(GridRotation::CLOCKWISE.transform(PZ), NX);
assert_eq!(GridRotation::CLOCKWISE.transform(NX), NZ);
assert_eq!(GridRotation::CLOCKWISE.transform(NZ), PX);
assert_eq!(GridRotation::CLOCKWISE.transform(PY), PY);sourcepub const COUNTERCLOCKWISE: GridRotation = Self::RzYX
pub const COUNTERCLOCKWISE: GridRotation = Self::RzYX
The rotation that is counterclockwise in our Y-up right-handed coordinate system.
use all_is_cubes::math::{Face6::*, GridRotation};
assert_eq!(GridRotation::COUNTERCLOCKWISE.transform(PX), NZ);
assert_eq!(GridRotation::COUNTERCLOCKWISE.transform(NZ), NX);
assert_eq!(GridRotation::COUNTERCLOCKWISE.transform(NX), PZ);
assert_eq!(GridRotation::COUNTERCLOCKWISE.transform(PZ), PX);
assert_eq!(GridRotation::COUNTERCLOCKWISE.transform(PY), PY);sourcepub fn from_basis(basis: impl Into<[Face6; 3]>) -> GridRotation
pub fn from_basis(basis: impl Into<[Face6; 3]>) -> GridRotation
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<GridRotation>
pub fn from_to( source: Face6, destination: Face6, up: Face6, ) -> Option<GridRotation>
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 fn to_positive_octant_transform(self, size: i32) -> Gridgid
pub fn to_positive_octant_transform(self, size: i32) -> 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::{GridAab, GridRotation};
let b = GridAab::for_block(Resolution::R8);
let rotation = GridRotation::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).
use all_is_cubes::math::{GridAab, Cube, GridRotation};
let rotation = GridRotation::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: Vector3D<i32, Cube>,
) -> Vector3D<i32, Cube>
pub fn transform_vector( self, vector: Vector3D<i32, Cube>, ) -> Vector3D<i32, Cube>
Rotate the vector by this rotation.
May panic or wrap if vector has any components equal to GridCoordinate::MIN.
sourcepub fn transform_size(self, size: Size3D<u32, Cube>) -> Size3D<u32, Cube>
pub fn transform_size(self, size: Size3D<u32, Cube>) -> Size3D<u32, Cube>
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) -> GridRotation
pub const fn inverse(self) -> GridRotation
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 = GridRotation>
pub fn iterate(self) -> impl Iterator<Item = GridRotation>
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.
use all_is_cubes::math::Face6::*;
use all_is_cubes::math::GridRotation;
assert_eq!(
GridRotation::IDENTITY.iterate().collect::<Vec<_>>(),
vec![GridRotation::IDENTITY],
);
let x_reflection = GridRotation::from_basis([NX, PY, PZ]);
assert_eq!(
x_reflection.iterate().collect::<Vec<_>>(),
vec![GridRotation::IDENTITY, x_reflection],
);
assert_eq!(
GridRotation::CLOCKWISE.iterate().collect::<Vec<_>>(),
vec![
GridRotation::IDENTITY,
GridRotation::CLOCKWISE,
GridRotation::CLOCKWISE * GridRotation::CLOCKWISE,
GridRotation::COUNTERCLOCKWISE,
],
);Trait Implementations§
source§impl<'arbitrary> Arbitrary<'arbitrary> for GridRotation
impl<'arbitrary> Arbitrary<'arbitrary> for GridRotation
source§fn arbitrary(u: &mut Unstructured<'arbitrary>) -> Result<GridRotation, Error>
fn arbitrary(u: &mut Unstructured<'arbitrary>) -> Result<GridRotation, Error>
Self from the given unstructured data. Read moresource§fn arbitrary_take_rest(
u: Unstructured<'arbitrary>,
) -> Result<GridRotation, Error>
fn arbitrary_take_rest( u: Unstructured<'arbitrary>, ) -> Result<GridRotation, Error>
Self from the entirety of the given
unstructured data. Read moresource§impl Clone for GridRotation
impl Clone for GridRotation
source§fn clone(&self) -> GridRotation
fn clone(&self) -> GridRotation
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moresource§impl Debug for GridRotation
impl Debug for GridRotation
source§impl Default for GridRotation
impl Default for GridRotation
source§fn default() -> GridRotation
fn default() -> GridRotation
Returns the identity (no rotation).
source§impl<'de> Deserialize<'de> for GridRotation
impl<'de> Deserialize<'de> for GridRotation
source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<GridRotation, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<GridRotation, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
source§impl From<GridRotation> for Gridgid
impl From<GridRotation> for Gridgid
source§fn from(value: GridRotation) -> Gridgid
fn from(value: GridRotation) -> Gridgid
source§impl Hash for GridRotation
impl Hash for GridRotation
source§impl Mul for GridRotation
impl Mul for GridRotation
source§fn mul(self, rhs: GridRotation) -> <GridRotation as Mul>::Output
fn mul(self, rhs: GridRotation) -> <GridRotation as Mul>::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)),
);
}§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 ==.source§impl Serialize for GridRotation
impl Serialize for GridRotation
source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl Copy for GridRotation
impl Eq for GridRotation
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 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: Copy,
impl<T> CloneToUninit for Twhere
T: Copy,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more