2022-04-08 16:59:52 +00:00
|
|
|
use std::ops::Sub;
|
|
|
|
|
2022-04-03 10:30:36 +00:00
|
|
|
/// A vector with a x and y axis.
|
2022-04-02 15:23:19 +00:00
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct Vector {
|
|
|
|
pub x: f32,
|
|
|
|
pub y: f32
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Vector {
|
2022-04-09 11:01:36 +00:00
|
|
|
pub fn new(x: f32, y: f32) -> Self {
|
2022-04-02 15:23:19 +00:00
|
|
|
Self { x, y }
|
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Returns the halfway point.
|
2022-04-08 16:59:52 +00:00
|
|
|
pub fn center(self) -> Self {
|
|
|
|
Self::new(self.x / 2.0, self.y / 2.0)
|
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Returns the length.
|
2022-04-08 16:59:52 +00:00
|
|
|
pub fn length(self) -> f32 {
|
|
|
|
(self.x * self.x + self.y * self.y).sqrt()
|
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Returns the angle.
|
2022-04-09 17:29:30 +00:00
|
|
|
pub fn angle(self) -> f32 {
|
2022-04-15 05:56:37 +00:00
|
|
|
self.y.atan2(self.x)
|
2022-04-09 17:29:30 +00:00
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Returns the value of the smaller axis.
|
2022-04-08 19:11:00 +00:00
|
|
|
pub fn smaller(self) -> f32 {
|
|
|
|
self.x.min(self.y)
|
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Converts all axis into positive values.
|
2022-04-09 17:29:30 +00:00
|
|
|
pub fn abs(self) -> Vector {
|
|
|
|
Self::new(self.x.abs(), self.y.abs())
|
|
|
|
}
|
|
|
|
|
2022-04-15 05:42:01 +00:00
|
|
|
/// Returns the sum of all axis.
|
2022-04-09 17:29:30 +00:00
|
|
|
pub fn sum(self) -> f32 {
|
|
|
|
self.x + self.y
|
|
|
|
}
|
|
|
|
|
2022-04-03 10:30:36 +00:00
|
|
|
/// Creates a vector with the on screen coordinates based on the terminal coordinates.
|
|
|
|
/// # Arguments
|
|
|
|
/// * `x`: The x axis of the terminal character.
|
|
|
|
/// * `y`: The y axis of the terminal character.
|
2022-04-02 15:23:19 +00:00
|
|
|
pub fn from_terminal(x: usize, y: usize) -> Self {
|
2022-04-03 12:43:14 +00:00
|
|
|
Self::new(x as f32, y as f32 * 2.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-08 16:59:52 +00:00
|
|
|
impl Sub for Vector {
|
|
|
|
type Output = Vector;
|
|
|
|
|
|
|
|
fn sub(self, rhs: Self) -> Self::Output {
|
|
|
|
Vector::new(self.x - rhs.x, self.y - rhs.y)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-03 12:43:14 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn new() {
|
|
|
|
let vec = Vector::new(3.0, 5.0);
|
|
|
|
|
|
|
|
assert_eq!(3.0, vec.x);
|
|
|
|
assert_eq!(5.0, vec.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-04-08 19:11:00 +00:00
|
|
|
fn center() {
|
|
|
|
let vec = Vector::new(3.0, 8.0);
|
2022-04-03 12:43:14 +00:00
|
|
|
|
2022-04-08 19:11:00 +00:00
|
|
|
assert_eq!(1.5, vec.center().x);
|
|
|
|
assert_eq!(4.0, vec.center().y);
|
2022-04-03 12:43:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-04-08 19:11:00 +00:00
|
|
|
fn length() {
|
|
|
|
let vec = Vector::new(3.0, 6.0);
|
|
|
|
|
|
|
|
assert!(6.7 < vec.length() && vec.length() < 6.8);
|
|
|
|
}
|
2022-04-03 12:43:14 +00:00
|
|
|
|
2022-04-15 05:56:37 +00:00
|
|
|
#[test]
|
|
|
|
fn angle() {
|
|
|
|
let vec = Vector::new(3.0, 6.0);
|
|
|
|
|
|
|
|
assert!(1.1 < vec.angle() && vec.angle() < 1.2);
|
|
|
|
}
|
|
|
|
|
2022-04-08 19:11:00 +00:00
|
|
|
#[test]
|
|
|
|
fn smaller() {
|
|
|
|
assert_eq!(4.0, Vector::new(7.0, 4.0).smaller());
|
|
|
|
assert_eq!(2.0, Vector::new(2.0, 9.0).smaller());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn from_terminal() {
|
|
|
|
let vec = Vector::from_terminal(2, 4);
|
|
|
|
|
|
|
|
assert_eq!(2.0, vec.x);
|
|
|
|
assert_eq!(8.0, vec.y);
|
2022-04-03 12:43:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-04-08 19:11:00 +00:00
|
|
|
fn sub() {
|
|
|
|
let left = Vector::new(8.0, 15.0);
|
|
|
|
let right = Vector::new(2.0, 4.0);
|
|
|
|
let result = left - right;
|
2022-04-03 12:43:14 +00:00
|
|
|
|
2022-04-08 19:11:00 +00:00
|
|
|
assert_eq!(6.0, result.x);
|
|
|
|
assert_eq!(11.0, result.y);
|
2022-04-02 15:23:19 +00:00
|
|
|
}
|
|
|
|
}
|