2013-08-26 05:51:19 +00:00
|
|
|
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
2013-08-26 05:08:25 +00:00
|
|
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
//! Points are fixed positions in affine space with no length or direction. This
|
|
|
|
//! disinguishes them from vectors, which have a length and direction, but do
|
|
|
|
//! not have a fixed position.
|
|
|
|
|
2013-10-19 14:00:44 +00:00
|
|
|
use std::fmt;
|
2014-01-23 16:00:24 +00:00
|
|
|
use std::num::{one, zero};
|
2013-09-03 03:54:03 +00:00
|
|
|
|
|
|
|
use array::*;
|
|
|
|
use vector::*;
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-09-03 06:37:06 +00:00
|
|
|
/// A point in 2-dimensional space.
|
2014-02-24 06:33:31 +00:00
|
|
|
#[deriving(Eq, Clone, Hash)]
|
2013-10-14 11:48:45 +00:00
|
|
|
pub struct Point2<S> { x: S, y: S }
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-11-07 02:08:37 +00:00
|
|
|
/// A point in 3-dimensional space.
|
2014-02-24 06:33:31 +00:00
|
|
|
#[deriving(Eq, Clone, Hash)]
|
2013-10-14 11:48:45 +00:00
|
|
|
pub struct Point3<S> { x: S, y: S, z: S }
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-09-03 13:36:03 +00:00
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
impl<S: Num> Point2<S> {
|
2013-08-26 05:08:25 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn new(x: S, y: S) -> Point2<S> {
|
|
|
|
Point2 { x: x, y: y }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-03 03:54:03 +00:00
|
|
|
impl<S: Num> Point3<S> {
|
2013-08-26 05:08:25 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn new(x: S, y: S, z: S) -> Point3<S> {
|
|
|
|
Point3 { x: x, y: y, z: z }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-01 14:32:29 +00:00
|
|
|
impl<S: Clone + Num + Primitive> Point3<S> {
|
|
|
|
#[inline]
|
2013-11-09 01:15:51 +00:00
|
|
|
pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> {
|
|
|
|
let e = v.truncate().mul_s(one::<S>() / v.w);
|
2013-11-01 14:32:29 +00:00
|
|
|
Point3::new(e.x.clone(), e.y.clone(), e.z.clone()) //FIXME
|
|
|
|
}
|
2013-11-02 13:11:13 +00:00
|
|
|
|
2013-11-01 14:32:29 +00:00
|
|
|
#[inline]
|
2013-11-09 01:15:51 +00:00
|
|
|
pub fn to_homogeneous(&self) -> Vec4<S> {
|
2013-11-01 14:32:29 +00:00
|
|
|
Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), one())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-03 06:37:06 +00:00
|
|
|
/// Specifies the numeric operations for point types.
|
2013-09-03 03:54:03 +00:00
|
|
|
pub trait Point
|
|
|
|
<
|
2013-09-17 08:50:42 +00:00
|
|
|
S: Primitive,
|
2013-09-03 03:54:03 +00:00
|
|
|
V: Vector<S, Slice>,
|
|
|
|
Slice
|
|
|
|
>
|
|
|
|
: Array<S, Slice>
|
|
|
|
{
|
2014-01-25 15:54:54 +00:00
|
|
|
#[inline] fn origin() -> Self{ build(|_i| zero::<S>()) }
|
|
|
|
|
2013-11-02 13:11:13 +00:00
|
|
|
#[inline] fn from_vec(v: &V) -> Self { build(|i| v.i(i).clone()) }
|
|
|
|
#[inline] fn to_vec(&self) -> V { build(|i| self.i(i).clone()) }
|
|
|
|
|
2013-09-14 01:58:19 +00:00
|
|
|
#[inline] fn mul_s(&self, s: S) -> Self { build(|i| self.i(i).mul(&s)) }
|
|
|
|
#[inline] fn div_s(&self, s: S) -> Self { build(|i| self.i(i).div(&s)) }
|
|
|
|
#[inline] fn rem_s(&self, s: S) -> Self { build(|i| self.i(i).rem(&s)) }
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-09-14 01:58:19 +00:00
|
|
|
#[inline] fn add_v(&self, other: &V) -> Self { build(|i| self.i(i).add(other.i(i))) }
|
|
|
|
#[inline] fn sub_p(&self, other: &Self) -> V { build(|i| self.i(i).sub(other.i(i))) }
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-09-14 03:40:38 +00:00
|
|
|
#[inline] fn mul_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.mul(&s)) }
|
|
|
|
#[inline] fn div_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.div(&s)) }
|
|
|
|
#[inline] fn rem_self_s(&mut self, s: S) { self.each_mut(|_, x| *x = x.rem(&s)) }
|
2013-08-28 00:19:47 +00:00
|
|
|
|
2013-09-14 03:40:38 +00:00
|
|
|
#[inline] fn add_self_v(&mut self, other: &V) { self.each_mut(|i, x| *x = x.add(other.i(i))) }
|
2013-09-18 01:36:41 +00:00
|
|
|
|
|
|
|
/// This is a weird one, but its useful for plane calculations
|
|
|
|
#[inline]
|
|
|
|
fn dot(&self, v: &V) -> S {
|
|
|
|
build::<S, Slice, V>(|i| self.i(i).mul(v.i(i))).comp_add()
|
|
|
|
}
|
2013-09-03 03:54:03 +00:00
|
|
|
}
|
2013-08-26 05:08:25 +00:00
|
|
|
|
2013-09-07 09:51:01 +00:00
|
|
|
array!(impl<S> Point2<S> -> [S, ..2] _2)
|
|
|
|
array!(impl<S> Point3<S> -> [S, ..3] _3)
|
2013-08-28 00:19:47 +00:00
|
|
|
|
2013-09-27 10:22:33 +00:00
|
|
|
impl<S: Primitive> Point<S, Vec2<S>, [S, ..2]> for Point2<S> {}
|
|
|
|
impl<S: Primitive> Point<S, Vec3<S>, [S, ..3]> for Point3<S> {}
|
2013-09-03 07:33:33 +00:00
|
|
|
|
2014-02-03 04:44:15 +00:00
|
|
|
impl<S: fmt::Show> ToStr for Point2<S> {
|
2013-09-03 07:33:33 +00:00
|
|
|
fn to_str(&self) -> ~str {
|
2013-10-19 14:00:44 +00:00
|
|
|
format!("[{}, {}]", self.x, self.y)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-03 04:44:15 +00:00
|
|
|
impl<S: fmt::Show> ToStr for Point3<S> {
|
2013-09-03 07:33:33 +00:00
|
|
|
fn to_str(&self) -> ~str {
|
2013-10-19 14:00:44 +00:00
|
|
|
format!("[{}, {}, {}]", self.x, self.y, self.z)
|
2013-09-03 07:33:33 +00:00
|
|
|
}
|
|
|
|
}
|