From ac991aaec0a7841160da69af8e5165552164c894 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Fri, 24 Jan 2014 03:00:24 +1100 Subject: [PATCH] Impl appropriate operators for implementors of Zero and One --- src/cgmath/angle.rs | 28 ++++++++++++++++++++++------ src/cgmath/matrix.rs | 30 +++++++++++++++++++++++------- src/cgmath/point.rs | 14 +++++++++----- src/cgmath/vector.rs | 28 ++++++++++++++++++++++------ 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/src/cgmath/angle.rs b/src/cgmath/angle.rs index 6fee689..637c408 100644 --- a/src/cgmath/angle.rs +++ b/src/cgmath/angle.rs @@ -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 } -#[deriving(Clone, Eq, Ord, Zero)] pub struct Deg { s: S } +#[deriving(Clone, Eq, Ord)] pub struct Rad { s: S } +#[deriving(Clone, Eq, Ord)] pub struct Deg { s: S } #[inline] pub fn rad(s: S) -> Rad { Rad { s: s } } #[inline] pub fn deg(s: S) -> Deg { Deg { s: s } } @@ -38,9 +38,6 @@ impl ToRad for Deg { #[inline] fn to_rad(&self) -> Rad { rad( impl ToDeg for Rad { #[inline] fn to_deg(&self) -> Deg { deg(self.s.to_degrees()) } } impl ToDeg for Deg { #[inline] fn to_deg(&self) -> Deg { self.clone() } } -impl Neg> for Rad { #[inline] fn neg(&self) -> Rad { rad(-self.s) } } -impl Neg> for Deg { #[inline] fn neg(&self) -> Deg { deg(-self.s) } } - /// Private utility functions for converting to/from scalars trait ScalarConv { fn from(s: S) -> Self; @@ -148,6 +145,25 @@ Deg { #[inline] pub fn turn_div_6() -> Deg { Angle::turn_div_6() } } + +impl Add, Rad> for Rad { #[inline] fn add(&self, other: &Rad) -> Rad { rad(self.s + other.s) } } +impl Add, Deg> for Deg { #[inline] fn add(&self, other: &Deg) -> Deg { deg(self.s + other.s) } } + +impl Sub, Rad> for Rad { #[inline] fn sub(&self, other: &Rad) -> Rad { rad(self.s - other.s) } } +impl Sub, Deg> for Deg { #[inline] fn sub(&self, other: &Deg) -> Deg { deg(self.s - other.s) } } + +impl Neg> for Rad { #[inline] fn neg(&self) -> Rad { rad(-self.s) } } +impl Neg> for Deg { #[inline] fn neg(&self) -> Deg { deg(-self.s) } } + +impl Zero for Rad { #[inline] fn zero() -> Rad { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl Zero for Deg { #[inline] fn zero() -> Deg { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } + +impl Mul, Rad> for Rad { #[inline] fn mul(&self, other: &Rad) -> Rad { rad(self.s * other.s) } } +impl Mul, Deg> for Deg { #[inline] fn mul(&self, other: &Deg) -> Deg { deg(self.s * other.s) } } + +impl One for Rad { #[inline] fn one() -> Rad { rad(one()) } } +impl One for Deg { #[inline] fn one() -> Deg { deg(one()) } } + impl> Equiv> for Rad { fn equiv(&self, other: &Rad) -> bool { diff --git a/src/cgmath/matrix.rs b/src/cgmath/matrix.rs index 421a561..041ed23 100644 --- a/src/cgmath/matrix.rs +++ b/src/cgmath/matrix.rs @@ -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 { x: Vec2, y: Vec2 } /// A 3 x 3, column major matrix -#[deriving(Clone, Eq, Zero)] +#[deriving(Clone, Eq)] pub struct Mat3 { x: Vec3, y: Vec3, z: Vec3 } /// A 4 x 4, column major matrix -#[deriving(Clone, Eq, Zero)] +#[deriving(Clone, Eq)] pub struct Mat4 { x: Vec4, y: Vec4, z: Vec4, w: Vec4 } @@ -236,10 +236,6 @@ Mat4 { } } -impl One for Mat2 { #[inline] fn one() -> Mat2 { Mat2::identity() } } -impl One for Mat3 { #[inline] fn one() -> Mat3 { Mat3::identity() } } -impl One for Mat4 { #[inline] fn one() -> Mat4 { Mat4::identity() } } - array!(impl Mat2 -> [Vec2, ..2] _2) array!(impl Mat3 -> [Vec3, ..3] _3) array!(impl Mat4 -> [Vec4, ..4] _4) @@ -358,10 +354,30 @@ pub trait Matrix fn is_symmetric(&self) -> bool; } +impl Add, Mat2> for Mat2 { #[inline] fn add(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).add_v(other.i(i))) } } +impl Add, Mat3> for Mat3 { #[inline] fn add(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).add_v(other.i(i))) } } +impl Add, Mat4> for Mat4 { #[inline] fn add(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).add_v(other.i(i))) } } + +impl Sub, Mat2> for Mat2 { #[inline] fn sub(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).sub_v(other.i(i))) } } +impl Sub, Mat3> for Mat3 { #[inline] fn sub(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).sub_v(other.i(i))) } } +impl Sub, Mat4> for Mat4 { #[inline] fn sub(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).sub_v(other.i(i))) } } + impl Neg> for Mat2 { #[inline] fn neg(&self) -> Mat2 { build(|i| self.i(i).neg()) } } impl Neg> for Mat3 { #[inline] fn neg(&self) -> Mat3 { build(|i| self.i(i).neg()) } } impl Neg> for Mat4 { #[inline] fn neg(&self) -> Mat4 { build(|i| self.i(i).neg()) } } +impl Zero for Mat2 { #[inline] fn zero() -> Mat2 { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl Zero for Mat3 { #[inline] fn zero() -> Mat3 { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl Zero for Mat4 { #[inline] fn zero() -> Mat4 { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } + +impl Mul, Mat2> for Mat2 { #[inline] fn mul(&self, other: &Mat2) -> Mat2 { build(|i| self.i(i).mul_v(other.i(i))) } } +impl Mul, Mat3> for Mat3 { #[inline] fn mul(&self, other: &Mat3) -> Mat3 { build(|i| self.i(i).mul_v(other.i(i))) } } +impl Mul, Mat4> for Mat4 { #[inline] fn mul(&self, other: &Mat4) -> Mat4 { build(|i| self.i(i).mul_v(other.i(i))) } } + +impl One for Mat2 { #[inline] fn one() -> Mat2 { Mat2::identity() } } +impl One for Mat3 { #[inline] fn one() -> Mat3 { Mat3::identity() } } +impl One for Mat4 { #[inline] fn one() -> Mat4 { Mat4::identity() } } + impl> Matrix, ..2], Vec2, [S, ..2]> for Mat2 diff --git a/src/cgmath/point.rs b/src/cgmath/point.rs index 7f481d3..193a1ed 100644 --- a/src/cgmath/point.rs +++ b/src/cgmath/point.rs @@ -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 { x: S, y: S } /// A point in 3-dimensional space. -#[deriving(Eq, Zero, Clone)] +#[deriving(Eq, Clone)] pub struct Point3 { x: S, y: S, z: S } @@ -39,7 +39,9 @@ impl Point2 { } #[inline] - pub fn origin() -> Point2 { zero() } + pub fn origin() -> Point2 { + Point2 { x: zero(), y: zero() } + } } impl Point3 { @@ -49,7 +51,9 @@ impl Point3 { } #[inline] - pub fn origin() -> Point3 { zero() } + pub fn origin() -> Point3 { + Point3 { x: zero(), y: zero(), z: zero() } + } } impl Point3 { diff --git a/src/cgmath/vector.rs b/src/cgmath/vector.rs index 0860d0d..c3bb245 100644 --- a/src/cgmath/vector.rs +++ b/src/cgmath/vector.rs @@ -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 { x: S, y: S } /// A 3-dimensional vector. -#[deriving(Eq, Clone, Zero)] +#[deriving(Eq, Clone)] pub struct Vec3 { x: S, y: S, z: S } /// A 4-dimensional vector. -#[deriving(Eq, Clone, Zero)] +#[deriving(Eq, Clone)] pub struct Vec4 { 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>(a: V, b: V) -> S { a.dot(&b) } -impl One for Vec2 { #[inline] fn one() -> Vec2 { Vec2::ident() } } -impl One for Vec3 { #[inline] fn one() -> Vec3 { Vec3::ident() } } -impl One for Vec4 { #[inline] fn one() -> Vec4 { Vec4::ident() } } +impl Add, Vec2> for Vec2 { #[inline] fn add(&self, other: &Vec2) -> Vec2 { self.add_v(other) } } +impl Add, Vec3> for Vec3 { #[inline] fn add(&self, other: &Vec3) -> Vec3 { self.add_v(other) } } +impl Add, Vec4> for Vec4 { #[inline] fn add(&self, other: &Vec4) -> Vec4 { self.add_v(other) } } + +impl Sub, Vec2> for Vec2 { #[inline] fn sub(&self, other: &Vec2) -> Vec2 { self.sub_v(other) } } +impl Sub, Vec3> for Vec3 { #[inline] fn sub(&self, other: &Vec3) -> Vec3 { self.sub_v(other) } } +impl Sub, Vec4> for Vec4 { #[inline] fn sub(&self, other: &Vec4) -> Vec4 { self.sub_v(other) } } + +impl Zero for Vec2 { #[inline] fn zero() -> Vec2 { Vec2::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl Zero for Vec3 { #[inline] fn zero() -> Vec3 { Vec3::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } +impl Zero for Vec4 { #[inline] fn zero() -> Vec4 { Vec4::from_value(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl Neg> for Vec2 { #[inline] fn neg(&self) -> Vec2 { build(|i| self.i(i).neg()) } } impl Neg> for Vec3 { #[inline] fn neg(&self) -> Vec3 { build(|i| self.i(i).neg()) } } impl Neg> for Vec4 { #[inline] fn neg(&self) -> Vec4 { build(|i| self.i(i).neg()) } } +impl Mul, Vec2> for Vec2 { #[inline] fn mul(&self, other: &Vec2) -> Vec2 { self.mul_v(other) } } +impl Mul, Vec3> for Vec3 { #[inline] fn mul(&self, other: &Vec3) -> Vec3 { self.mul_v(other) } } +impl Mul, Vec4> for Vec4 { #[inline] fn mul(&self, other: &Vec4) -> Vec4 { self.mul_v(other) } } + +impl One for Vec2 { #[inline] fn one() -> Vec2 { Vec2::from_value(one()) } } +impl One for Vec3 { #[inline] fn one() -> Vec3 { Vec3::from_value(one()) } } +impl One for Vec4 { #[inline] fn one() -> Vec4 { Vec4::from_value(one()) } } + impl Vector for Vec2 {} impl Vector for Vec3 {} impl Vector for Vec4 {}