More functions in math
This commit is contained in:
parent
037b38c704
commit
2748c16f55
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in New Issue