#[derive(Clone, Copy, Debug)]
pub struct Transform {
pub sx: f64,
pub shx: f64,
pub tx: f64,
pub shy: f64,
pub sy: f64,
pub ty: f64,
}
impl Default for Transform {
fn default() -> Self {
Self::identity()
}
}
impl Transform {
pub fn identity() -> Self {
Self {
sx: 1.0,
shx: 0.0,
tx: 0.0,
shy: 0.0,
sy: 1.0,
ty: 0.0,
}
}
pub fn translate(x: f64, y: f64) -> Self {
Self {
sx: 1.0,
shx: 0.0,
tx: x,
shy: 0.0,
sy: 1.0,
ty: y,
}
}
pub fn scale(sx: f64, sy: f64) -> Self {
Self {
sx,
shx: 0.0,
tx: 0.0,
shy: 0.0,
sy,
ty: 0.0,
}
}
pub fn scale_uniform(s: f64) -> Self {
Self::scale(s, s)
}
pub fn rotate(angle: f64) -> Self {
let cos = angle.cos();
let sin = angle.sin();
Self {
sx: cos,
shx: -sin,
tx: 0.0,
shy: sin,
sy: cos,
ty: 0.0,
}
}
pub fn rotate_degrees(degrees: f64) -> Self {
Self::rotate(degrees.to_radians())
}
pub fn apply(&self, x: f64, y: f64) -> (f64, f64) {
(
self.sx * x + self.shx * y + self.tx,
self.shy * x + self.sy * y + self.ty,
)
}
pub fn then(&self, other: &Transform) -> Self {
Self {
sx: self.sx * other.sx + self.shx * other.shy,
shx: self.sx * other.shx + self.shx * other.sy,
tx: self.sx * other.tx + self.shx * other.ty + self.tx,
shy: self.shy * other.sx + self.sy * other.shy,
sy: self.shy * other.shx + self.sy * other.sy,
ty: self.shy * other.tx + self.sy * other.ty + self.ty,
}
}
pub fn with_translate(self, x: f64, y: f64) -> Self {
self.then(&Transform::translate(x, y))
}
pub fn with_scale(self, sx: f64, sy: f64) -> Self {
self.then(&Transform::scale(sx, sy))
}
pub fn with_rotate(self, angle: f64) -> Self {
self.then(&Transform::rotate(angle))
}
}