use core::{
fmt::{Debug, Display},
hash::Hash,
ops::{Deref, DerefMut},
panic::{RefUnwindSafe, UnwindSafe},
};
use crate::{
Aligned, Alignment, Length, Matrix, Scalar, ScalarBackend, ScalarRepr, SignedInteger,
SupportedLength, Unaligned, Vector,
constants::{Nan, One, Zero},
utils::{Repr3, Repr4, Repr5, specialize, transmute_generic, transmute_mut, transmute_ref},
};
mod float;
#[repr(transparent)]
pub struct Affine<const N: usize, T, A: Alignment>(
pub(crate) <T::Repr as ScalarRepr>::AffineRepr<N, T, A>,
)
where
Length<N>: SupportedLength,
T: Scalar;
pub type Affine2<T> = Affine<2, T, Aligned>;
pub type Affine3<T> = Affine<3, T, Aligned>;
pub type Affine2U<T> = Affine<2, T, Unaligned>;
pub type Affine3U<T> = Affine<3, T, Unaligned>;
impl<const N: usize, T, A: Alignment> Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Zero,
{
pub const ZERO: Self = Self::from_mat_translation(Matrix::ZERO, Vector::ZERO);
}
impl<const N: usize, T, A: Alignment> Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Zero + One,
{
pub const IDENTITY: Self = Self::from_mat_translation(Matrix::IDENTITY, Vector::ZERO);
}
impl<const N: usize, T, A: Alignment> Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Nan,
{
pub const NAN: Self = Self::from_mat_translation(Matrix::NAN, Vector::NAN);
}
impl<const N: usize, T, A: Alignment> Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar,
{
#[inline]
#[must_use]
pub const fn from_mat(mat: Matrix<N, T, A>) -> Self
where
T: Zero,
{
Self::from_mat_translation(mat, Vector::ZERO)
}
#[inline]
#[must_use]
pub const fn from_translation(translation: Vector<N, T, A>) -> Self
where
T: Zero + One,
{
Self::from_mat_translation(Matrix::IDENTITY, translation)
}
#[inline]
#[must_use]
pub const fn from_mat_translation(mat: Matrix<N, T, A>, translation: Vector<N, T, A>) -> Self {
if const {
size_of::<Affine<N, T, A>>()
== size_of::<Matrix<N, T, A>>() + size_of::<Vector<N, T, A>>()
} {
unsafe {
#[repr(C)]
struct AffineRepr<const N: usize, T, A: Alignment>
where
Length<N>: SupportedLength,
T: Scalar,
{
mat: Matrix<N, T, A>,
translation: Vector<N, T, A>,
}
transmute_generic::<AffineRepr<N, T, A>, Affine<N, T, A>>(AffineRepr {
mat,
translation,
})
}
} else if const { N == 2 && size_of::<Affine<2, T, A>>() / size_of::<Vector<2, T, A>>() == 4 }
{
unsafe {
#[repr(C)]
struct AffineRepr<const N: usize, T, A: Alignment>
where
Length<N>: SupportedLength,
T: Scalar,
{
mat: Matrix<N, T, A>,
translation: Vector<N, T, A>,
padding: Vector<N, T, A>,
}
transmute_generic::<AffineRepr<N, T, A>, Affine<N, T, A>>(AffineRepr {
mat,
translation,
padding: translation,
})
}
} else if const {
N == 3
&& size_of::<Affine<3, T, A>>()
- size_of::<Matrix<3, T, A>>()
- size_of::<Vector<3, T, A>>()
== size_of::<T>() * 4
} {
unsafe {
#[repr(C)]
struct AffineRepr<const N: usize, T, A: Alignment>
where
Length<N>: SupportedLength,
T: Scalar,
{
mat: Matrix<N, T, A>,
translation: Vector<N, T, A>,
padding: Repr4<T>,
}
transmute_generic::<AffineRepr<N, T, A>, Affine<N, T, A>>(AffineRepr {
mat,
translation,
padding: Repr4(
translation.as_array_ref()[0],
translation.as_array_ref()[1],
translation.as_array_ref()[2],
translation.as_array_ref()[2],
),
})
}
} else {
unreachable!()
}
}
#[inline]
#[must_use]
pub const fn to_alignment<A2: Alignment>(&self) -> Affine<N, T, A2> {
let deref = unsafe { transmute_ref::<Affine<N, T, A>, AffineDeref<N, T, A>>(self) };
Affine::from_mat_translation(
deref.matrix.to_alignment(),
deref.translation.to_alignment(),
)
}
#[inline]
#[must_use]
pub const fn align(&self) -> Affine<N, T, Aligned> {
self.to_alignment()
}
#[inline]
#[must_use]
pub const fn unalign(&self) -> Affine<N, T, Unaligned> {
self.to_alignment()
}
#[inline]
#[must_use]
#[expect(private_bounds)]
pub const unsafe fn to_repr<T2>(self) -> Affine<N, T2, A>
where
T2: Scalar<Repr = T::Repr>,
T::Repr: SignedInteger,
{
unsafe { transmute_generic::<Affine<N, T, A>, Affine<N, T2, A>>(self) }
}
}
impl<T, A: Alignment> Affine<2, T, A>
where
T: Scalar,
{
#[inline]
#[must_use]
pub const fn from_columns(array: &[Vector<2, T, A>; 3]) -> Self {
match size_of::<Affine<2, T, A>>() / size_of::<Vector<2, T, A>>() {
3 => unsafe {
transmute_generic::<Repr3<Vector<2, T, A>>, Affine<2, T, A>>(Repr3(
array[0], array[1], array[2],
))
},
4 => unsafe {
transmute_generic::<Repr4<Vector<2, T, A>>, Affine<2, T, A>>(Repr4(
array[0], array[1], array[2], array[2],
))
},
_ => unreachable!(),
}
}
#[inline]
#[must_use]
pub const fn as_columns(&self) -> &[Vector<2, T, A>; 3] {
unsafe { transmute_ref::<Affine<2, T, A>, [Vector<2, T, A>; 3]>(self) }
}
#[inline]
#[must_use]
pub const fn as_columns_mut(&mut self) -> &mut [Vector<2, T, A>; 3] {
unsafe { transmute_mut::<Affine<2, T, A>, [Vector<2, T, A>; 3]>(self) }
}
#[deprecated(since = "0.16.3", note = "replaced by `from_columns`")]
#[inline]
#[must_use]
pub const fn from_cols(
x_axis: Vector<2, T, A>,
y_axis: Vector<2, T, A>,
translation: Vector<2, T, A>,
) -> Self {
Self::from_columns(&[x_axis, y_axis, translation])
}
#[deprecated(since = "0.16.3", note = "renamed to `from_columns`")]
#[inline]
#[must_use]
pub const fn from_col_array(array: &[Vector<2, T, A>; 3]) -> Self {
Self::from_columns(array)
}
#[deprecated(since = "0.16.3", note = "replaced by `as_columns`")]
#[inline]
#[must_use]
pub const fn to_col_array(&self) -> [Vector<2, T, A>; 3] {
*self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns`")]
#[inline]
#[must_use]
pub const fn as_col_array_ref(&self) -> &[Vector<2, T, A>; 3] {
self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns_mut`")]
#[inline]
#[must_use]
pub const fn as_col_array_mut(&mut self) -> &mut [Vector<2, T, A>; 3] {
self.as_columns_mut()
}
}
impl<T, A: Alignment> Affine<3, T, A>
where
T: Scalar,
{
#[inline]
#[must_use]
pub const fn from_columns(array: &[Vector<3, T, A>; 4]) -> Self {
match const {
(size_of::<Affine<3, T, A>>()
- size_of::<Matrix<3, T, A>>()
- size_of::<Vector<3, T, A>>())
/ size_of::<T>()
} {
0 => unsafe {
transmute_generic::<Repr4<Vector<3, T, A>>, Affine<3, T, A>>(Repr4(
array[0], array[1], array[2], array[3],
))
},
4 => unsafe {
#[repr(C)]
struct AffineRepr<T, A: Alignment>
where
T: Scalar,
{
x_axis: Vector<3, T, A>,
y_axis: Vector<3, T, A>,
z_axis: Vector<3, T, A>,
w_axis: Vector<3, T, A>,
padding: Repr4<T>,
}
transmute_generic::<AffineRepr<T, A>, Affine<3, T, A>>(AffineRepr {
x_axis: array[0],
y_axis: array[1],
z_axis: array[2],
w_axis: array[3],
padding: Repr4(
array[0].as_array_ref()[0],
array[0].as_array_ref()[1],
array[0].as_array_ref()[2],
array[0].as_array_ref()[2],
),
})
},
_ => unreachable!(),
}
}
#[inline]
#[must_use]
pub const fn as_columns(&self) -> &[Vector<3, T, A>; 4] {
unsafe { transmute_ref::<Affine<3, T, A>, [Vector<3, T, A>; 4]>(self) }
}
#[inline]
#[must_use]
pub const fn as_columns_mut(&mut self) -> &mut [Vector<3, T, A>; 4] {
unsafe { transmute_mut::<Affine<3, T, A>, [Vector<3, T, A>; 4]>(self) }
}
#[deprecated(since = "0.16.3", note = "replaced by `from_columns`")]
#[inline]
#[must_use]
pub const fn from_cols(
x_axis: Vector<3, T, A>,
y_axis: Vector<3, T, A>,
z_axis: Vector<3, T, A>,
translation: Vector<3, T, A>,
) -> Self {
Self::from_columns(&[x_axis, y_axis, z_axis, translation])
}
#[deprecated(since = "0.16.3", note = "renamed to `from_columns`")]
#[inline]
#[must_use]
pub const fn from_col_array(array: &[Vector<3, T, A>; 4]) -> Self {
Self::from_columns(array)
}
#[deprecated(since = "0.16.3", note = "replaced by `as_columns`")]
#[inline]
#[must_use]
pub const fn to_col_array(&self) -> [Vector<3, T, A>; 4] {
*self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns`")]
#[inline]
#[must_use]
pub const fn as_col_array_ref(&self) -> &[Vector<3, T, A>; 4] {
self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns_mut`")]
#[inline]
#[must_use]
pub const fn as_col_array_mut(&mut self) -> &mut [Vector<3, T, A>; 4] {
self.as_columns_mut()
}
}
impl<T, A: Alignment> Affine<4, T, A>
where
T: Scalar,
{
#[inline]
#[must_use]
pub const fn from_columns(array: &[Vector<4, T, A>; 5]) -> Self {
unsafe {
transmute_generic::<Repr5<Vector<4, T, A>>, Affine<4, T, A>>(Repr5(
array[0], array[1], array[2], array[3], array[4],
))
}
}
#[inline]
#[must_use]
pub const fn as_columns(&self) -> &[Vector<4, T, A>; 5] {
unsafe { transmute_ref::<Affine<4, T, A>, [Vector<4, T, A>; 5]>(self) }
}
#[inline]
#[must_use]
pub const fn as_columns_mut(&mut self) -> &mut [Vector<4, T, A>; 5] {
unsafe { transmute_mut::<Affine<4, T, A>, [Vector<4, T, A>; 5]>(self) }
}
#[deprecated(since = "0.16.3", note = "replaced by `from_columns`")]
#[inline]
#[must_use]
pub const fn from_cols(
x_axis: Vector<4, T, A>,
y_axis: Vector<4, T, A>,
z_axis: Vector<4, T, A>,
w_axis: Vector<4, T, A>,
translation: Vector<4, T, A>,
) -> Self {
Self::from_columns(&[x_axis, y_axis, z_axis, w_axis, translation])
}
#[deprecated(since = "0.16.3", note = "renamed to `from_columns`")]
#[inline]
#[must_use]
pub const fn from_col_array(array: &[Vector<4, T, A>; 5]) -> Self {
Self::from_columns(array)
}
#[deprecated(since = "0.16.3", note = "replaced by `as_columns`")]
#[inline]
#[must_use]
pub const fn to_col_array(&self) -> [Vector<4, T, A>; 5] {
*self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns`")]
#[inline]
#[must_use]
pub const fn as_col_array_ref(&self) -> &[Vector<4, T, A>; 5] {
self.as_columns()
}
#[deprecated(since = "0.16.3", note = "renamed to `as_columns_mut`")]
#[inline]
#[must_use]
pub const fn as_col_array_mut(&mut self) -> &mut [Vector<4, T, A>; 5] {
self.as_columns_mut()
}
}
impl<const N: usize, T, A: Alignment> Clone for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar,
{
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<const N: usize, T, A: Alignment> Copy for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar,
{
}
#[doc(hidden)]
#[repr(C)]
pub struct AffineDeref<const N: usize, T, A: Alignment>
where
Length<N>: SupportedLength,
T: Scalar,
{
pub matrix: Matrix<N, T, A>,
pub translation: Vector<N, T, A>,
}
impl<const N: usize, T, A: Alignment> Deref for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar,
{
type Target = AffineDeref<N, T, A>;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { transmute_ref::<Affine<N, T, A>, AffineDeref<N, T, A>>(self) }
}
}
impl<const N: usize, T, A: Alignment> DerefMut for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { transmute_mut::<Affine<N, T, A>, AffineDeref<N, T, A>>(self) }
}
}
impl<const N: usize, T, A: Alignment> Debug for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match N {
2 => write!(
f,
"[{:?}, {:?}, {:?}]",
self.matrix.column(0),
self.matrix.column(1),
self.translation
),
3 => write!(
f,
"[{:?}, {:?}, {:?}, {:?}]",
self.matrix.column(0),
self.matrix.column(1),
self.matrix.column(2),
self.translation
),
4 => write!(
f,
"[{:?}, {:?}, {:?}, {:?}, {:?}]",
self.matrix.column(0),
self.matrix.column(1),
self.matrix.column(2),
self.matrix.column(3),
self.translation
),
_ => unreachable!(),
}
}
}
impl<const N: usize, T, A: Alignment> Display for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match N {
2 => write!(
f,
"[{}, {}, {}]",
self.matrix.column(0),
self.matrix.column(1),
self.translation
),
3 => write!(
f,
"[{}, {}, {}, {}]",
self.matrix.column(0),
self.matrix.column(1),
self.matrix.column(2),
self.translation
),
4 => write!(
f,
"[{}, {}, {}, {}, {}]",
self.matrix.column(0),
self.matrix.column(1),
self.matrix.column(2),
self.matrix.column(3),
self.translation
),
_ => unreachable!(),
}
}
}
impl<const N: usize, T, A: Alignment> PartialEq for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
specialize!(<T as ScalarBackend<N, A>>::affine_eq(self, other))
}
#[expect(clippy::partialeq_ne_impl)]
#[inline]
fn ne(&self, other: &Self) -> bool {
specialize!(<T as ScalarBackend<N, A>>::affine_ne(self, other))
}
}
impl<const N: usize, T, A: Alignment> Eq for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Eq,
{
}
impl<const N: usize, T, A: Alignment> Hash for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Hash,
{
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.matrix.hash(state);
self.translation.hash(state);
}
}
impl<const N: usize, T, A: Alignment> Default for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Zero + One,
{
#[inline]
fn default() -> Self {
Self::IDENTITY
}
}
unsafe impl<const N: usize, T, A: Alignment> Send for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Send,
{
}
unsafe impl<const N: usize, T, A: Alignment> Sync for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Sync,
{
}
impl<const N: usize, T, A: Alignment> Unpin for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + Unpin,
{
}
impl<const N: usize, T, A: Alignment> UnwindSafe for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + UnwindSafe,
{
}
impl<const N: usize, T, A: Alignment> RefUnwindSafe for Affine<N, T, A>
where
Length<N>: SupportedLength,
T: Scalar + RefUnwindSafe,
{
}
#[cfg(test)]
mod tests {
use crate::{
Affine, Affine2, Affine2U, Affine3, Affine3U, Aligned, Mat2, Mat3, Mat4, Matrix, Unaligned,
Vec2, Vec3, Vector,
utils::{assert_float_eq, for_parameters},
};
#[test]
fn test_layout() {
for_parameters!(|T: PrimitiveNumber| {
assert!(
size_of::<Affine2<T>>() == size_of::<T>() * 6
&& align_of::<Affine2<T>>() == align_of::<Vec2<T>>()
|| size_of::<Affine2<T>>() == size_of::<T>() * 8
&& (align_of::<Affine2<T>>() == align_of::<Mat2<T>>()
|| align_of::<Affine2<T>>() == size_of::<T>() * 8)
);
assert!(
size_of::<Affine3<T>>() == size_of::<Mat3<T>>() + size_of::<Vec3<T>>()
&& align_of::<Affine3<T>>() == align_of::<Mat3<T>>()
|| size_of::<Affine3<T>>() == size_of::<T>() * 16
&& align_of::<Affine3<T>>() == size_of::<T>() * 16
&& size_of::<Mat3<T>>() == size_of::<T>() * 9
&& size_of::<Vec3<T>>() == size_of::<T>() * 3
);
assert_eq!(size_of::<Affine<4, T, Aligned>>(), size_of::<T>() * 20);
assert_eq!(align_of::<Affine<4, T, Aligned>>(), align_of::<Mat4<T>>());
assert_eq!(size_of::<Affine2U<T>>(), size_of::<T>() * 6);
assert_eq!(align_of::<Affine2U<T>>(), align_of::<T>());
assert_eq!(size_of::<Affine3U<T>>(), size_of::<T>() * 12);
assert_eq!(align_of::<Affine3U<T>>(), align_of::<T>());
assert_eq!(size_of::<Affine<4, T, Unaligned>>(), size_of::<T>() * 20);
assert_eq!(align_of::<Affine<4, T, Unaligned>>(), align_of::<T>());
});
}
#[test]
fn test_zero() {
for_parameters!(|T: PrimitiveNumber, A| {
assert_eq!(
Affine::<2, T, A>::ZERO,
Affine::from_mat_translation(Matrix::ZERO, Vector::ZERO)
);
assert_eq!(
Affine::<3, T, A>::ZERO,
Affine::from_mat_translation(Matrix::ZERO, Vector::ZERO)
);
assert_eq!(
Affine::<4, T, A>::ZERO,
Affine::from_mat_translation(Matrix::ZERO, Vector::ZERO)
);
});
}
#[test]
fn test_identity() {
for_parameters!(|T: PrimitiveNumber, A| {
assert_eq!(
Affine::<2, T, A>::IDENTITY,
Affine::from_mat_translation(Matrix::IDENTITY, Vector::ZERO)
);
assert_eq!(
Affine::<3, T, A>::IDENTITY,
Affine::from_mat_translation(Matrix::IDENTITY, Vector::ZERO)
);
assert_eq!(
Affine::<4, T, A>::IDENTITY,
Affine::from_mat_translation(Matrix::IDENTITY, Vector::ZERO)
);
});
}
#[test]
fn test_nan() {
for_parameters!(|T: PrimitiveFloat, A| {
assert_float_eq!(
Affine::<2, T, A>::NAN,
Affine::from_mat_translation(Matrix::NAN, Vector::NAN)
);
assert_float_eq!(
Affine::<3, T, A>::NAN,
Affine::from_mat_translation(Matrix::NAN, Vector::NAN)
);
assert_float_eq!(
Affine::<4, T, A>::NAN,
Affine::from_mat_translation(Matrix::NAN, Vector::NAN)
);
});
}
#[test]
fn test_from_mat() {
for_parameters!(|T: PrimitiveNumber, A| {
let [_, x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat(Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
])),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::ZERO
)
);
assert_eq!(
Affine::<3, T, A>::from_mat(Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
])),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::ZERO
)
);
assert_eq!(
Affine::<4, T, A>::from_mat(Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
])),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::ZERO
)
);
});
}
#[test]
fn test_from_translation() {
for_parameters!(|T: PrimitiveNumber, A| {
let [_, _, x, y, z, w] = std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_translation(Vector::<2, T, A>::new(x, y)),
Affine::from_mat_translation(Matrix::IDENTITY, Vector::<2, T, A>::new(x, y))
);
assert_eq!(
Affine::<3, T, A>::from_translation(Vector::<3, T, A>::new(x, y, z)),
Affine::from_mat_translation(Matrix::IDENTITY, Vector::<3, T, A>::new(x, y, z))
);
assert_eq!(
Affine::<4, T, A>::from_translation(Vector::<4, T, A>::new(x, y, z, w)),
Affine::from_mat_translation(Matrix::IDENTITY, Vector::<4, T, A>::new(x, y, z, w))
);
});
}
#[test]
fn test_to_alignment() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.to_alignment(),
Affine::<2, T, Aligned>::from_mat_translation(
Matrix::<2, T, Aligned>::from_columns(&[
Vector::<2, T, Aligned>::new(x, y),
Vector::<2, T, Aligned>::new(z, w)
]),
Vector::<2, T, Aligned>::new(a, b)
)
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.to_alignment(),
Affine::<3, T, Aligned>::from_mat_translation(
Matrix::<3, T, Aligned>::from_columns(&[
Vector::<3, T, Aligned>::new(x, y, z),
Vector::<3, T, Aligned>::new(w, a, b),
Vector::<3, T, Aligned>::new(c, d, e)
]),
Vector::<3, T, Aligned>::new(f, g, h)
)
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.to_alignment(),
Affine::<4, T, Aligned>::from_mat_translation(
Matrix::<4, T, Aligned>::from_columns(&[
Vector::<4, T, Aligned>::new(x, y, z, w),
Vector::<4, T, Aligned>::new(a, b, c, d),
Vector::<4, T, Aligned>::new(e, f, g, h),
Vector::<4, T, Aligned>::new(i, j, k, l)
]),
Vector::<4, T, Aligned>::new(m, n, o, p)
)
);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.to_alignment(),
Affine::<2, T, Unaligned>::from_mat_translation(
Matrix::<2, T, Unaligned>::from_columns(&[
Vector::<2, T, Unaligned>::new(x, y),
Vector::<2, T, Unaligned>::new(z, w)
]),
Vector::<2, T, Unaligned>::new(a, b)
)
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.to_alignment(),
Affine::<3, T, Unaligned>::from_mat_translation(
Matrix::<3, T, Unaligned>::from_columns(&[
Vector::<3, T, Unaligned>::new(x, y, z),
Vector::<3, T, Unaligned>::new(w, a, b),
Vector::<3, T, Unaligned>::new(c, d, e)
]),
Vector::<3, T, Unaligned>::new(f, g, h)
)
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.to_alignment(),
Affine::<4, T, Unaligned>::from_mat_translation(
Matrix::<4, T, Unaligned>::from_columns(&[
Vector::<4, T, Unaligned>::new(x, y, z, w),
Vector::<4, T, Unaligned>::new(a, b, c, d),
Vector::<4, T, Unaligned>::new(e, f, g, h),
Vector::<4, T, Unaligned>::new(i, j, k, l)
]),
Vector::<4, T, Unaligned>::new(m, n, o, p)
)
);
});
}
#[test]
fn test_align() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.align(),
Affine::<2, T, Aligned>::from_mat_translation(
Matrix::<2, T, Aligned>::from_columns(&[
Vector::<2, T, Aligned>::new(x, y),
Vector::<2, T, Aligned>::new(z, w)
]),
Vector::<2, T, Aligned>::new(a, b)
)
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.align(),
Affine::<3, T, Aligned>::from_mat_translation(
Matrix::<3, T, Aligned>::from_columns(&[
Vector::<3, T, Aligned>::new(x, y, z),
Vector::<3, T, Aligned>::new(w, a, b),
Vector::<3, T, Aligned>::new(c, d, e)
]),
Vector::<3, T, Aligned>::new(f, g, h)
)
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.align(),
Affine::<4, T, Aligned>::from_mat_translation(
Matrix::<4, T, Aligned>::from_columns(&[
Vector::<4, T, Aligned>::new(x, y, z, w),
Vector::<4, T, Aligned>::new(a, b, c, d),
Vector::<4, T, Aligned>::new(e, f, g, h),
Vector::<4, T, Aligned>::new(i, j, k, l)
]),
Vector::<4, T, Aligned>::new(m, n, o, p)
)
);
});
}
#[test]
fn test_unalign() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.unalign(),
Affine::<2, T, Unaligned>::from_mat_translation(
Matrix::<2, T, Unaligned>::from_columns(&[
Vector::<2, T, Unaligned>::new(x, y),
Vector::<2, T, Unaligned>::new(z, w)
]),
Vector::<2, T, Unaligned>::new(a, b)
)
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.unalign(),
Affine::<3, T, Unaligned>::from_mat_translation(
Matrix::<3, T, Unaligned>::from_columns(&[
Vector::<3, T, Unaligned>::new(x, y, z),
Vector::<3, T, Unaligned>::new(w, a, b),
Vector::<3, T, Unaligned>::new(c, d, e)
]),
Vector::<3, T, Unaligned>::new(f, g, h)
)
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.unalign(),
Affine::<4, T, Unaligned>::from_mat_translation(
Matrix::<4, T, Unaligned>::from_columns(&[
Vector::<4, T, Unaligned>::new(x, y, z, w),
Vector::<4, T, Unaligned>::new(a, b, c, d),
Vector::<4, T, Unaligned>::new(e, f, g, h),
Vector::<4, T, Unaligned>::new(i, j, k, l)
]),
Vector::<4, T, Unaligned>::new(m, n, o, p)
)
);
});
}
#[test]
fn test_to_repr() {
for_parameters!(|A| {
assert_eq!(
unsafe {
Affine::<2, i32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, i32, A>::new(0, 1),
Vector::<2, i32, A>::new(2, 3),
]),
Vector::<2, i32, A>::new(4, 5),
)
.to_repr()
},
Affine::<2, u32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, u32, A>::new(0, 1),
Vector::<2, u32, A>::new(2, 3),
]),
Vector::<2, u32, A>::new(4, 5),
)
);
assert_eq!(
unsafe {
Affine::<3, i32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, i32, A>::new(0, 1, 2),
Vector::<3, i32, A>::new(3, 4, 5),
Vector::<3, i32, A>::new(6, 7, 8),
]),
Vector::<3, i32, A>::new(9, 10, 11),
)
.to_repr()
},
Affine::<3, u32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, u32, A>::new(0, 1, 2),
Vector::<3, u32, A>::new(3, 4, 5),
Vector::<3, u32, A>::new(6, 7, 8),
]),
Vector::<3, u32, A>::new(9, 10, 11)
)
);
assert_eq!(
unsafe {
Affine::<4, i32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, i32, A>::new(0, 1, 2, 3),
Vector::<4, i32, A>::new(4, 5, 6, 7),
Vector::<4, i32, A>::new(8, 9, 10, 11),
Vector::<4, i32, A>::new(12, 13, 14, 15),
]),
Vector::<4, i32, A>::new(16, 17, 18, 19),
)
.to_repr()
},
Affine::<4, u32, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, u32, A>::new(0, 1, 2, 3),
Vector::<4, u32, A>::new(4, 5, 6, 7),
Vector::<4, u32, A>::new(8, 9, 10, 11),
Vector::<4, u32, A>::new(12, 13, 14, 15),
]),
Vector::<4, u32, A>::new(16, 17, 18, 19),
)
);
});
}
#[test]
fn test_from_columns() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
Vector::<2, T, A>::new(a, b)
]),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
);
assert_eq!(
Affine::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e),
Vector::<3, T, A>::new(f, g, h)
]),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
);
assert_eq!(
Affine::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l),
Vector::<4, T, A>::new(m, n, o, p)
]),
Affine::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
);
});
}
#[test]
fn test_as_columns() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.as_columns(),
&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
Vector::<2, T, A>::new(a, b)
]
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.as_columns(),
&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e),
Vector::<3, T, A>::new(f, g, h)
]
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.as_columns(),
&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l),
Vector::<4, T, A>::new(m, n, o, p)
]
);
});
}
#[test]
fn test_as_columns_mut() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.as_columns_mut(),
&mut [
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
Vector::<2, T, A>::new(a, b)
]
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.as_columns_mut(),
&mut [
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e),
Vector::<3, T, A>::new(f, g, h)
]
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.as_columns_mut(),
&mut [
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l),
Vector::<4, T, A>::new(m, n, o, p)
]
);
});
}
#[test]
fn test_deref() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.matrix,
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
])
);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.translation,
Vector::<2, T, A>::new(a, b)
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.matrix,
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
])
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.translation,
Vector::<3, T, A>::new(f, g, h)
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.matrix,
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
])
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.translation,
Vector::<4, T, A>::new(m, n, o, p)
);
});
}
#[test]
fn test_deref_mut() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
&mut Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.matrix,
&mut Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
])
);
assert_eq!(
&mut Affine::<2, T, A>::from_mat_translation(
Matrix::<2, T, A>::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
.translation,
&mut Vector::<2, T, A>::new(a, b)
);
assert_eq!(
&mut Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.matrix,
&mut Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
])
);
assert_eq!(
&mut Affine::<3, T, A>::from_mat_translation(
Matrix::<3, T, A>::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
.translation,
&mut Vector::<3, T, A>::new(f, g, h)
);
assert_eq!(
&mut Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.matrix,
&mut Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
])
);
assert_eq!(
&mut Affine::<4, T, A>::from_mat_translation(
Matrix::<4, T, A>::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
.translation,
&mut Vector::<4, T, A>::new(m, n, o, p)
);
});
}
#[test]
fn test_debug() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
format!(
"{:?}",
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
),
format!("[({x:?}, {y:?}), ({z:?}, {w:?}), ({a:?}, {b:?})]")
);
assert_eq!(
format!(
"{:?}",
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
),
format!(
"[({x:?}, {y:?}, {z:?}), ({w:?}, {a:?}, {b:?}), ({c:?}, {d:?}, {e:?}), ({f:?}, {g:?}, {h:?})]"
)
);
assert_eq!(
format!(
"{:?}",
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
),
format!(
"[({x:?}, {y:?}, {z:?}, {w:?}), ({a:?}, {b:?}, {c:?}, {d:?}), ({e:?}, {f:?}, {g:?}, {h:?}), ({i:?}, {j:?}, {k:?}, {l:?}), ({m:?}, {n:?}, {o:?}, {p:?})]"
)
);
});
}
#[test]
fn test_display() {
for_parameters!(|T: PrimitiveNumber, A| {
let [x, y, z, w, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] =
std::array::from_fn(T::as_from);
assert_eq!(
format!(
"{}",
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w)
]),
Vector::<2, T, A>::new(a, b)
)
),
format!("[({x}, {y}), ({z}, {w}), ({a}, {b})]")
);
assert_eq!(
format!(
"{}",
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(w, a, b),
Vector::<3, T, A>::new(c, d, e)
]),
Vector::<3, T, A>::new(f, g, h)
)
),
format!("[({x}, {y}, {z}), ({w}, {a}, {b}), ({c}, {d}, {e}), ({f}, {g}, {h})]")
);
assert_eq!(
format!(
"{}",
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(a, b, c, d),
Vector::<4, T, A>::new(e, f, g, h),
Vector::<4, T, A>::new(i, j, k, l)
]),
Vector::<4, T, A>::new(m, n, o, p)
)
),
format!(
"[({x}, {y}, {z}, {w}), ({a}, {b}, {c}, {d}), ({e}, {f}, {g}, {h}), ({i}, {j}, {k}, {l}), ({m}, {n}, {o}, {p})]"
)
);
});
}
#[test]
fn test_eq() {
for_parameters!(|T: PrimitiveNumber, A, x, y, z| {
let w = if x > y { x } else { y };
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
) == Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(z, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
),
x == z && y == y && z == z && w == w && x == x
);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
) == Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(z, w),
Vector::<2, T, A>::new(x, y),
]),
Vector::<2, T, A>::new(z, x),
),
x == z && y == w
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(x, y, z),
) == Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(x, y, z),
),
x == x && y == y && z == w && w == w
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(z, w, y),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(z, x, y),
) == Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(z, w, y),
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(z, w, y),
]),
Vector::<3, T, A>::new(y, y, w),
),
x == z && y == w && z == y
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, y, x, w),
Vector::<4, T, A>::new(x, y, z, y),
]),
Vector::<4, T, A>::new(x, y, z, w),
) == Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(w, y, z, w),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, y, x, w),
Vector::<4, T, A>::new(x, y, z, y),
]),
Vector::<4, T, A>::new(x, y, z, w),
),
x == w && y == y && z == z && w == w
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
]),
Vector::<4, T, A>::new(z, y, x, w),
) == Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
]),
Vector::<4, T, A>::new(x, y, z, x),
),
x == z && y == w && z == y
);
});
}
#[test]
fn test_ne() {
for_parameters!(|T: PrimitiveNumber, A, x, y, z| {
let w = if x > y { x } else { y };
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
) != Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(z, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
),
x != z || y != y || z != z || w != w || x != x
);
assert_eq!(
Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(x, y),
Vector::<2, T, A>::new(z, w),
]),
Vector::<2, T, A>::new(x, z),
) != Affine::<2, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<2, T, A>::new(z, w),
Vector::<2, T, A>::new(x, y),
]),
Vector::<2, T, A>::new(z, x),
),
x != z || y != w
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(x, y, z),
) != Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, w),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(x, y, z),
),
x != x || y != y || z != w || w != w
);
assert_eq!(
Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(z, w, y),
Vector::<3, T, A>::new(x, y, z),
]),
Vector::<3, T, A>::new(z, x, y),
) != Affine::<3, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<3, T, A>::new(z, w, y),
Vector::<3, T, A>::new(x, y, z),
Vector::<3, T, A>::new(z, w, y),
]),
Vector::<3, T, A>::new(y, y, w),
),
x != z || y != w || z != y
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, y, x, w),
Vector::<4, T, A>::new(x, y, z, y),
]),
Vector::<4, T, A>::new(x, y, z, w),
) != Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(w, y, z, w),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, y, x, w),
Vector::<4, T, A>::new(x, y, z, y),
]),
Vector::<4, T, A>::new(x, y, z, w),
),
x != w || y != y || z != z || w != w
);
assert_eq!(
Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
]),
Vector::<4, T, A>::new(z, y, x, w),
) != Affine::<4, T, A>::from_mat_translation(
Matrix::from_columns(&[
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
Vector::<4, T, A>::new(z, w, y, x),
Vector::<4, T, A>::new(x, y, z, w),
]),
Vector::<4, T, A>::new(x, y, z, x),
),
x != z || y != w || z != y
);
});
}
#[test]
fn test_default() {
for_parameters!(|T: PrimitiveNumber, A| {
assert_eq!(Affine::<2, T, A>::default(), Affine::IDENTITY);
assert_eq!(Affine::<3, T, A>::default(), Affine::IDENTITY);
assert_eq!(Affine::<4, T, A>::default(), Affine::IDENTITY);
});
}
}