use kas::geom::{Coord, Rect, Size};
use std::ops::{Add, Div, Mul, Neg, Sub};
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Quad {
pub a: Vec2,
pub b: Vec2,
}
impl Quad {
#[inline]
pub fn size(&self) -> Vec2 {
self.b - self.a
}
#[inline]
pub fn ab(&self) -> Vec2 {
Vec2(self.a.0, self.b.1)
}
#[inline]
pub fn ba(&self) -> Vec2 {
Vec2(self.b.0, self.a.1)
}
#[inline]
pub fn shrink(&self, value: f32) -> Quad {
let a = self.a + value;
let b = self.b - value;
debug_assert!(a.le(b));
Quad { a, b }
}
#[inline]
pub fn shrink_vec(&self, value: Vec2) -> Quad {
let a = self.a + value;
let b = self.b - value;
debug_assert!(a.le(b));
Quad { a, b }
}
}
impl From<Rect> for Quad {
#[inline]
fn from(rect: Rect) -> Quad {
let a = Vec2::from(rect.pos);
let b = a + Vec2::from(rect.size);
Quad { a, b }
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vec2(pub f32, pub f32);
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct DVec2(pub f64, pub f64);
macro_rules! impl_vec2 {
($T:ident, $f:ty) => {
impl $T {
pub const ZERO: $T = $T(0.0, 0.0);
#[inline]
pub const fn splat(value: $f) -> Self {
$T(value, value)
}
#[inline]
pub fn min_comp(self) -> $f {
self.0.min(self.1)
}
#[inline]
pub fn sign(self) -> Self {
let one: $f = 1.0;
$T(one.copysign(self.0), one.copysign(self.1))
}
#[inline]
pub fn lt(self, rhs: Self) -> bool {
self.0 < rhs.0 && self.1 < rhs.1
}
#[inline]
pub fn le(self, rhs: Self) -> bool {
self.0 <= rhs.0 && self.1 <= rhs.1
}
#[inline]
pub fn ge(self, rhs: Self) -> bool {
self.0 >= rhs.0 && self.1 >= rhs.1
}
#[inline]
pub fn gt(self, rhs: Self) -> bool {
self.0 > rhs.0 && self.1 > rhs.1
}
#[inline]
pub fn complex_mul(self, rhs: Self) -> Self {
$T(
self.0 * rhs.0 - self.1 * rhs.1,
self.0 * rhs.1 + self.1 * rhs.0,
)
}
#[inline]
pub fn complex_div(self, rhs: Self) -> Self {
self.complex_mul(rhs.complex_inv())
}
#[inline]
pub fn complex_inv(self) -> Self {
let ssi = 1.0 / self.sum_square();
$T(self.0 * ssi, -self.1 * ssi)
}
#[inline]
pub fn sum(self) -> $f {
self.0 + self.1
}
#[inline]
pub fn sum_square(self) -> $f {
self.0 * self.0 + self.1 * self.1
}
}
impl Neg for $T {
type Output = $T;
#[inline]
fn neg(self) -> Self::Output {
$T(-self.0, -self.1)
}
}
impl Add<$T> for $T {
type Output = $T;
#[inline]
fn add(self, rhs: $T) -> Self::Output {
$T(self.0 + rhs.0, self.1 + rhs.1)
}
}
impl Add<$f> for $T {
type Output = $T;
#[inline]
fn add(self, rhs: $f) -> Self::Output {
$T(self.0 + rhs, self.1 + rhs)
}
}
impl Sub<$T> for $T {
type Output = $T;
#[inline]
fn sub(self, rhs: $T) -> Self::Output {
$T(self.0 - rhs.0, self.1 - rhs.1)
}
}
impl Sub<$f> for $T {
type Output = $T;
#[inline]
fn sub(self, rhs: $f) -> Self::Output {
$T(self.0 - rhs, self.1 - rhs)
}
}
impl Mul<$T> for $T {
type Output = $T;
#[inline]
fn mul(self, rhs: $T) -> Self::Output {
$T(self.0 * rhs.0, self.1 * rhs.1)
}
}
impl Mul<$f> for $T {
type Output = $T;
#[inline]
fn mul(self, rhs: $f) -> Self::Output {
$T(self.0 * rhs, self.1 * rhs)
}
}
impl Div<$T> for $T {
type Output = $T;
#[inline]
fn div(self, rhs: $T) -> Self::Output {
$T(self.0 / rhs.0, self.1 / rhs.1)
}
}
impl Div<$f> for $T {
type Output = $T;
#[inline]
fn div(self, rhs: $f) -> Self::Output {
$T(self.0 / rhs, self.1 / rhs)
}
}
impl From<($f, $f)> for $T {
#[inline]
fn from(arg: ($f, $f)) -> Self {
$T(arg.0, arg.1)
}
}
impl From<$T> for ($f, $f) {
#[inline]
fn from(v: $T) -> Self {
(v.0, v.1)
}
}
impl From<Coord> for $T {
#[inline]
fn from(arg: Coord) -> Self {
$T(arg.0 as $f, arg.1 as $f)
}
}
impl From<Size> for $T {
#[inline]
fn from(arg: Size) -> Self {
$T(arg.0 as $f, arg.1 as $f)
}
}
impl From<$T> for Coord {
#[inline]
fn from(arg: $T) -> Self {
Coord(arg.0.round() as i32, arg.1.round() as i32)
}
}
impl From<$T> for Size {
#[inline]
fn from(arg: $T) -> Self {
Size(arg.0.round() as u32, arg.1.round() as u32)
}
}
};
}
impl_vec2!(Vec2, f32);
impl_vec2!(DVec2, f64);
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Vec3(pub f32, pub f32, pub f32);
impl Vec3 {
#[inline]
pub fn from2(v: Vec2, z: f32) -> Self {
Vec3(v.0, v.1, z)
}
}