///|
/// 2D Affine Transformation Matrix
/// Represents a transformation of the form:
/// x' = a*x + c*y + tx
/// y' = b*x + d*y + ty
pub(all) struct Matrix2D {
a : Double
b : Double
c : Double
d : Double
tx : Double
ty : Double
} derive(Eq, Debug, ToJson)
///|
/// Returns the identity matrix
pub fn Matrix2D::identity() -> Matrix2D {
{ a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0 }
}
///|
/// Creates a translation matrix
pub fn Matrix2D::translate(tx : Double, ty : Double) -> Matrix2D {
{ a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx, ty }
}
///|
/// Creates a rotation matrix around the origin (angle in radians)
pub fn Matrix2D::rotate(angle : Double) -> Matrix2D {
let cos_a = @math.cos(angle)
let sin_a = @math.sin(angle)
{ a: cos_a, b: sin_a, c: -sin_a, d: cos_a, tx: 0.0, ty: 0.0 }
}
///|
/// Creates a scaling matrix
pub fn Matrix2D::scale(sx : Double, sy : Double) -> Matrix2D {
{ a: sx, b: 0.0, c: 0.0, d: sy, tx: 0.0, ty: 0.0 }
}
///|
/// Creates a reflection matrix across a line through the origin at angle (radians)
pub fn Matrix2D::reflect(angle : Double) -> Matrix2D {
let cos_2a = @math.cos(2.0 * angle)
let sin_2a = @math.sin(2.0 * angle)
{ a: cos_2a, b: sin_2a, c: sin_2a, d: -cos_2a, tx: 0.0, ty: 0.0 }
}
///|
/// Multiplies two matrices: self * other
pub fn Matrix2D::multiply(self : Matrix2D, other : Matrix2D) -> Matrix2D {
{
a: self.a * other.a + self.c * other.b,
b: self.b * other.a + self.d * other.b,
c: self.a * other.c + self.c * other.d,
d: self.b * other.c + self.d * other.d,
tx: self.a * other.tx + self.c * other.ty + self.tx,
ty: self.b * other.tx + self.d * other.ty + self.ty,
}
}
///|
/// Applies the matrix transformation to a 2D point (x, y)
pub fn Matrix2D::transform_point(
self : Matrix2D,
x : Double,
y : Double,
) -> (Double, Double) {
(self.a * x + self.c * y + self.tx, self.b * x + self.d * y + self.ty)
}