Impl appropriate operators for implementors of Zero and One

This commit is contained in:
Brendan Zabarauskas 2014-01-24 03:00:24 +11:00
parent cbc08a7de7
commit ac991aaec0
4 changed files with 76 additions and 24 deletions

View file

@ -19,12 +19,12 @@ pub use std::num::{sinh, cosh, tanh};
pub use std::num::{asinh, acosh, atanh};
use std::fmt;
use std::num::{Zero, zero, cast};
use std::num::{One, one, Zero, zero, cast};
use approx::ApproxEq;
#[deriving(Clone, Eq, Ord, Zero)] pub struct Rad<S> { s: S }
#[deriving(Clone, Eq, Ord, Zero)] pub struct Deg<S> { s: S }
#[deriving(Clone, Eq, Ord)] pub struct Rad<S> { s: S }
#[deriving(Clone, Eq, Ord)] pub struct Deg<S> { s: S }
#[inline] pub fn rad<S: Float>(s: S) -> Rad<S> { Rad { s: s } }
#[inline] pub fn deg<S: Float>(s: S) -> Deg<S> { Deg { s: s } }
@ -38,9 +38,6 @@ impl<S: Float> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(
impl<S: Float> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
impl<S: Float> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
/// Private utility functions for converting to/from scalars
trait ScalarConv<S> {
fn from(s: S) -> Self;
@ -148,6 +145,25 @@ Deg<S> {
#[inline] pub fn turn_div_6() -> Deg<S> { Angle::turn_div_6() }
}
impl<S: Float> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
impl<S: Float> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }
impl<S: Float> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
impl<S: Float> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }
impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
impl<S: Float> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
impl<S: Float> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }
impl<S: Float> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
impl<S: Float> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }
impl<S: Float + ApproxEq<S>>
Equiv<Rad<S>> for Rad<S> {
fn equiv(&self, other: &Rad<S>) -> bool {

View file

@ -26,15 +26,15 @@ use vector::{Vector, EuclideanVector};
use vector::{Vec2, Vec3, Vec4};
/// A 2 x 2, column major matrix
#[deriving(Clone, Eq, Zero)]
#[deriving(Clone, Eq)]
pub struct Mat2<S> { x: Vec2<S>, y: Vec2<S> }
/// A 3 x 3, column major matrix
#[deriving(Clone, Eq, Zero)]
#[deriving(Clone, Eq)]
pub struct Mat3<S> { x: Vec3<S>, y: Vec3<S>, z: Vec3<S> }
/// A 4 x 4, column major matrix
#[deriving(Clone, Eq, Zero)]
#[deriving(Clone, Eq)]
pub struct Mat4<S> { x: Vec4<S>, y: Vec4<S>, z: Vec4<S>, w: Vec4<S> }
@ -236,10 +236,6 @@ Mat4<S> {
}
}
impl<S: Float> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } }
impl<S: Float> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } }
impl<S: Float> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } }
array!(impl<S> Mat2<S> -> [Vec2<S>, ..2] _2)
array!(impl<S> Mat3<S> -> [Vec3<S>, ..3] _3)
array!(impl<S> Mat4<S> -> [Vec4<S>, ..4] _4)
@ -358,10 +354,30 @@ pub trait Matrix
fn is_symmetric(&self) -> bool;
}
impl<S: Float> Add<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn add(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Add<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn add(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Add<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn add(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Sub<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn sub(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Sub<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn sub(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Sub<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn sub(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Neg<Mat3<S>> for Mat3<S> { #[inline] fn neg(&self) -> Mat3<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Zero for Mat2<S> { #[inline] fn zero() -> Mat2<S> { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Mat3<S> { #[inline] fn zero() -> Mat3<S> { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Mat4<S> { #[inline] fn zero() -> Mat4<S> { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Mul<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn mul(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> Mul<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn mul(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> Mul<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn mul(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } }
impl<S: Float> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } }
impl<S: Float> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } }
impl<S: Float + ApproxEq<S>>
Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]>
for Mat2<S>

View file

@ -18,17 +18,17 @@
//! not have a fixed position.
use std::fmt;
use std::num::{one,zero};
use std::num::{one, zero};
use array::*;
use vector::*;
/// A point in 2-dimensional space.
#[deriving(Eq, Zero, Clone)]
#[deriving(Eq, Clone)]
pub struct Point2<S> { x: S, y: S }
/// A point in 3-dimensional space.
#[deriving(Eq, Zero, Clone)]
#[deriving(Eq, Clone)]
pub struct Point3<S> { x: S, y: S, z: S }
@ -39,7 +39,9 @@ impl<S: Num> Point2<S> {
}
#[inline]
pub fn origin() -> Point2<S> { zero() }
pub fn origin() -> Point2<S> {
Point2 { x: zero(), y: zero() }
}
}
impl<S: Num> Point3<S> {
@ -49,7 +51,9 @@ impl<S: Num> Point3<S> {
}
#[inline]
pub fn origin() -> Point3<S> { zero() }
pub fn origin() -> Point3<S> {
Point3 { x: zero(), y: zero(), z: zero() }
}
}
impl<S: Clone + Num + Primitive> Point3<S> {

View file

@ -21,15 +21,15 @@ use approx::ApproxEq;
use array::{Array, build};
/// A 2-dimensional vector.
#[deriving(Eq, Clone, Zero)]
#[deriving(Eq, Clone)]
pub struct Vec2<S> { x: S, y: S }
/// A 3-dimensional vector.
#[deriving(Eq, Clone, Zero)]
#[deriving(Eq, Clone)]
pub struct Vec3<S> { x: S, y: S, z: S }
/// A 4-dimensional vector.
#[deriving(Eq, Clone, Zero)]
#[deriving(Eq, Clone)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }
// Conversion traits //FIXME: not used anywhere?
@ -169,14 +169,30 @@ pub trait Vector
#[inline] pub fn dot<S: Primitive, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
impl<S: Primitive> One for Vec2<S> { #[inline] fn one() -> Vec2<S> { Vec2::ident() } }
impl<S: Primitive> One for Vec3<S> { #[inline] fn one() -> Vec3<S> { Vec3::ident() } }
impl<S: Primitive> One for Vec4<S> { #[inline] fn one() -> Vec4<S> { Vec4::ident() } }
impl<S: Primitive> Add<Vec2<S>, Vec2<S>> for Vec2<S> { #[inline] fn add(&self, other: &Vec2<S>) -> Vec2<S> { self.add_v(other) } }
impl<S: Primitive> Add<Vec3<S>, Vec3<S>> for Vec3<S> { #[inline] fn add(&self, other: &Vec3<S>) -> Vec3<S> { self.add_v(other) } }
impl<S: Primitive> Add<Vec4<S>, Vec4<S>> for Vec4<S> { #[inline] fn add(&self, other: &Vec4<S>) -> Vec4<S> { self.add_v(other) } }
impl<S: Primitive> Sub<Vec2<S>, Vec2<S>> for Vec2<S> { #[inline] fn sub(&self, other: &Vec2<S>) -> Vec2<S> { self.sub_v(other) } }
impl<S: Primitive> Sub<Vec3<S>, Vec3<S>> for Vec3<S> { #[inline] fn sub(&self, other: &Vec3<S>) -> Vec3<S> { self.sub_v(other) } }
impl<S: Primitive> Sub<Vec4<S>, Vec4<S>> for Vec4<S> { #[inline] fn sub(&self, other: &Vec4<S>) -> Vec4<S> { self.sub_v(other) } }
impl<S: Primitive> Zero for Vec2<S> { #[inline] fn zero() -> Vec2<S> { Vec2::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Primitive> Zero for Vec3<S> { #[inline] fn zero() -> Vec3<S> { Vec3::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Primitive> Zero for Vec4<S> { #[inline] fn zero() -> Vec4<S> { Vec4::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Primitive> Neg<Vec2<S>> for Vec2<S> { #[inline] fn neg(&self) -> Vec2<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec3<S>> for Vec3<S> { #[inline] fn neg(&self) -> Vec3<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Neg<Vec4<S>> for Vec4<S> { #[inline] fn neg(&self) -> Vec4<S> { build(|i| self.i(i).neg()) } }
impl<S: Primitive> Mul<Vec2<S>, Vec2<S>> for Vec2<S> { #[inline] fn mul(&self, other: &Vec2<S>) -> Vec2<S> { self.mul_v(other) } }
impl<S: Primitive> Mul<Vec3<S>, Vec3<S>> for Vec3<S> { #[inline] fn mul(&self, other: &Vec3<S>) -> Vec3<S> { self.mul_v(other) } }
impl<S: Primitive> Mul<Vec4<S>, Vec4<S>> for Vec4<S> { #[inline] fn mul(&self, other: &Vec4<S>) -> Vec4<S> { self.mul_v(other) } }
impl<S: Primitive> One for Vec2<S> { #[inline] fn one() -> Vec2<S> { Vec2::from_value(one()) } }
impl<S: Primitive> One for Vec3<S> { #[inline] fn one() -> Vec3<S> { Vec3::from_value(one()) } }
impl<S: Primitive> One for Vec4<S> { #[inline] fn one() -> Vec4<S> { Vec4::from_value(one()) } }
impl<S: Primitive> Vector<S, [S, ..2]> for Vec2<S> {}
impl<S: Primitive> Vector<S, [S, ..3]> for Vec3<S> {}
impl<S: Primitive> Vector<S, [S, ..4]> for Vec4<S> {}