use num_traits::real::Real;
#[doc = "## Examples"]
#[doc = "```"]
#[doc = include_str ! ("../../tests/point.rs")]
#[doc = "```"]
pub trait Projective<T>
where
Self: Sized,
T: Real,
{
fn transform(&mut self, matrix: &[&T; 9]);
#[inline(always)]
#[rustfmt::skip]
fn translate(&mut self, x: &T, y: &T) {
self.transform(&[
&T::one(), &T::zero(), x,
&T::zero(), &T::one(), y,
&T::zero(), &T::zero(), &T::one()
])
}
#[inline(always)]
fn translate_x(&mut self, x: &T) {
self.translate(x, &T::zero())
}
#[inline(always)]
fn translate_y(&mut self, y: &T) {
self.translate(&T::zero(), y)
}
#[inline(always)]
#[rustfmt::skip]
fn rotate(&mut self, angle: &T) {
let cos = angle.cos();
let sin = angle.sin();
self.transform(&[
&cos, &sin, &T::zero(),
&sin.neg(), &cos, &T::zero(),
&T::zero(), &T::zero(), &T::one(),
])
}
#[inline(always)]
fn rotate_point(&mut self, point: &[&T; 2], angle: &T) {
self.translate(&point[0].neg(), &point[1].neg());
self.rotate(angle);
self.translate(point[0], point[1])
}
#[inline(always)]
#[rustfmt::skip]
fn scale(&mut self, x: &T, y: &T) {
self.transform(&[
x, &T::zero(), &T::zero(),
&T::zero(), y, &T::zero(),
&T::zero(), &T::zero(), &T::one(),
])
}
#[inline(always)]
fn scale_x(&mut self, x: &T) {
self.scale(x, &T::one())
}
#[inline(always)]
fn scale_y(&mut self, y: &T) {
self.scale(&T::one(), y)
}
#[inline(always)]
#[rustfmt::skip]
fn reflect(&mut self, x: &T, y: &T) {
self.transform(&[
&T::one(), &T::zero(), &T::zero(),
&T::zero(), &T::one(), &T::zero(),
x, y, &T::one(),
])
}
#[inline(always)]
fn reflect_x(&mut self) {
self.reflect(&T::zero(), &T::one())
}
#[inline(always)]
fn reflect_y(&mut self) {
self.reflect(&T::one(), &T::zero())
}
#[inline(always)]
#[rustfmt::skip]
fn skew(&mut self, a: &T, b: &T) {
self.transform(&[
&T::one(), &a.tan(), &T::zero(),
&b.tan(), &T::one(), &T::zero(),
&T::zero(), &T::zero(), &T::one(),
])
}
#[inline(always)]
fn skew_x(&mut self, a: &T) {
self.skew(a, &T::zero())
}
#[inline(always)]
fn skew_y(&mut self, b: &T) {
self.skew(&T::zero(), b)
}
}