Commit 5d5fb7d1 authored by Luke Jones's avatar Luke Jones

Adjust vec functions. Make vec2d*vec2d return scalar

parent ef4dc76b
// Copied from https://raw.githubusercontent.com/LFalch/simple-vector2d/master/src/lib.rs
// and modified to suit my needs
extern crate num_traits;
/// Representation of a mathematical vector e.g. a position or velocity
......@@ -22,80 +20,44 @@ macro_rules! impl_vec_ops_for {
let (y, x) = direction.sin_cos();
Vec2d { x: x, y: y }
}
/// Normalises the vector
pub fn normalise(self) -> Self {
let mut magnitude = self.magnitude();
if magnitude <= 0.0001 { magnitude = 0.0 }
self / magnitude
let magnitude = self.magnitude();
if magnitude > 0.0 {
return self * (1.0 / magnitude)
} self
}
/// Returns the magnitude/length of the vector
pub fn magnitude(self) -> $t{
(self.x.powf(2.0) + self.y.powf(2.0)).sqrt()
}
/// Returns the (non-sqrt) magnitude/length of the vector
pub fn square_magnitude(self) -> $t{
self.x.powf(2.0) + self.y.powf(2.0)
}
/// Returns direction the vector is pointing
pub fn direction(self) -> $t{
self.y.atan2(self.x)
}
/// Returns direction towards another vector
pub fn direction_to(self, other: Self) -> $t{
(other-self).direction()
}
/// Returns the distance betweens two vectors
pub fn distance_to(self, other: Self) -> $t{
(other-self).magnitude()
}
/// Returns `true` if either component is `NaN`.
pub fn is_any_nan(&self) -> bool{
self.x.is_nan() || self.y.is_nan()
}
/// Returns `true` if either component is positive or negative infinity.
pub fn is_any_infinite(&self) -> bool{
self.x.is_infinite() || self.y.is_infinite()
}
/// Returns `true` if both components are neither infinite nor `NaN`.
pub fn is_all_finite(&self) -> bool{
self.x.is_finite() && self.y.is_finite()
}
/// Returns `true` if both components are neither zero, infinite, subnormal nor `NaN`.
pub fn is_all_normal(&self) -> bool{
self.x.is_normal() && self.y.is_normal()
}
}
)*};
}
impl_vec_ops_for!(f32 f64);
/// Returns floats in all cases. Main purpose is to help when using SDL2 etc
impl Vec2d<i32> {
/// Normalises the vector
pub fn normalise(self) -> Vec2d<f32> {
let mut mag = self.magnitude();
if mag <= 0.0001 {
mag = 0.0
}
Vec2d {
x: self.x as f32 / mag,
y: self.y as f32 / mag,
}
}
/// Returns the magnitude/length of the vector
pub fn magnitude(self) -> f32 {
((self.x as f32).powi(2) + (self.y as f32).powi(2)).sqrt()
}
/// Returns direction the vector is pointing
pub fn direction(self) -> f32 {
(self.y as f32).atan2(self.x as f32)
}
/// Returns direction towards another vector
pub fn direction_to(self, other: Self) -> f32 {
(other - self).direction()
}
/// Returns the distance betweens two vectors
pub fn distance_to(self, other: Self) -> f32 {
(other - self).magnitude()
}
}
/******************************************
Standard Vector operators
******************************************/
......@@ -165,14 +127,13 @@ impl<T: Mul + Copy> Mul<T> for Vec2d<T> {
}
}
}
/// Multiply `Vec2d` by `Vec2d`
impl<T: Mul> Mul for Vec2d<T> {
type Output = Vec2d<T::Output>;
/// Calculate and return the scalar product of this `Vec2d` by `Vec2d`
impl<T: Mul + Add> Mul for Vec2d<T>
where
<T as Mul>::Output: Add {
type Output = <<T as Mul>::Output as Add>::Output;
fn mul(self, rhs: Self) -> Self::Output {
Vec2d {
x: self.x * rhs.x,
y: self.y * rhs.y,
}
self.x * rhs.x + self.y * rhs.y
}
}
/// Divide `Vec2d` by scalar
......@@ -301,6 +262,13 @@ impl<T> From<(T, T)> for Vec2d<T> {
mod tests {
use super::*;
use std::f32::consts::PI;
#[test]
fn multiply_two_vec2d_for_scalar() {
let point1: Vec2d<f32> = Vec2d::new(1.0, 2.0);
let point2: Vec2d<f32> = Vec2d::new(2.0, 3.0);
assert_eq!(point1 * point2, 8.0);
}
#[test]
fn unit_vector_float_32() {
......@@ -357,42 +325,4 @@ mod tests {
let point: Vec2d<f32> = Vec2d::new(4.0, 3.0);
assert_eq!(point.magnitude(), 5.0);
}
#[test]
fn direction_pi_i32() {
let point: Vec2d<i32> = Vec2d::new(-1, 0);
assert_eq!(point.direction(), PI);
}
#[test]
fn direction_pi2_i32() {
let point: Vec2d<i32> = Vec2d::new(0, 1);
assert_eq!(point.direction(), PI / 2.0);
}
#[test]
fn direction_to_i32() {
let point1: Vec2d<i32> = Vec2d::new(0, 3);
let point2: Vec2d<i32> = Vec2d::new(0, 0);
assert_eq!(point1.direction_to(point2), -(PI / 2.0));
}
#[test]
fn distance_to_i32() {
let point1: Vec2d<i32> = Vec2d::new(0, 3);
let point2: Vec2d<i32> = Vec2d::new(0, 0);
assert_eq!(point1.distance_to(point2), 3.0);
}
#[test]
fn normalise_i32() {
let point: Vec2d<i32> = Vec2d::new(4, 3);
assert_eq!(point.normalise(), Vec2d::new(0.8, 0.6));
}
#[test]
fn magnitude_i32() {
let point: Vec2d<i32> = Vec2d::new(4, 3);
assert_eq!(point.magnitude(), 5.0);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment