commit
7916a14f70
20 changed files with 164 additions and 159 deletions
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "cgmath"
|
name = "cgmath"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
authors = ["Brendan Zabarauskas <bjzaba@yahoo.com.au>",
|
authors = ["Brendan Zabarauskas <bjzaba@yahoo.com.au>",
|
||||||
"Brian Heylin",
|
"Brian Heylin",
|
||||||
"Colin Sherratt",
|
"Colin Sherratt",
|
||||||
|
@ -24,4 +24,5 @@ name = "cgmath"
|
||||||
rustc_serialize = "*"
|
rustc_serialize = "*"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
num = "*"
|
||||||
rand = "*"
|
rand = "*"
|
||||||
|
|
|
@ -20,15 +20,18 @@
|
||||||
//! dimension) where the slope of every line is either 0 or undefined. These
|
//! dimension) where the slope of every line is either 0 or undefined. These
|
||||||
//! are useful for very cheap collision detection.
|
//! are useful for very cheap collision detection.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use rust_num::{Float, zero, one};
|
||||||
|
|
||||||
use bound::*;
|
use bound::*;
|
||||||
use point::{Point, Point2, Point3};
|
use point::{Point, Point2, Point3};
|
||||||
use vector::{Vector, Vector2, Vector3};
|
use vector::{Vector, Vector2, Vector3};
|
||||||
use ray::{Ray2};
|
use ray::{Ray2};
|
||||||
use intersect::Intersect;
|
use intersect::Intersect;
|
||||||
use num::{zero, one, BaseNum, BaseFloat};
|
use num::{BaseNum, BaseFloat};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
use std::fmt;
|
|
||||||
use std::num::Float;
|
|
||||||
|
|
||||||
pub trait Aabb<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
|
pub trait Aabb<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
|
||||||
/// Create a new AABB using two points as opposing corners.
|
/// Create a new AABB using two points as opposing corners.
|
||||||
|
|
30
src/angle.rs
30
src/angle.rs
|
@ -17,14 +17,16 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::num::{cast, Float};
|
use std::num::cast;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use rand::distributions::range::SampleRange;
|
use rand::distributions::range::SampleRange;
|
||||||
|
|
||||||
|
use rust_num::{Float, One, Zero, one, zero};
|
||||||
|
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use num::{BaseFloat, One, one, Zero, zero};
|
use num::BaseFloat;
|
||||||
|
|
||||||
/// An angle, in radians
|
/// An angle, in radians
|
||||||
#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, RustcEncodable, RustcDecodable)]
|
#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, RustcEncodable, RustcDecodable)]
|
||||||
|
@ -50,11 +52,27 @@ pub trait ToDeg<S: BaseFloat> {
|
||||||
fn to_deg(&self) -> Deg<S>;
|
fn to_deg(&self) -> Deg<S>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
|
impl<S: BaseFloat> ToRad<S> for Rad<S> {
|
||||||
impl<S: BaseFloat> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }
|
#[inline]
|
||||||
|
fn to_rad(&self) -> Rad<S> { self.clone() }
|
||||||
|
}
|
||||||
|
impl<S: BaseFloat> ToRad<S> for Deg<S> {
|
||||||
|
#[inline]
|
||||||
|
fn to_rad(&self) -> Rad<S> {
|
||||||
|
rad(self.s * cast(f64::consts::PI / 180.0).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
|
impl<S: BaseFloat> ToDeg<S> for Rad<S> {
|
||||||
impl<S: BaseFloat> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
|
#[inline]
|
||||||
|
fn to_deg(&self) -> Deg<S> {
|
||||||
|
deg(self.s * cast(180.0 / f64::consts::PI).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<S: BaseFloat> ToDeg<S> for Deg<S> {
|
||||||
|
#[inline]
|
||||||
|
fn to_deg(&self) -> Deg<S> { self.clone() }
|
||||||
|
}
|
||||||
|
|
||||||
/// Private utility functions for converting to/from scalars
|
/// Private utility functions for converting to/from scalars
|
||||||
trait ScalarConv<S> {
|
trait ScalarConv<S> {
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::num;
|
use std::num::{NumCast, cast};
|
||||||
use std::num::Float;
|
use rust_num::Float;
|
||||||
|
|
||||||
pub trait ApproxEq<T: Float>: Sized {
|
pub trait ApproxEq<T: NumCast + Float>: Sized {
|
||||||
fn approx_epsilon(_hack: Option<Self>) -> T {
|
fn approx_epsilon(_hack: Option<Self>) -> T {
|
||||||
num::cast(1.0e-5f64).unwrap()
|
cast(1.0e-5f64).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn approx_eq(&self, other: &Self) -> bool {
|
fn approx_eq(&self, other: &Self) -> bool {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![crate_type = "dylib"]
|
#![crate_type = "dylib"]
|
||||||
#![feature(plugin, core, std_misc, custom_derive)]
|
#![feature(plugin, core, custom_derive)]
|
||||||
|
|
||||||
//! Computer graphics-centric math.
|
//! Computer graphics-centric math.
|
||||||
//!
|
//!
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
|
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
|
||||||
//! These are provided for convenience.
|
//! These are provided for convenience.
|
||||||
|
|
||||||
|
extern crate num as rust_num;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
|
@ -62,6 +63,8 @@ pub use sphere::Sphere;
|
||||||
pub use approx::ApproxEq;
|
pub use approx::ApproxEq;
|
||||||
pub use num::*;
|
pub use num::*;
|
||||||
|
|
||||||
|
pub use rust_num::{One, Zero, one, zero};
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
|
|
||||||
mod array;
|
mod array;
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
//! Line segments
|
//! Line segments
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use num::{BaseNum, BaseFloat, Zero, zero, One, one};
|
|
||||||
|
use rust_num::{Zero, zero, One, one};
|
||||||
|
|
||||||
|
use num::{BaseNum, BaseFloat};
|
||||||
use point::{Point, Point2, Point3};
|
use point::{Point, Point2, Point3};
|
||||||
use vector::{Vector, Vector2, Vector3};
|
use vector::{Vector, Vector2, Vector3};
|
||||||
use ray::{Ray2};
|
use ray::{Ray2};
|
||||||
|
|
123
src/matrix.rs
123
src/matrix.rs
|
@ -22,10 +22,12 @@ use std::ops::*;
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
use rust_num::{Zero, zero, One, one};
|
||||||
|
|
||||||
use angle::{Rad, sin, cos, sin_cos};
|
use angle::{Rad, sin, cos, sin_cos};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::{Array1, Array2, FixedArray};
|
use array::{Array1, Array2, FixedArray};
|
||||||
use num::{BaseFloat, BaseNum, Zero, zero, One, one};
|
use num::{BaseFloat, BaseNum};
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use quaternion::{Quaternion, ToQuaternion};
|
use quaternion::{Quaternion, ToQuaternion};
|
||||||
use vector::{Vector, EuclideanVector};
|
use vector::{Vector, EuclideanVector};
|
||||||
|
@ -44,7 +46,7 @@ pub struct Matrix3<S> { pub x: Vector3<S>, pub y: Vector3<S>, pub z: Vector3<S>
|
||||||
pub struct Matrix4<S> { pub x: Vector4<S>, pub y: Vector4<S>, pub z: Vector4<S>, pub w: Vector4<S> }
|
pub struct Matrix4<S> { pub x: Vector4<S>, pub y: Vector4<S>, pub z: Vector4<S>, pub w: Vector4<S> }
|
||||||
|
|
||||||
|
|
||||||
impl<S: BaseNum> Matrix2<S> {
|
impl<S> Matrix2<S> {
|
||||||
/// Create a new matrix, providing values for each index.
|
/// Create a new matrix, providing values for each index.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(c0r0: S, c0r1: S,
|
pub fn new(c0r0: S, c0r1: S,
|
||||||
|
@ -58,7 +60,9 @@ impl<S: BaseNum> Matrix2<S> {
|
||||||
pub fn from_cols(c0: Vector2<S>, c1: Vector2<S>) -> Matrix2<S> {
|
pub fn from_cols(c0: Vector2<S>, c1: Vector2<S>) -> Matrix2<S> {
|
||||||
Matrix2 { x: c0, y: c1 }
|
Matrix2 { x: c0, y: c1 }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: BaseNum> Matrix2<S> {
|
||||||
/// Create a new diagonal matrix, providing a single value to use for each
|
/// Create a new diagonal matrix, providing a single value to use for each
|
||||||
/// non-zero index.
|
/// non-zero index.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -80,7 +84,7 @@ impl<S: BaseNum> Matrix2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Matrix2<S> {
|
impl<S: BaseFloat> Matrix2<S> {
|
||||||
/// Create a transformation matrix that will cause a vector to point at
|
/// Create a transformation matrix that will cause a vector to point at
|
||||||
/// `dir`, using `up` for orientation.
|
/// `dir`, using `up` for orientation.
|
||||||
pub fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Matrix2<S> {
|
pub fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Matrix2<S> {
|
||||||
|
@ -98,7 +102,16 @@ impl<S: BaseFloat + 'static> Matrix2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Matrix3<S> {
|
impl<S: Copy + Neg<Output = S>> Matrix2<S> {
|
||||||
|
/// Negate this `Matrix2` in-place.
|
||||||
|
#[inline]
|
||||||
|
pub fn neg_self(&mut self) {
|
||||||
|
(&mut self[0]).neg_self();
|
||||||
|
(&mut self[1]).neg_self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Matrix3<S> {
|
||||||
/// Create a new matrix, providing values for each index.
|
/// Create a new matrix, providing values for each index.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(c0r0:S, c0r1:S, c0r2:S,
|
pub fn new(c0r0:S, c0r1:S, c0r2:S,
|
||||||
|
@ -114,7 +127,9 @@ impl<S: BaseNum> Matrix3<S> {
|
||||||
pub fn from_cols(c0: Vector3<S>, c1: Vector3<S>, c2: Vector3<S>) -> Matrix3<S> {
|
pub fn from_cols(c0: Vector3<S>, c1: Vector3<S>, c2: Vector3<S>) -> Matrix3<S> {
|
||||||
Matrix3 { x: c0, y: c1, z: c2 }
|
Matrix3 { x: c0, y: c1, z: c2 }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: BaseNum> Matrix3<S> {
|
||||||
/// Create a new diagonal matrix, providing a single value to use for each
|
/// Create a new diagonal matrix, providing a single value to use for each
|
||||||
/// non-zero index.
|
/// non-zero index.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -137,8 +152,7 @@ impl<S: BaseNum> Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static>
|
impl<S: BaseFloat> Matrix3<S> {
|
||||||
Matrix3<S> {
|
|
||||||
/// Create a transformation matrix that will cause a vector to point at
|
/// Create a transformation matrix that will cause a vector to point at
|
||||||
/// `dir`, using `up` for orientation.
|
/// `dir`, using `up` for orientation.
|
||||||
pub fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Matrix3<S> {
|
pub fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Matrix3<S> {
|
||||||
|
@ -220,7 +234,17 @@ Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Matrix4<S> {
|
impl<S: Copy + Neg<Output = S>> Matrix3<S> {
|
||||||
|
/// Negate this `Matrix3` in-place.
|
||||||
|
#[inline]
|
||||||
|
pub fn neg_self(&mut self) {
|
||||||
|
(&mut self[0]).neg_self();
|
||||||
|
(&mut self[1]).neg_self();
|
||||||
|
(&mut self[2]).neg_self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Matrix4<S> {
|
||||||
/// Create a new matrix, providing values for each index.
|
/// Create a new matrix, providing values for each index.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S,
|
pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S,
|
||||||
|
@ -238,7 +262,9 @@ impl<S: BaseNum> Matrix4<S> {
|
||||||
pub fn from_cols(c0: Vector4<S>, c1: Vector4<S>, c2: Vector4<S>, c3: Vector4<S>) -> Matrix4<S> {
|
pub fn from_cols(c0: Vector4<S>, c1: Vector4<S>, c2: Vector4<S>, c3: Vector4<S>) -> Matrix4<S> {
|
||||||
Matrix4 { x: c0, y: c1, z: c2, w: c3 }
|
Matrix4 { x: c0, y: c1, z: c2, w: c3 }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: BaseNum> Matrix4<S> {
|
||||||
/// Create a new diagonal matrix, providing a single value to use for each
|
/// Create a new diagonal matrix, providing a single value to use for each
|
||||||
/// non-zero index.
|
/// non-zero index.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -271,8 +297,7 @@ impl<S: BaseNum> Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat>
|
impl<S: BaseFloat> Matrix4<S> {
|
||||||
Matrix4<S> {
|
|
||||||
/// Create a transformation matrix that will cause a vector to point at
|
/// Create a transformation matrix that will cause a vector to point at
|
||||||
/// `dir`, using `up` for orientation.
|
/// `dir`, using `up` for orientation.
|
||||||
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> Matrix4<S> {
|
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> Matrix4<S> {
|
||||||
|
@ -287,8 +312,18 @@ Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Copy + Neg<Output = S>> Matrix4<S> {
|
||||||
|
/// Negate this `Matrix4` in-place.
|
||||||
|
#[inline]
|
||||||
|
pub fn neg_self(&mut self) {
|
||||||
|
(&mut self[0]).neg_self();
|
||||||
|
(&mut self[1]).neg_self();
|
||||||
|
(&mut self[2]).neg_self();
|
||||||
|
(&mut self[3]).neg_self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Matrix<S: BaseFloat, V: Clone + Vector<S>>: Array2<V, V, S>
|
pub trait Matrix<S: BaseFloat, V: Clone + Vector<S>>: Array2<V, V, S>
|
||||||
+ Neg
|
|
||||||
+ Zero + One
|
+ Zero + One
|
||||||
+ ApproxEq<S>
|
+ ApproxEq<S>
|
||||||
+ Sized {
|
+ Sized {
|
||||||
|
@ -317,9 +352,6 @@ pub trait Matrix<S: BaseFloat, V: Clone + Vector<S>>: Array2<V, V, S>
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn mul_m(&self, m: &Self) -> Self;
|
fn mul_m(&self, m: &Self) -> Self;
|
||||||
|
|
||||||
/// Negate this matrix in-place (multiply by scalar -1).
|
|
||||||
fn neg_self(&mut self);
|
|
||||||
|
|
||||||
/// Multiply this matrix by a scalar, in-place.
|
/// Multiply this matrix by a scalar, in-place.
|
||||||
fn mul_self_s(&mut self, s: S);
|
fn mul_self_s(&mut self, s: S);
|
||||||
/// Divide this matrix by a scalar, in-place.
|
/// Divide this matrix by a scalar, in-place.
|
||||||
|
@ -381,67 +413,73 @@ pub trait Matrix<S: BaseFloat, V: Clone + Vector<S>>: Array2<V, V, S>
|
||||||
fn is_symmetric(&self) -> bool;
|
fn is_symmetric(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Add for Matrix2<S> {
|
impl<S: BaseFloat> Add for Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, other: Matrix2<S>) -> Matrix2<S> { self.add_m(&other) }
|
fn add(self, other: Matrix2<S>) -> Matrix2<S> { self.add_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Add for Matrix3<S> {
|
impl<S: BaseFloat> Add for Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, other: Matrix3<S>) -> Matrix3<S> { self.add_m(&other) }
|
fn add(self, other: Matrix3<S>) -> Matrix3<S> { self.add_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Add for Matrix4<S> {
|
impl<S: BaseFloat> Add for Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, other: Matrix4<S>) -> Matrix4<S> { self.add_m(&other) }
|
fn add(self, other: Matrix4<S>) -> Matrix4<S> { self.add_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Sub for Matrix2<S> {
|
impl<S: BaseFloat> Sub for Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, other: Matrix2<S>) -> Matrix2<S> { self.sub_m(&other) }
|
fn sub(self, other: Matrix2<S>) -> Matrix2<S> { self.sub_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Sub for Matrix3<S> {
|
impl<S: BaseFloat> Sub for Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, other: Matrix3<S>) -> Matrix3<S> { self.sub_m(&other) }
|
fn sub(self, other: Matrix3<S>) -> Matrix3<S> { self.sub_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Sub for Matrix4<S> {
|
impl<S: BaseFloat> Sub for Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, other: Matrix4<S>) -> Matrix4<S> { self.sub_m(&other) }
|
fn sub(self, other: Matrix4<S>) -> Matrix4<S> { self.sub_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Neg for Matrix2<S> {
|
impl<S: Neg<Output = S>> Neg for Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(self) -> Matrix2<S> { Matrix2::from_cols(self[0].neg(), self[1].neg()) }
|
fn neg(self) -> Matrix2<S> {
|
||||||
|
Matrix2::from_cols(self.x.neg(), self.y.neg())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Neg for Matrix3<S> {
|
impl<S: Neg<Output = S>> Neg for Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(self) -> Matrix3<S> { Matrix3::from_cols(self[0].neg(), self[1].neg(), self[2].neg()) }
|
fn neg(self) -> Matrix3<S> {
|
||||||
|
Matrix3::from_cols(self.x.neg(), self.y.neg(), self.z.neg())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Neg for Matrix4<S> {
|
impl<S: Neg<Output = S>> Neg for Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(self) -> Matrix4<S> { Matrix4::from_cols(self[0].neg(), self[1].neg(), self[2].neg(), self[3].neg()) }
|
fn neg(self) -> Matrix4<S> {
|
||||||
|
Matrix4::from_cols(self.x.neg(), self.y.neg(), self.z.neg(), self.w.neg())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Zero for Matrix2<S> {
|
impl<S: BaseFloat> Zero for Matrix2<S> {
|
||||||
|
@ -465,21 +503,21 @@ impl<S: BaseFloat> Zero for Matrix4<S> {
|
||||||
fn is_zero(&self) -> bool{ *self == zero() }
|
fn is_zero(&self) -> bool{ *self == zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Mul for Matrix2<S> {
|
impl<S: BaseFloat> Mul for Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, other: Matrix2<S>) -> Matrix2<S> { self.mul_m(&other) }
|
fn mul(self, other: Matrix2<S>) -> Matrix2<S> { self.mul_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Mul for Matrix3<S> {
|
impl<S: BaseFloat> Mul for Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, other: Matrix3<S>) -> Matrix3<S> { self.mul_m(&other) }
|
fn mul(self, other: Matrix3<S>) -> Matrix3<S> { self.mul_m(&other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Mul for Matrix4<S> {
|
impl<S: BaseFloat> Mul for Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -753,7 +791,7 @@ impl<S: Copy + 'static> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Matrix<S, Vector2<S>> for Matrix2<S> {
|
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_s(&self, s: S) -> Matrix2<S> {
|
fn mul_s(&self, s: S) -> Matrix2<S> {
|
||||||
Matrix2::from_cols(self[0].mul_s(s),
|
Matrix2::from_cols(self[0].mul_s(s),
|
||||||
|
@ -795,12 +833,6 @@ impl<S: BaseFloat + 'static> Matrix<S, Vector2<S>> for Matrix2<S> {
|
||||||
self.row(0).dot(&other[1]), self.row(1).dot(&other[1]))
|
self.row(0).dot(&other[1]), self.row(1).dot(&other[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn neg_self(&mut self) {
|
|
||||||
(&mut self[0]).neg_self();
|
|
||||||
(&mut self[1]).neg_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn mul_self_s(&mut self, s: S) {
|
||||||
(&mut self[0]).mul_self_s(s);
|
(&mut self[0]).mul_self_s(s);
|
||||||
|
@ -877,7 +909,7 @@ impl<S: BaseFloat + 'static> Matrix<S, Vector2<S>> for Matrix2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Matrix<S, Vector3<S>> for Matrix3<S> {
|
impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_s(&self, s: S) -> Matrix3<S> {
|
fn mul_s(&self, s: S) -> Matrix3<S> {
|
||||||
Matrix3::from_cols(self[0].mul_s(s),
|
Matrix3::from_cols(self[0].mul_s(s),
|
||||||
|
@ -926,13 +958,6 @@ impl<S: BaseFloat + 'static> Matrix<S, Vector3<S>> for Matrix3<S> {
|
||||||
self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2]))
|
self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2]))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn neg_self(&mut self) {
|
|
||||||
(&mut self[0]).neg_self();
|
|
||||||
(&mut self[1]).neg_self();
|
|
||||||
(&mut self[2]).neg_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn mul_self_s(&mut self, s: S) {
|
||||||
(&mut self[0]).mul_self_s(s);
|
(&mut self[0]).mul_self_s(s);
|
||||||
|
@ -1038,7 +1063,7 @@ macro_rules! dot_matrix4(
|
||||||
($A[3][$I]) * ($B[$J][3])
|
($A[3][$I]) * ($B[$J][3])
|
||||||
));
|
));
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> Matrix<S, Vector4<S>> for Matrix4<S> {
|
impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_s(&self, s: S) -> Matrix4<S> {
|
fn mul_s(&self, s: S) -> Matrix4<S> {
|
||||||
Matrix4::from_cols(self[0].mul_s(s),
|
Matrix4::from_cols(self[0].mul_s(s),
|
||||||
|
@ -1094,14 +1119,6 @@ impl<S: BaseFloat + 'static> Matrix<S, Vector4<S>> for Matrix4<S> {
|
||||||
dot_matrix4!(self, other, 0, 3), dot_matrix4!(self, other, 1, 3), dot_matrix4!(self, other, 2, 3), dot_matrix4!(self, other, 3, 3))
|
dot_matrix4!(self, other, 0, 3), dot_matrix4!(self, other, 1, 3), dot_matrix4!(self, other, 2, 3), dot_matrix4!(self, other, 3, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn neg_self(&mut self) {
|
|
||||||
(&mut self[0]).neg_self();
|
|
||||||
(&mut self[1]).neg_self();
|
|
||||||
(&mut self[2]).neg_self();
|
|
||||||
(&mut self[3]).neg_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn mul_self_s(&mut self, s: S) {
|
||||||
(&mut self[0]).mul_self_s(s);
|
(&mut self[0]).mul_self_s(s);
|
||||||
|
@ -1338,7 +1355,7 @@ impl<S: BaseFloat> ToMatrix4<S> for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat + 'static> ToQuaternion<S> for Matrix3<S> {
|
impl<S: BaseFloat> ToQuaternion<S> for Matrix3<S> {
|
||||||
/// Convert the matrix to a quaternion
|
/// Convert the matrix to a quaternion
|
||||||
fn to_quaternion(&self) -> Quaternion<S> {
|
fn to_quaternion(&self) -> Quaternion<S> {
|
||||||
// http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
|
// http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
|
||||||
|
|
61
src/num.rs
61
src/num.rs
|
@ -17,8 +17,9 @@ use approx::ApproxEq;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::{Float, Int, NumCast};
|
use std::num::NumCast;
|
||||||
use std::ops::*;
|
|
||||||
|
use rust_num::{Float, Num};
|
||||||
|
|
||||||
/// A trait providing a [partial ordering](http://mathworld.wolfram.com/PartialOrder.html).
|
/// A trait providing a [partial ordering](http://mathworld.wolfram.com/PartialOrder.html).
|
||||||
pub trait PartialOrd {
|
pub trait PartialOrd {
|
||||||
|
@ -58,43 +59,18 @@ macro_rules! partial_ord_float (
|
||||||
partial_ord_float!(f32);
|
partial_ord_float!(f32);
|
||||||
partial_ord_float!(f64);
|
partial_ord_float!(f64);
|
||||||
|
|
||||||
/// Additive neutral element
|
|
||||||
pub trait Zero {
|
|
||||||
fn zero() -> Self;
|
|
||||||
fn is_zero(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Multiplicative neutral element
|
|
||||||
pub trait One {
|
|
||||||
fn one() -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Base numeric types with partial ordering
|
/// Base numeric types with partial ordering
|
||||||
pub trait BaseNum:
|
pub trait BaseNum:
|
||||||
Copy + NumCast + Clone + Add<Output=Self> + Sub<Output=Self> +
|
Copy + NumCast + Clone + Num
|
||||||
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> + Neg<Output=Self> + PartialEq
|
+ PartialOrd + cmp::PartialOrd + fmt::Debug
|
||||||
+ PartialOrd + cmp::PartialOrd + fmt::Debug + Zero + One
|
+ 'static
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! impl_basenum_int (
|
macro_rules! impl_basenum_int (
|
||||||
($T: ident) => (
|
($T: ident) => (
|
||||||
impl BaseNum for $T {}
|
impl BaseNum for $T {}
|
||||||
impl Zero for $T {
|
|
||||||
fn zero() -> $T {
|
|
||||||
Int::zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
*self == Int::zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl One for $T {
|
|
||||||
fn one() -> $T {
|
|
||||||
Int::one()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -113,38 +89,15 @@ impl_basenum_int!(usize);
|
||||||
macro_rules! impl_basenum_float (
|
macro_rules! impl_basenum_float (
|
||||||
($T: ident) => (
|
($T: ident) => (
|
||||||
impl BaseNum for $T {}
|
impl BaseNum for $T {}
|
||||||
impl Zero for $T {
|
|
||||||
fn zero() -> $T {
|
|
||||||
Float::zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
*self == Float::zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl One for $T {
|
|
||||||
fn one() -> $T {
|
|
||||||
Float::one()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_basenum_float!(f32);
|
impl_basenum_float!(f32);
|
||||||
impl_basenum_float!(f64);
|
impl_basenum_float!(f64);
|
||||||
|
|
||||||
pub fn zero<T: Zero>() -> T {
|
|
||||||
Zero::zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn one<T: One>() -> T {
|
|
||||||
One::one()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Base integer types
|
/// Base integer types
|
||||||
pub trait BaseInt : BaseNum + Int {}
|
pub trait BaseInt : BaseNum {}
|
||||||
|
|
||||||
impl BaseInt for i8 {}
|
impl BaseInt for i8 {}
|
||||||
impl BaseInt for i16 {}
|
impl BaseInt for i16 {}
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use rust_num::{one, Zero, zero};
|
||||||
|
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use intersect::Intersect;
|
use intersect::Intersect;
|
||||||
use num::{BaseFloat, one, Zero, zero};
|
use num::{BaseFloat};
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use ray::Ray3;
|
use ray::Ray3;
|
||||||
use vector::{Vector3, Vector4};
|
use vector::{Vector3, Vector4};
|
||||||
|
|
|
@ -21,11 +21,13 @@ use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
|
use rust_num::{one, zero};
|
||||||
|
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::{Array1, FixedArray};
|
use array::{Array1, FixedArray};
|
||||||
use bound::*;
|
use bound::*;
|
||||||
use matrix::{Matrix, Matrix4};
|
use matrix::{Matrix, Matrix4};
|
||||||
use num::{BaseNum, BaseFloat, one, zero};
|
use num::{BaseNum, BaseFloat};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
use vector::*;
|
use vector::*;
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
|
|
||||||
use std::num::cast;
|
use std::num::cast;
|
||||||
|
|
||||||
|
use rust_num::{zero, one};
|
||||||
|
|
||||||
use angle::{Angle, tan, cot};
|
use angle::{Angle, tan, cot};
|
||||||
use frustum::Frustum;
|
use frustum::Frustum;
|
||||||
use matrix::{Matrix4, ToMatrix4};
|
use matrix::{Matrix4, ToMatrix4};
|
||||||
use num::{BaseFloat, zero, one};
|
use num::BaseFloat;
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
|
|
||||||
/// Create a perspective projection matrix.
|
/// Create a perspective projection matrix.
|
||||||
|
|
|
@ -13,19 +13,20 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::f64;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::f64;
|
use std::num::cast;
|
||||||
use std::num::{cast, Float};
|
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
use rust_num::{Float, one, zero};
|
||||||
|
|
||||||
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::Array1;
|
use array::Array1;
|
||||||
use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4};
|
use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4};
|
||||||
use num::{BaseFloat, one, zero};
|
use num::BaseFloat;
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
|
use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
|
||||||
use vector::{Vector3, Vector, EuclideanVector};
|
use vector::{Vector3, Vector, EuclideanVector};
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
|
|
||||||
//! Bounding sphere
|
//! Bounding sphere
|
||||||
|
|
||||||
|
use rust_num::zero;
|
||||||
|
|
||||||
use bound::*;
|
use bound::*;
|
||||||
use intersect::Intersect;
|
use intersect::Intersect;
|
||||||
use num::{BaseFloat, zero};
|
use num::BaseFloat;
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
use ray::Ray3;
|
use ray::Ray3;
|
||||||
|
|
|
@ -15,19 +15,20 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use rust_num::{zero, one};
|
||||||
|
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use matrix::*;
|
use matrix::*;
|
||||||
use num::*;
|
use num::*;
|
||||||
use point::*;
|
use point::*;
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use rotation::*;
|
use rotation::*;
|
||||||
use std::marker::PhantomFn;
|
|
||||||
use vector::*;
|
use vector::*;
|
||||||
|
|
||||||
/// A trait representing an [affine
|
/// A trait representing an [affine
|
||||||
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
|
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
|
||||||
/// can be applied to points or vectors. An affine transformation is one which
|
/// can be applied to points or vectors. An affine transformation is one which
|
||||||
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized + PhantomFn<S> {
|
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
|
||||||
/// Create an identity transformation. That is, a transformation which
|
/// Create an identity transformation. That is, a transformation which
|
||||||
/// does nothing.
|
/// does nothing.
|
||||||
fn identity() -> Self;
|
fn identity() -> Self;
|
||||||
|
@ -236,7 +237,7 @@ impl<S: BaseFloat + 'static> Transform3<S> for AffineMatrix3<S> {}
|
||||||
|
|
||||||
/// A trait that allows extracting components (rotation, translation, scale)
|
/// A trait that allows extracting components (rotation, translation, scale)
|
||||||
/// from an arbitrary transformations
|
/// from an arbitrary transformations
|
||||||
pub trait ToComponents<S, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>>: PhantomFn<(S, P)> {
|
pub trait ToComponents<S, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>> {
|
||||||
/// Extract the (scale, rotation, translation) triple
|
/// Extract the (scale, rotation, translation) triple
|
||||||
fn decompose(&self) -> (V, R, V);
|
fn decompose(&self) -> (V, R, V);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +261,8 @@ impl<
|
||||||
R: Rotation<S, V, P> + Clone,
|
R: Rotation<S, V, P> + Clone,
|
||||||
> ToComponents<S, V, P, R> for Decomposed<S, V, R> {
|
> ToComponents<S, V, P, R> for Decomposed<S, V, R> {
|
||||||
fn decompose(&self) -> (V, R, V) {
|
fn decompose(&self) -> (V, R, V) {
|
||||||
(Vector::from_value(self.scale), self.rot.clone(), self.disp.clone())
|
let v: V = one();
|
||||||
|
(v.mul_s(self.scale), self.rot.clone(), self.disp.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
//!
|
//!
|
||||||
//! assert_eq!(Vector2::new(1.0f64, 0.0f64), Vector2::unit_x());
|
//! assert_eq!(Vector2::new(1.0f64, 0.0f64), Vector2::unit_x());
|
||||||
//! assert_eq!(vec3(0.0f64, 0.0f64, 0.0f64), zero());
|
//! assert_eq!(vec3(0.0f64, 0.0f64, 0.0f64), zero());
|
||||||
//! assert_eq!(Vector::from_value(1.0f64), vec2(1.0, 1.0));
|
//! assert_eq!(Vector2::from_value(1.0f64), vec2(1.0, 1.0));
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Vectors can be manipulated with typical mathematical operations (addition,
|
//! Vectors can be manipulated with typical mathematical operations (addition,
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
//!
|
//!
|
||||||
//! // Scalar multiplication can return a new object, or be done in place
|
//! // Scalar multiplication can return a new object, or be done in place
|
||||||
//! // to avoid an allocation:
|
//! // to avoid an allocation:
|
||||||
//! let mut c: Vector4<f64> = Vector::from_value(3.0);
|
//! let mut c = Vector4::from_value(3f64);
|
||||||
//! let d: Vector4<f64> = c.mul_s(2.0);
|
//! let d: Vector4<f64> = c.mul_s(2.0);
|
||||||
//! c.mul_self_s(2.0);
|
//! c.mul_self_s(2.0);
|
||||||
//! assert_eq!(c, d);
|
//! assert_eq!(c, d);
|
||||||
|
@ -103,15 +103,17 @@ use std::ops::*;
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
use rust_num::{Zero, One, zero, one};
|
||||||
|
|
||||||
use angle::{Rad, atan2, acos};
|
use angle::{Rad, atan2, acos};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::{Array1, FixedArray};
|
use array::{Array1, FixedArray};
|
||||||
use num::{BaseNum, BaseFloat, Zero, One, zero, one};
|
use num::{BaseNum, BaseFloat};
|
||||||
|
|
||||||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
/// A trait that specifies a range of numeric operations for vectors. Not all
|
||||||
/// of these make sense from a linear algebra point of view, but are included
|
/// of these make sense from a linear algebra point of view, but are included
|
||||||
/// for pragmatic reasons.
|
/// for pragmatic reasons.
|
||||||
pub trait Vector<S: BaseNum>: Array1<S> + Zero + One + Neg<Output=Self> {
|
pub trait Vector<S: BaseNum>: Array1<S> + Zero + One {
|
||||||
/// Construct a vector from a single value, replicating it.
|
/// Construct a vector from a single value, replicating it.
|
||||||
fn from_value(s: S) -> Self;
|
fn from_value(s: S) -> Self;
|
||||||
/// Add a scalar to this vector, returning a new vector.
|
/// Add a scalar to this vector, returning a new vector.
|
||||||
|
@ -146,9 +148,6 @@ pub trait Vector<S: BaseNum>: Array1<S> + Zero + One + Neg<Output=Self> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn rem_v(&self, v: &Self) -> Self;
|
fn rem_v(&self, v: &Self) -> Self;
|
||||||
|
|
||||||
/// Negate this vector in-place.
|
|
||||||
fn neg_self(&mut self);
|
|
||||||
|
|
||||||
/// Add a scalar to this vector in-place.
|
/// Add a scalar to this vector in-place.
|
||||||
fn add_self_s(&mut self, s: S);
|
fn add_self_s(&mut self, s: S);
|
||||||
/// Subtract a scalar from this vector, in-place.
|
/// Subtract a scalar from this vector, in-place.
|
||||||
|
@ -203,13 +202,21 @@ macro_rules! vec(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<$S: Copy + Neg<Output = $S>> $Self_<$S> {
|
||||||
|
/// Negate this vector in-place (multiply by -1).
|
||||||
|
#[inline]
|
||||||
|
pub fn neg_self(&mut self) {
|
||||||
|
$(self.$field = -self.$field);+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The short constructor.
|
/// The short constructor.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $constructor<S>($($field: S),+) -> $Self_<S> {
|
pub fn $constructor<S>($($field: S),+) -> $Self_<S> {
|
||||||
$Self_::new($($field),+)
|
$Self_::new($($field),+)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$S: Zero> Zero for $Self_<$S> {
|
impl<$S: Zero + BaseNum> Zero for $Self_<$S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero() -> $Self_<S> { $Self_ { $($field: zero()),+ } }
|
fn zero() -> $Self_<S> { $Self_ { $($field: zero()),+ } }
|
||||||
|
|
||||||
|
@ -217,7 +224,7 @@ macro_rules! vec(
|
||||||
fn is_zero(&self) -> bool { $((self.$field.is_zero()) )&&+ }
|
fn is_zero(&self) -> bool { $((self.$field.is_zero()) )&&+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$S: One> One for $Self_<$S> {
|
impl<$S: One + BaseNum> One for $Self_<$S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> $Self_<$S> { $Self_ { $($field: one()),+ } }
|
fn one() -> $Self_<$S> { $Self_ { $($field: one()),+ } }
|
||||||
}
|
}
|
||||||
|
@ -300,8 +307,6 @@ macro_rules! vec(
|
||||||
#[inline] fn div_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field / v.$field),+) }
|
#[inline] fn div_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field / v.$field),+) }
|
||||||
#[inline] fn rem_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field % v.$field),+) }
|
#[inline] fn rem_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field % v.$field),+) }
|
||||||
|
|
||||||
#[inline] fn neg_self(&mut self) { $(self.$field = -self.$field;)+ }
|
|
||||||
|
|
||||||
#[inline] fn add_self_s(&mut self, s: S) { $(self.$field = self.$field + s;)+ }
|
#[inline] fn add_self_s(&mut self, s: S) { $(self.$field = self.$field + s;)+ }
|
||||||
#[inline] fn sub_self_s(&mut self, s: S) { $(self.$field = self.$field - s;)+ }
|
#[inline] fn sub_self_s(&mut self, s: S) { $(self.$field = self.$field - s;)+ }
|
||||||
#[inline] fn mul_self_s(&mut self, s: S) { $(self.$field = self.$field * s;)+ }
|
#[inline] fn mul_self_s(&mut self, s: S) { $(self.$field = self.$field * s;)+ }
|
||||||
|
@ -334,7 +339,7 @@ macro_rules! vec(
|
||||||
fn sub(self, v: $Self_<S>) -> $Self_<S> { self.sub_v(&v) }
|
fn sub(self, v: $Self_<S>) -> $Self_<S> { self.sub_v(&v) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Neg for $Self_<S> {
|
impl<S: Neg<Output = S>> Neg for $Self_<S> {
|
||||||
type Output = $Self_<S>;
|
type Output = $Self_<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#![feature(core)]
|
|
||||||
|
|
||||||
|
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#![feature(core)]
|
|
||||||
|
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use cgmath::{ToMatrix4, ToMatrix3};
|
use cgmath::{ToMatrix4, ToMatrix3};
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
use std::num::Float;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_intersection() {
|
fn test_intersection() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ fn test_components() {
|
||||||
disp: Vector3::new(6.0f64,-7.0,8.0)
|
disp: Vector3::new(6.0f64,-7.0,8.0)
|
||||||
};
|
};
|
||||||
let (scale, rot, disp) = t.decompose();
|
let (scale, rot, disp) = t.decompose();
|
||||||
assert_eq!(scale, Vector::from_value(t.scale));
|
assert_eq!(scale, Vector3::from_value(t.scale));
|
||||||
assert_eq!(rot, t.rot);
|
assert_eq!(rot, t.rot);
|
||||||
assert_eq!(disp, t.disp);
|
assert_eq!(disp, t.disp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#![feature(core)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::num::Float;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_constructor() {
|
fn test_constructor() {
|
||||||
|
@ -31,9 +28,9 @@ fn test_constructor() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_value() {
|
fn test_from_value() {
|
||||||
assert_eq!(Vector::from_value(102isize), Vector2::new(102isize, 102isize));
|
assert_eq!(Vector2::from_value(102isize), Vector2::new(102isize, 102isize));
|
||||||
assert_eq!(Vector::from_value(22isize), Vector3::new(22isize, 22isize, 22isize));
|
assert_eq!(Vector3::from_value(22isize), Vector3::new(22isize, 22isize, 22isize));
|
||||||
assert_eq!(Vector::from_value(76.5f64), Vector4::new(76.5f64, 76.5f64, 76.5f64, 76.5f64));
|
assert_eq!(Vector4::from_value(76.5f64), Vector4::new(76.5f64, 76.5f64, 76.5f64, 76.5f64));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue