use super::DVec2;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Linear(DVec2);
impl Linear {
pub const IDENTITY: Linear = Linear(DVec2(1.0, 0.0));
pub const ZERO: Linear = Linear(DVec2::ZERO);
#[inline]
pub fn new(u: f64, v: f64) -> Self {
Linear(DVec2(u, v))
}
#[inline]
pub fn scale(scale: f64) -> Self {
Linear(DVec2(scale, 0.0))
}
pub fn rotate(radians: f64) -> Self {
let (s, c) = radians.sin_cos();
Linear(DVec2(c, s))
}
#[inline]
pub fn from_vectors(a: DVec2, b: DVec2) -> Self {
Linear(b.complex_div(a))
}
#[inline]
pub fn pan(a: DVec2, b: DVec2, (scale, rotate): (bool, bool)) -> Self {
match (scale, rotate) {
(false, false) => Self::IDENTITY,
(true, false) => Self::scale((b.sum_square() / a.sum_square()).sqrt()),
(false, true) => Linear::from_vectors(a, b).normalize(),
(true, true) => Linear::from_vectors(a, b),
}
}
#[inline]
pub fn get_complex(self) -> (f64, f64) {
(self.0.0, self.0.1)
}
#[inline]
pub fn get_vec2(self) -> DVec2 {
self.0
}
#[inline]
pub fn get_scale(self) -> f64 {
self.0.sum_square().sqrt()
}
#[inline]
pub fn get_angle(self) -> f64 {
self.0.1.atan2(self.0.0)
}
#[inline]
pub fn has_scale(self) -> bool {
self.0.sum_square() != 1.0
}
#[inline]
pub fn has_rotation(self) -> bool {
self.0.1 != 0.0
}
#[inline]
pub fn is_finite(self) -> bool {
self.0.is_finite()
}
#[inline]
pub fn is_bijective(self) -> bool {
self.0.0.is_normal() && (self.0.1.is_normal() || self.0.1 == 0.0)
}
#[inline]
pub fn normalize(self) -> Self {
Linear(self.0 / self.0.sum_square().sqrt())
}
#[inline]
pub fn inverse(self) -> Self {
Linear(self.0.complex_inv())
}
}
impl Neg for Linear {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Linear(-self.0)
}
}
impl Mul<f64> for Linear {
type Output = Linear;
#[inline]
fn mul(self, rhs: f64) -> Linear {
Linear(self.0 * rhs)
}
}
impl MulAssign<f64> for Linear {
#[inline]
fn mul_assign(&mut self, rhs: f64) {
self.0 *= rhs;
}
}
impl Div<f64> for Linear {
type Output = Linear;
#[inline]
fn div(self, rhs: f64) -> Linear {
Linear(self.0 / rhs)
}
}
impl DivAssign<f64> for Linear {
#[inline]
fn div_assign(&mut self, rhs: f64) {
self.0 /= rhs;
}
}
impl Add<Linear> for Linear {
type Output = Linear;
#[inline]
fn add(self, rhs: Linear) -> Linear {
Linear(self.0 + rhs.0)
}
}
impl AddAssign<Linear> for Linear {
#[inline]
fn add_assign(&mut self, rhs: Linear) {
self.0 += rhs.0;
}
}
impl Sub<Linear> for Linear {
type Output = Linear;
#[inline]
fn sub(self, rhs: Linear) -> Linear {
Linear(self.0 - rhs.0)
}
}
impl SubAssign<Linear> for Linear {
#[inline]
fn sub_assign(&mut self, rhs: Linear) {
self.0 -= rhs.0;
}
}
impl Mul<Linear> for Linear {
type Output = Linear;
#[inline]
fn mul(self, rhs: Linear) -> Linear {
Linear(self.0.complex_mul(rhs.0))
}
}
impl MulAssign<Linear> for Linear {
#[inline]
fn mul_assign(&mut self, rhs: Linear) {
*self = *self * rhs;
}
}
impl Div<Linear> for Linear {
type Output = Linear;
#[inline]
fn div(self, rhs: Linear) -> Linear {
Linear(self.0.complex_div(rhs.0))
}
}
impl DivAssign<Linear> for Linear {
#[inline]
fn div_assign(&mut self, rhs: Linear) {
self.0 = self.0.complex_div(rhs.0);
}
}
impl Mul<DVec2> for Linear {
type Output = DVec2;
#[inline]
fn mul(self, rhs: DVec2) -> DVec2 {
self.0.complex_mul(rhs)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Affine {
alpha: Linear,
delta: DVec2,
}
impl Affine {
pub const IDENTITY: Affine = Affine {
alpha: Linear::IDENTITY,
delta: DVec2::ZERO,
};
#[inline]
pub fn new(alpha: Linear, delta: DVec2) -> Self {
Affine { alpha, delta }
}
#[inline]
pub fn translate(delta: DVec2) -> Self {
Affine {
alpha: Linear::IDENTITY,
delta,
}
}
pub fn from_vectors(x0: DVec2, x1: DVec2, y0: DVec2, y1: DVec2) -> Self {
let alpha = Linear::from_vectors(x1 - x0, y1 - y0);
let delta = (x1 - alpha * x0 + y1 - alpha * y0) * 0.5;
Affine { alpha, delta }
}
pub fn pan(x0: DVec2, x1: DVec2, y0: DVec2, y1: DVec2, (scale, rotate): (bool, bool)) -> Self {
let alpha = Linear::pan(y0 - x0, y1 - x1, (scale, rotate));
let delta = (x1 - alpha * x0 + y1 - alpha * y0) * 0.5;
Affine { alpha, delta }
}
#[inline]
pub fn alpha(self) -> Linear {
self.alpha
}
#[inline]
pub fn delta(self) -> DVec2 {
self.delta
}
#[inline]
pub fn has_translation(self) -> bool {
self.delta != DVec2::ZERO
}
#[inline]
pub fn as_translation(self) -> Option<DVec2> {
if self.alpha == Linear::IDENTITY {
Some(self.delta)
} else {
None
}
}
#[inline]
pub fn as_scale_and_translation(self) -> Option<(f64, DVec2)> {
if self.alpha.0.1 == 0.0 {
Some((self.alpha.0.0, self.delta))
} else {
None
}
}
#[inline]
pub fn is_finite(self) -> bool {
self.alpha.is_finite() && self.delta.is_finite()
}
pub fn inverse(self) -> Self {
let alpha = self.alpha.inverse();
let delta = -alpha * self.delta;
Affine { alpha, delta }
}
}
impl From<Linear> for Affine {
#[inline]
fn from(alpha: Linear) -> Self {
Affine {
alpha,
delta: DVec2::ZERO,
}
}
}
impl Mul<DVec2> for Affine {
type Output = DVec2;
#[inline]
fn mul(self, rhs: DVec2) -> DVec2 {
self.alpha * rhs + self.delta
}
}
impl Mul<Linear> for Affine {
type Output = Affine;
#[inline]
fn mul(mut self, rhs: Linear) -> Affine {
self.alpha *= rhs;
self
}
}
impl MulAssign<Linear> for Affine {
#[inline]
fn mul_assign(&mut self, rhs: Linear) {
self.alpha *= rhs;
}
}
impl Mul<Affine> for Linear {
type Output = Affine;
fn mul(self, rhs: Affine) -> Affine {
let alpha = self * rhs.alpha;
let delta = self * rhs.delta;
Affine { alpha, delta }
}
}
impl Mul<Affine> for Affine {
type Output = Affine;
fn mul(self, rhs: Affine) -> Affine {
let alpha = self.alpha * rhs.alpha;
let delta = self.alpha * rhs.delta + self.delta;
Affine { alpha, delta }
}
}
impl Div<Linear> for Affine {
type Output = Affine;
#[inline]
fn div(mut self, rhs: Linear) -> Affine {
self.alpha /= rhs;
self
}
}
impl DivAssign<Linear> for Affine {
#[inline]
fn div_assign(&mut self, rhs: Linear) {
self.alpha /= rhs;
}
}
impl Div<Affine> for Linear {
type Output = Affine;
fn div(self, rhs: Affine) -> Affine {
let alpha = self / rhs.alpha;
let delta = -alpha * rhs.delta;
Affine { alpha, delta }
}
}
impl Div<Affine> for Affine {
type Output = Affine;
fn div(self, rhs: Affine) -> Affine {
let alpha = self.alpha / rhs.alpha;
let delta = self.delta - alpha * rhs.delta;
Affine { alpha, delta }
}
}
impl Add<DVec2> for Affine {
type Output = Affine;
#[inline]
fn add(mut self, rhs: DVec2) -> Affine {
self.delta += rhs;
self
}
}
impl AddAssign<DVec2> for Affine {
#[inline]
fn add_assign(&mut self, rhs: DVec2) {
self.delta += rhs;
}
}
impl Sub<DVec2> for Affine {
type Output = Affine;
#[inline]
fn sub(mut self, rhs: DVec2) -> Affine {
self.delta -= rhs;
self
}
}
impl SubAssign<DVec2> for Affine {
#[inline]
fn sub_assign(&mut self, rhs: DVec2) {
self.delta -= rhs;
}
}