Make point into standalone struct as opposed to a newtype struct
This commit is contained in:
parent
5b5d1f38b3
commit
a5d4fc1ed4
5 changed files with 83 additions and 36 deletions
|
@ -14,7 +14,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
pub use self::plane::Plane;
|
||||
pub use self::point::{Point2, Point3};
|
||||
pub use self::point::{Point, Point2, Point3};
|
||||
pub use self::ray::Ray3;
|
||||
|
||||
pub mod plane;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
use core::{Vec3, Vec4, Mat3};
|
||||
use geom::{Point3, Ray3};
|
||||
use geom::{Point, Point3, Ray3};
|
||||
|
||||
#[path = "../num_macros.rs"]
|
||||
mod num_macros;
|
||||
|
@ -34,7 +34,7 @@ pub struct Plane<T> {
|
|||
dist: T,
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Plane<T> {
|
||||
impl<T:Clone + Float> Plane<T> {
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `a`: the `x` component of the normal
|
||||
|
@ -60,7 +60,7 @@ impl<T:Clone + Real> Plane<T> {
|
|||
|
||||
/// Compute the distance from the plane to the point
|
||||
pub fn distance(&self, pos: &Point3<T>) -> T {
|
||||
self.norm.dot(&**pos) + self.dist
|
||||
self.norm.dot(pos.as_vec()) + self.dist
|
||||
}
|
||||
|
||||
/// Computes the point at which `ray` intersects the plane
|
||||
|
@ -79,14 +79,14 @@ impl<T:Clone + Real> Plane<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Clone + Real + ApproxEq<T>> Plane<T> {
|
||||
impl<T:Clone + Float> Plane<T> {
|
||||
/// Constructs a plane that passes through the the three points `a`, `b` and `c`
|
||||
pub fn from_3p(a: Point3<T>,
|
||||
b: Point3<T>,
|
||||
c: Point3<T>) -> Option<Plane<T>> {
|
||||
// create two vectors that run parallel to the plane
|
||||
let v0 = (*b).sub_v(&*a);
|
||||
let v1 = (*c).sub_v(&*a);
|
||||
let v0 = b.as_vec().sub_v(a.as_vec());
|
||||
let v1 = c.as_vec().sub_v(a.as_vec());
|
||||
// find the vector that is perpendicular to v1 and v2
|
||||
let mut norm = v0.cross(&v1);
|
||||
|
||||
|
@ -95,7 +95,7 @@ impl<T:Clone + Real + ApproxEq<T>> Plane<T> {
|
|||
} else {
|
||||
// compute the normal and the distance to the plane
|
||||
norm.normalize_self();
|
||||
let dist = -a.dot(&norm);
|
||||
let dist = -a.as_vec().dot(&norm);
|
||||
|
||||
Some(Plane::from_nd(norm, dist))
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ impl<T:Clone + Real + ApproxEq<T>> Plane<T> {
|
|||
} else {
|
||||
// The end-point of the ray is at the three-plane intersection between
|
||||
// `self`, `other`, and a tempory plane positioned at the origin
|
||||
do Plane::from_nd(ray_dir.clone(), zero!(T)).intersection_3pl(self, other).map |ray_pos| {
|
||||
do Plane::from_nd(ray_dir.clone(), zero!(T)).intersection_3pl(self, other).map |&ray_pos| {
|
||||
Ray3 {
|
||||
pos: ray_pos.clone(),
|
||||
dir: ray_dir.clone(),
|
||||
|
@ -136,9 +136,11 @@ impl<T:Clone + Real + ApproxEq<T>> Plane<T> {
|
|||
self.norm.y.clone(), other_a.norm.y.clone(), other_b.norm.y.clone(),
|
||||
self.norm.z.clone(), other_a.norm.z.clone(), other_b.norm.z.clone());
|
||||
do mx.inverse().map |m| {
|
||||
Point3(m.mul_v(&Vec3::new(self.dist.clone(),
|
||||
other_a.dist.clone(),
|
||||
other_b.dist.clone())))
|
||||
Point::from_vec(
|
||||
m.mul_v(&Vec3::new(self.dist.clone(),
|
||||
other_a.dist.clone(),
|
||||
other_b.dist.clone()))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +191,7 @@ mod tests {
|
|||
let p1 = Plane::from_abcd(0.0, -1.0, 0.0, 2.0);
|
||||
let p2 = Plane::from_abcd(0.0, 0.0, 1.0, 1.0);
|
||||
|
||||
assert_eq!(p0.intersection_3pl(&p1, &p2).unwrap(), Point3::new(1.0, -2.0, 1.0));
|
||||
assert_eq!(p0.intersection_3pl(&p1, &p2), Some(Point3::new(1.0, -2.0, 1.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -13,31 +13,55 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::cast;
|
||||
|
||||
use core::{Vec2, Vec3};
|
||||
|
||||
/// A geometric point
|
||||
pub trait Point<T,V>: Eq + ApproxEq<T> + ToStr {
|
||||
pub fn from_vec(vec: V) -> Self;
|
||||
pub fn as_vec<'a>(&'a self) -> &'a V;
|
||||
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut V;
|
||||
|
||||
pub fn translate(&self, offset: &V) -> Self;
|
||||
pub fn distance(&self, other: &Self) -> T;
|
||||
}
|
||||
|
||||
/// A two-dimensional point
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct Point2<T>(Vec2<T>);
|
||||
pub struct Point2<T> { x: T, y: T }
|
||||
|
||||
impl<T> Point2<T> {
|
||||
#[inline]
|
||||
pub fn new(x: T, y: T) -> Point2<T> {
|
||||
Point2(Vec2::new(x, y))
|
||||
Point2 { x: x, y: y }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Point<T,Vec2<T>> for Point2<T> {
|
||||
pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> {
|
||||
Point2(self.add_v(offset))
|
||||
impl<T:Clone + Float> Point<T,Vec2<T>> for Point2<T> {
|
||||
#[inline]
|
||||
pub fn from_vec(vec: Vec2<T>) -> Point2<T> {
|
||||
unsafe { cast::transmute(vec) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_vec<'a>(&'a self) -> &'a Vec2<T> {
|
||||
unsafe { cast::transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec2<T> {
|
||||
unsafe { cast::transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> {
|
||||
Point::from_vec(self.as_vec().add_v(offset))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn distance(&self, other: &Point2<T>) -> T {
|
||||
(**self).distance(&**other)
|
||||
self.as_vec().distance(other.as_vec())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +78,8 @@ impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point2<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn approx_eq_eps(&self, other: &Point2<T>, epsilon: &T) -> bool {
|
||||
(**self).approx_eq_eps(&**other, epsilon)
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
self.y.approx_eq_eps(&other.y, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,21 +101,39 @@ mod test_point2 {
|
|||
|
||||
/// A three-dimensional point
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct Point3<T>(Vec3<T>);
|
||||
pub struct Point3<T> { x: T, y: T, z: T }
|
||||
|
||||
impl<T> Point3<T> {
|
||||
#[inline]
|
||||
pub fn new(x: T, y: T, z: T) -> Point3<T> {
|
||||
Point3(Vec3::new(x, y, z))
|
||||
Point3 { x: x, y: y, z: z }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Point<T,Vec3<T>> for Point3<T> {
|
||||
pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> {
|
||||
Point3(self.add_v(offset))
|
||||
impl<T:Clone + Float> Point<T,Vec3<T>> for Point3<T> {
|
||||
#[inline]
|
||||
pub fn from_vec(vec: Vec3<T>) -> Point3<T> {
|
||||
unsafe { cast::transmute(vec) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_vec<'a>(&'a self) -> &'a Vec3<T> {
|
||||
unsafe { cast::transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec3<T> {
|
||||
unsafe { cast::transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> {
|
||||
Point::from_vec(self.as_vec().add_v(offset))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn distance(&self, other: &Point3<T>) -> T {
|
||||
(**self).distance(&**other)
|
||||
self.as_vec().distance(other.as_vec())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +150,9 @@ impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point3<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn approx_eq_eps(&self, other: &Point3<T>, epsilon: &T) -> bool {
|
||||
(**self).approx_eq_eps(&**other, epsilon)
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
self.y.approx_eq_eps(&other.y, epsilon) &&
|
||||
self.z.approx_eq_eps(&other.z, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ pub struct FrustumPoints<T> {
|
|||
far_bottom_right: Point3<T>,
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Frustum<T> {
|
||||
impl<T:Clone + Float> Frustum<T> {
|
||||
/// Constructs a frustum
|
||||
pub fn from_planes(left: Plane<T>, right: Plane<T>,
|
||||
bottom: Plane<T>, top: Plane<T>,
|
||||
|
@ -80,7 +80,7 @@ impl<T:Clone + Real> Frustum<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Clone + Real + ApproxEq<T>> Frustum<T> {
|
||||
impl<T:Clone + Float> Frustum<T> {
|
||||
/// Computes where the frustum planes intersect to form corners and returns
|
||||
/// a struct containing the eight resulting position vectors.
|
||||
pub fn to_points(&self) -> FrustumPoints<T> {
|
||||
|
|
|
@ -28,7 +28,7 @@ mod num_macros;
|
|||
/// This is the equivalent of the gluPerspective function, the algorithm of which
|
||||
/// can be found [here](http://www.opengl.org/wiki/GluPerspective_code).
|
||||
///
|
||||
pub fn perspective<T:Clone + Real>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn perspective<T:Clone + Float>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
||||
let ymax = near * (fovy / two!(T)).to_radians().tan();
|
||||
let xmax = ymax * aspectRatio;
|
||||
|
||||
|
@ -41,7 +41,7 @@ pub fn perspective<T:Clone + Real>(fovy: T, aspectRatio: T, near: T, far: T) ->
|
|||
/// This is the equivalent of the now deprecated [glFrustrum]
|
||||
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
|
||||
///
|
||||
pub fn frustum<T:Clone + Real>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn frustum<T:Clone + Float>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
let c0r0 = (two!(T) * near) / (right - left);
|
||||
let c0r1 = zero!(T);
|
||||
let c0r2 = zero!(T);
|
||||
|
@ -74,7 +74,7 @@ pub fn frustum<T:Clone + Real>(left: T, right: T, bottom: T, top: T, near: T, fa
|
|||
/// This is the equivalent of the now deprecated [glOrtho]
|
||||
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
|
||||
///
|
||||
pub fn ortho<T:Clone + Real>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
pub fn ortho<T:Clone + Float>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
|
||||
let c0r0 = two!(T) / (right - left);
|
||||
let c0r1 = zero!(T);
|
||||
let c0r2 = zero!(T);
|
||||
|
@ -116,7 +116,7 @@ pub struct PerspectiveFOV<T> {
|
|||
far: T,
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> PerspectiveFOV<T> {
|
||||
impl<T:Clone + Float> PerspectiveFOV<T> {
|
||||
pub fn to_perspective(&self) -> Result<Perspective<T>, ~str> {
|
||||
do self.if_valid {
|
||||
let angle = self.fovy / two!(T);
|
||||
|
@ -135,7 +135,7 @@ impl<T:Clone + Real> PerspectiveFOV<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Projection<T> for PerspectiveFOV<T> {
|
||||
impl<T:Clone + Float> Projection<T> for PerspectiveFOV<T> {
|
||||
pub fn if_valid<U:Clone>(&self, f: &fn() -> U) -> Result<U, ~str> {
|
||||
let frac_pi_2: T = Real::frac_pi_2();
|
||||
cond! (
|
||||
|
@ -169,7 +169,7 @@ pub struct Perspective<T> {
|
|||
far: T,
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Projection<T> for Perspective<T> {
|
||||
impl<T:Clone + Float> Projection<T> for Perspective<T> {
|
||||
pub fn if_valid<U:Clone>(&self, f: &fn() -> U) -> Result<U, ~str> {
|
||||
cond! (
|
||||
(self.left > self.right) { Err(fmt!("`left` cannot be greater than `right`, found: left: %? right: %?", self.left, self.right)) }
|
||||
|
@ -275,7 +275,7 @@ pub struct Ortho<T> {
|
|||
far: T,
|
||||
}
|
||||
|
||||
impl<T:Clone + Real> Projection<T> for Ortho<T> {
|
||||
impl<T:Clone + Float> Projection<T> for Ortho<T> {
|
||||
pub fn if_valid<U:Clone>(&self, f: &fn() -> U) -> Result<U, ~str> {
|
||||
cond! (
|
||||
(self.left > self.right) { Err(fmt!("`left` cannot be greater than `right`, found: left: %? right: %?", self.left, self.right)) }
|
||||
|
|
Loading…
Reference in a new issue