use qtty::angular::Radians;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rotation2 {
m: [[f64; 2]; 2],
}
impl Rotation2 {
pub const IDENTITY: Self = Self {
m: [[1.0, 0.0], [0.0, 1.0]],
};
#[inline]
#[must_use]
pub const fn from_matrix(m: [[f64; 2]; 2]) -> Self {
Self { m }
}
#[inline]
#[must_use]
pub fn new(angle: Radians) -> Self {
let (s, c) = angle.sin_cos();
Self {
m: [[c, -s], [s, c]],
}
}
#[inline]
#[must_use]
pub fn transpose(&self) -> Self {
Self {
m: [[self.m[0][0], self.m[1][0]], [self.m[0][1], self.m[1][1]]],
}
}
#[inline]
#[must_use]
pub fn inverse(&self) -> Self {
self.transpose()
}
#[inline]
#[must_use]
pub fn compose(&self, other: &Self) -> Self {
*self * *other
}
#[inline]
#[must_use]
pub fn apply_array(&self, v: [f64; 2]) -> [f64; 2] {
[
self.m[0][0] * v[0] + self.m[0][1] * v[1],
self.m[1][0] * v[0] + self.m[1][1] * v[1],
]
}
#[inline]
#[must_use]
pub const fn as_matrix(&self) -> &[[f64; 2]; 2] {
&self.m
}
}
impl Default for Rotation2 {
fn default() -> Self {
Self::IDENTITY
}
}
impl core::ops::Mul for Rotation2 {
type Output = Self;
#[inline]
fn mul(self, rhs: Self) -> Self::Output {
let m = self
.m
.map(|row| core::array::from_fn(|j| row[0] * rhs.m[0][j] + row[1] * rhs.m[1][j]));
Self { m }
}
}
impl core::ops::Mul<[f64; 2]> for Rotation2 {
type Output = [f64; 2];
#[inline]
fn mul(self, rhs: [f64; 2]) -> Self::Output {
self.apply_array(rhs)
}
}