More functions in math

This commit is contained in:
Thomas Forgione 2018-03-12 11:15:51 +01:00
parent 037b38c704
commit 2748c16f55
No known key found for this signature in database
GPG Key ID: C75CD416BD1FFCE1
2 changed files with 79 additions and 1 deletions

View File

@ -9,6 +9,7 @@ macro_rules! make_bounding_box {
use math::vector::$vector;
/// Represents a bounding box.
#[derive(Clone)]
pub struct $name<T> {
min: $vector<T>,
max: $vector<T>,
@ -45,6 +46,16 @@ macro_rules! make_bounding_box {
self.max
}
/// Returns a mut ref to the min.
pub fn min_mut(&mut self) -> &mut $vector<T> {
&mut self.min
}
/// Returns a mut ref to the max.
pub fn max_mut(&mut self) -> &mut $vector<T> {
&mut self.max
}
}
impl<T: Number> $name<T> {
@ -55,6 +66,20 @@ macro_rules! make_bounding_box {
self.min -= diag * factor;
self.max += diag * factor;
}
/// Returns the intersection between two bounding boxes.
pub fn intersection(&self, other: &$name<T>) -> $name<T> {
let mut ret = self.clone();
for i in 0..$size {
if ret.min()[i] > other.min()[i] {
ret.min_mut()[i] = other.min()[i];
}
if ret.max()[i] < other.max()[i] {
ret.max_mut()[i] = other.max()[i];
}
}
ret
}
}
}
@ -63,3 +88,37 @@ macro_rules! make_bounding_box {
make_bounding_box!(BoundingBox2, Vector2, 2);
make_bounding_box!(BoundingBox3, Vector3, 3);
make_bounding_box!(BoundingBox4, Vector4, 4);
#[cfg(test)]
mod tests {
macro_rules! assert_delta {
($x:expr, $y:expr, $d:expr) => {
if !($x - $y < $d || $y - $x < $d) { panic!(); }
}
}
use math::vector::Vector2;
use math::bounding_box::BoundingBox2;
#[test]
fn initialization() {
use std::f64::{MIN, MAX};
let mut bounding_box = BoundingBox2::new(
Vector2::new(MAX, MAX),
Vector2::new(MIN, MIN),
);
let v1 = Vector2::new(10.0, 20.0);
bounding_box.add_point(&v1);
assert_delta!(bounding_box.min().x(), v1.x(), 0.01);
assert_delta!(bounding_box.min().y(), v1.y(), 0.01);
assert_delta!(bounding_box.max().x(), v1.x(), 0.01);
assert_delta!(bounding_box.max().y(), v1.y(), 0.01);
let v2 = Vector2::new(20.0, 10.0);
assert_delta!(bounding_box.min().x(), v1.x(), 0.01);
assert_delta!(bounding_box.min().y(), v2.y(), 0.01);
assert_delta!(bounding_box.max().x(), v1.x(), 0.01);
assert_delta!(bounding_box.max().y(), v2.y(), 0.01);
}
}

View File

@ -2,6 +2,8 @@
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Index, IndexMut};
use std::fmt;
use num::Zero;
use num::Float;
use math::Number;
@ -100,11 +102,16 @@ macro_rules! make_vector {
}
impl<T: Number + Float> $name<T> {
/// Computes the 2-norm of the vector
/// Computes the 2-norm of the vector.
pub fn norm(&self) -> T {
self.norm2().sqrt()
}
/// Divides each coordinate by the norm of the vector.
pub fn normalize(&mut self) {
*self /= self.norm()
}
}
impl<T: Number> Add for $name<T> {
@ -185,6 +192,18 @@ macro_rules! make_vector {
}
}
impl<T: fmt::Display> fmt::Display for $name<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "(")?;
for i in &self.data {
write!(formatter, "{}, ", i)?;
}
write!(formatter, ")")?;
Ok(())
}
}
// impl<T: PartialEq> PartialEq for $name<T> {
// fn eq(&self, other: &$name<T>) -> bool {
// for (x1, x2) in self.data.iter().zip(other.data.iter()) {