diff --git a/src/geom/point.rs b/src/geom/point.rs index e9c68d5..9d3edfd 100644 --- a/src/geom/point.rs +++ b/src/geom/point.rs @@ -18,13 +18,21 @@ use std::cast; use core::{Vec2, Vec3, Quat}; /// A geometric point -pub trait Point: Eq + ApproxEq + ToStr { +pub trait Point: Eq + + Add + + Sub + + Mul + + ApproxEq + + ToStr { pub fn as_vec<'a>(&'a self) -> &'a Vec; pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec; pub fn translate(&self, offset: &Vec) -> Self; pub fn rotate(&self, rotation: &Rot) -> Self; + pub fn scale(&self, factor: &Vec) -> Self; + pub fn distance2(&self, other: &Self) -> T; pub fn distance(&self, other: &Self) -> T; + pub fn direction(&self, other: &Self) -> Vec; } /// A two-dimensional point @@ -43,7 +51,7 @@ impl Point2 { } } -impl Point,T> for Point2 { +impl Point, T> for Point2 { #[inline] pub fn as_vec<'a>(&'a self) -> &'a Vec2 { unsafe { cast::transmute(self) } @@ -56,18 +64,54 @@ impl Point,T> for Point2 { #[inline] pub fn translate(&self, offset: &Vec2) -> Point2 { - Point2::from_vec(self.as_vec().add_v(offset)) + (*self) + (*offset) } #[inline] pub fn rotate(&self, radians: &T) -> Point2 { - Point2::new((*radians) * (*self).x.cos(), - (*radians) * (*self).y.sin()) + Point2::new((*self).x.cos() * (*radians), + (*self).y.sin() * (*radians)) + } + + #[inline] + pub fn scale(&self, factor: &Vec2) -> Point2 { + (*self) * (*factor) + } + + #[inline] + pub fn distance2(&self, other: &Point2) -> T { + ((*other) - (*self)).length2() } #[inline] pub fn distance(&self, other: &Point2) -> T { - self.as_vec().distance(other.as_vec()) + other.distance2(self).sqrt() + } + + #[inline] + pub fn direction(&self, other: &Point2) -> Vec2 { + ((*other) - (*self)).normalize() + } +} + +impl Add, Point2> for Point2 { + fn add(&self, other: &Vec2) -> Point2 { + Point2::new((*self).x + (*other).x, + (*self).y + (*other).y) + } +} + +impl Sub, Vec2> for Point2 { + fn sub(&self, other: &Point2) -> Vec2 { + Vec2::new((*self).x - (*other).x, + (*self).y - (*other).y) + } +} + +impl Mul, Point2> for Point2 { + fn mul(&self, scale: &Vec2) -> Point2 { + Point2::new((*self).x * (*scale).x, + (*self).y * (*scale).y) } } @@ -121,7 +165,7 @@ impl Point3 { } } -impl Point,Quat> for Point3 { +impl Point, Quat> for Point3 { #[inline] pub fn as_vec<'a>(&'a self) -> &'a Vec3 { unsafe { cast::transmute(self) } @@ -134,7 +178,7 @@ impl Point,Quat> for Point3 { #[inline] pub fn translate(&self, offset: &Vec3) -> Point3 { - Point3::from_vec(self.as_vec().add_v(offset)) + (*self) + (*offset) } #[inline] @@ -142,9 +186,48 @@ impl Point,Quat> for Point3 { Point3::from_vec(rotation.mul_v(self.as_vec())) } + #[inline] + pub fn scale(&self, factor: &Vec3) -> Point3 { + (*self) * (*factor) + } + + #[inline] + pub fn distance2(&self, other: &Point3) -> T { + ((*other) - (*self)).length2() + } + #[inline] pub fn distance(&self, other: &Point3) -> T { - self.as_vec().distance(other.as_vec()) + other.distance2(self).sqrt() + } + + #[inline] + pub fn direction(&self, other: &Point3) -> Vec3 { + ((*other) - (*self)).normalize() + } +} + +impl Add, Point3> for Point3 { + fn add(&self, other: &Vec3) -> Point3 { + Point3::new((*self).x + (*other).x, + (*self).y + (*other).y, + (*self).z + (*other).z) + } +} + +impl Sub, Vec3> for Point3 { + fn sub(&self, other: &Point3) -> Vec3 { + Vec3::new((*self).x - (*other).x, + (*self).y - (*other).y, + (*self).z - (*other).z) + } +} + +impl Mul, Point3> for Point3 { + fn mul(&self, scale: &Vec3) -> Point3 { + Point3::new((*self).x * (*scale).x, + (*self).y * (*scale).y, + (*self).z * (*scale).z) } }