glium_types/vectors/
dvec2.rs

1use crate::matrices::DMat2;
2use derive_cmp_ops::CmpOps;
3use glium::uniforms::AsUniformValue;
4
5use super::{ dvec3::{dvec3, DVec3}, vec2::Vec2, bvec2::*};
6#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, CmpOps)]
7/// a double vector made from a x and y coordinate
8pub struct DVec2 {
9    pub x: f64,
10    pub y: f64,
11}
12impl DVec2 {
13    /// a zero vector
14    pub const ZERO: Self = dvec2(0.0, 0.0);
15    /// a vector full of ones
16    pub const ONE: Self = dvec2(1.0, 1.0);
17    /// the x axis
18    pub const X: Self = dvec2(1.0, 0.0);
19    /// the y axis
20    pub const Y: Self = dvec2(0.0, 1.0);
21
22    pub const fn new(x: f64, y: f64) -> Self { Self { x, y } }
23    pub const fn extend(self, z: f64) -> DVec3 { dvec3(self.x, self.y, z) }
24    pub fn truncate(self) -> f64 { self.x }
25    /// create a vector where x and y equals `value`
26    pub fn splat(value: f64) -> Self { Self::new(value, value) }
27
28    /// the length of the vector before being square rooted
29    pub fn length_squared(self) -> f64 {
30        self.x * self.x + self.y * self.y
31    }
32    /// length of the vector
33    pub fn length(self) -> f64 {
34        self.length_squared().sqrt()
35    }
36    /// distance between two vectors before being square rooted
37    pub fn distance_squared(self, other: DVec2) -> f64 {
38        (self - other).length_squared()
39    }
40    /// distance between two vectors
41    pub fn distance(self, other: DVec2) -> f64 {
42        (self - other).length()
43    }
44    /// get the dot product of 2 vectors. equal to the cosign of the angle between vectors
45    pub fn dot(self, other: DVec2) -> f64 {
46        self.x * other.x + self.y * other.y
47    }
48    /// multiplies each value by the scalar
49    pub fn scale(self, scalar: f64) -> DVec2 {
50        Self::new(self.x * scalar, self.y * scalar)
51    }
52    /// makes the length of the vector equal to 1. on fail returns dvec2 of zeros
53    pub fn normalise(self) -> Self {
54        let length = self.length();
55        if length == 0.0 {
56            return dvec2(0.0, 0.0);
57        }
58        self.scale(1.0 / length)
59    }
60    /// transforms the vector by the matrix
61    pub fn transform(self, matrix: DMat2) -> DVec2 {
62        let a: DVec2 = matrix.row(0).into();
63        let b: DVec2 = matrix.row(1).into();
64        dvec2(a.dot(self), b.dot(self))
65    }
66    /// returns whether the 2 components are equal
67    pub fn eq(self, rhs: Self) -> BVec2 { bvec2(self.x == rhs.x, self.y == rhs.y) }
68    /// returns whether the 1st components are less than the 2nd
69    pub fn less(self, rhs: Self) -> BVec2 { bvec2(self.x < rhs.x, self.y < rhs.y) }
70    /// returns whether the 1st components are more than the 2nd
71    pub fn more(self, rhs: Self) -> BVec2 { bvec2(self.x > rhs.x, self.y > rhs.y) }
72    /// returns whether the 1st components are less than or equal to the 2nd
73    pub fn less_or_eq(self, rhs: Self) -> BVec2 { bvec2(self.x <= rhs.x, self.y <= rhs.y) }
74    /// returns whether the 1st components are more than or equal to the 2nd
75    pub fn more_or_eq(self, rhs: Self) -> BVec2 { bvec2(self.x >= rhs.x, self.y >= rhs.y) }
76}
77impl std::ops::Mul<DVec2> for f64 {
78    fn mul(self, rhs: DVec2) -> Self::Output { rhs * self }
79    type Output = DVec2;
80}
81impl std::ops::Mul<f64> for DVec2 {
82    fn mul(self, rhs: f64) -> Self::Output { self.scale(rhs) }
83    type Output = Self;
84}
85impl std::ops::MulAssign<f64> for DVec2 { fn mul_assign(&mut self, rhs: f64) { *self = *self * rhs } }
86impl std::ops::Div<DVec2> for f64 {
87    fn div(self, rhs: DVec2) -> Self::Output { DVec2::splat(self) / rhs }
88    type Output = DVec2;
89}
90impl std::ops::Div<f64> for DVec2 {
91    fn div(self, rhs: f64) -> Self::Output { self.scale(1.0/rhs) }
92    type Output = Self;
93}
94impl std::ops::DivAssign<f64> for DVec2 { fn div_assign(&mut self, rhs: f64) { *self = *self / rhs } }
95impl std::ops::Rem<DVec2> for f64 {
96    fn rem(self, rhs: DVec2) -> Self::Output { DVec2::splat(self) % rhs }
97    type Output = DVec2;
98}
99impl std::ops::Rem<f64> for DVec2 {
100    fn rem(self, rhs: f64) -> Self::Output { self % DVec2::splat(rhs) }
101    type Output = Self;
102}
103impl std::ops::RemAssign<f64> for DVec2 { fn rem_assign(&mut self, rhs: f64) { *self = *self % rhs } }
104impl AsUniformValue for DVec2 {
105    fn as_uniform_value(&self) -> glium::uniforms::UniformValue<'_> {
106        glium::uniforms::UniformValue::DoubleVec2([self.x, self.y])
107    }
108}
109///create a double vector with an x and y coordinate.
110pub const fn dvec2(x: f64, y: f64) -> DVec2 {
111    DVec2 { x, y }
112}
113impl From<Vec2> for DVec2 {
114    fn from(value: Vec2) -> Self {
115        dvec2(value.x as f64, value.y as f64)
116    }
117}
118impl From<[f64; 2]> for DVec2 {
119    fn from(value: [f64; 2]) -> Self {
120        dvec2(value[0], value[1])
121    }
122}
123impl From<(f64, f64)> for DVec2 {
124    fn from(value: (f64, f64)) -> Self {
125        dvec2(value.0, value.1)
126    }
127}
128impl From<[f32; 2]> for DVec2 {
129    fn from(value: [f32; 2]) -> Self {
130        dvec2(value[0] as f64, value[1] as f64)
131    }
132}
133impl From<DVec2> for [f64; 2] {
134    fn from(value: DVec2) -> Self {
135        [value.x, value.y]
136    }
137}
138impl From<DVec2> for (f64, f64) {
139    fn from(value: DVec2) -> Self {
140        (value.x, value.y)
141    }
142}