Merge pull request #273 from bjz/operator-method-sweep

Operator method sweep
This commit is contained in:
Brendan Zabarauskas 2015-12-13 13:05:40 +11:00
commit de4389759b
8 changed files with 80 additions and 227 deletions

View file

@ -17,6 +17,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
simplifies the signature of `PerspectiveFov` from `PerspectiveFov<S, A>` to
`PerspectiveFov<S>`.
### Changed
- `Vector` and `Point` are now constrained to require specific operators to be
overloaded. This means that generic code can now use operators, instead of
the operator methods.
### Removed
- Remove redundant `Point::{min, max}` methods - these are now covered by the
`Array::{min, max}` methods that were introduced in 0.5.0.
@ -25,6 +30,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
accessing the fields on `Decomposed` directly. To create the scale vector,
use: `Vector::from_value(transform.scale)`.
- Removed `CompositeTransform`, `CompositeTransform2`, and `CompositeTransform3`.
- Remove `Vector::one`. Vectors don't really have a multiplicative identity.
If you really want a `one` vector, you can do something like:
`Vector::from_value(1.0)`.
- Remove operator methods from `Vector` and `Point` traits in favor of operator
overloading.
- Remove `*_self` methods from `Vector` and `Point`. These were of little
performance benefit, and assignment operator overloading will be coming soon!
## [v0.6.0] - 2015-12-12

View file

@ -467,14 +467,14 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
#[inline]
fn mul_self_s(&mut self, s: S) {
self[0].mul_self_s(s);
self[1].mul_self_s(s);
self[0] = self[0] * s;
self[1] = self[1] * s;
}
#[inline]
fn div_self_s(&mut self, s: S) {
self[0].div_self_s(s);
self[1].div_self_s(s);
self[0] = self[0] / s;
self[1] = self[1] / s;
}
fn transpose(&self) -> Matrix2<S> {
@ -511,14 +511,14 @@ impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
#[inline]
fn add_self_m(&mut self, m: &Matrix2<S>) {
self[0].add_self_v(m[0]);
self[1].add_self_v(m[1]);
self[0] = self[0] + m[0];
self[1] = self[1] + m[1];
}
#[inline]
fn sub_self_m(&mut self, m: &Matrix2<S>) {
self[0].sub_self_v(m[0]);
self[1].sub_self_v(m[1]);
self[0] = self[0] - m[0];
self[1] = self[1] - m[1];
}
#[inline]
@ -615,16 +615,16 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
#[inline]
fn mul_self_s(&mut self, s: S) {
self[0].mul_self_s(s);
self[1].mul_self_s(s);
self[2].mul_self_s(s);
self[0] = self[0] * s;
self[1] = self[1] * s;
self[2] = self[2] * s;
}
#[inline]
fn div_self_s(&mut self, s: S) {
self[0].div_self_s(s);
self[1].div_self_s(s);
self[2].div_self_s(s);
self[0] = self[0] / s;
self[1] = self[1] / s;
self[2] = self[2] / s;
}
fn transpose(&self) -> Matrix3<S> {
@ -664,16 +664,16 @@ impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
#[inline]
fn add_self_m(&mut self, m: &Matrix3<S>) {
self[0].add_self_v(m[0]);
self[1].add_self_v(m[1]);
self[2].add_self_v(m[2]);
self[0] = self[0] + m[0];
self[1] = self[1] + m[1];
self[2] = self[2] + m[2];
}
#[inline]
fn sub_self_m(&mut self, m: &Matrix3<S>) {
self[0].sub_self_v(m[0]);
self[1].sub_self_v(m[1]);
self[2].sub_self_v(m[2]);
self[0] = self[0] - m[0];
self[1] = self[1] - m[1];
self[2] = self[2] - m[2];
}
#[inline]
@ -784,18 +784,18 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
#[inline]
fn mul_self_s(&mut self, s: S) {
self[0].mul_self_s(s);
self[1].mul_self_s(s);
self[2].mul_self_s(s);
self[3].mul_self_s(s);
self[0] = self[0] * s;
self[1] = self[1] * s;
self[2] = self[2] * s;
self[3] = self[3] * s;
}
#[inline]
fn div_self_s(&mut self, s: S) {
self[0].div_self_s(s);
self[1].div_self_s(s);
self[2].div_self_s(s);
self[3].div_self_s(s);
self[0] = self[0] / s;
self[1] = self[1] / s;
self[2] = self[2] / s;
self[3] = self[3] / s;
}
fn transpose(&self) -> Matrix4<S> {
@ -838,18 +838,18 @@ impl<S: BaseFloat> SquareMatrix for Matrix4<S> {
#[inline]
fn add_self_m(&mut self, m: &Matrix4<S>) {
self[0].add_self_v(m[0]);
self[1].add_self_v(m[1]);
self[2].add_self_v(m[2]);
self[3].add_self_v(m[3]);
self[0] = self[0] + m[0];
self[1] = self[1] + m[1];
self[2] = self[2] + m[2];
self[3] = self[3] + m[3];
}
#[inline]
fn sub_self_m(&mut self, m: &Matrix4<S>) {
self[0].sub_self_v(m[0]);
self[1].sub_self_v(m[1]);
self[2].sub_self_v(m[2]);
self[3].sub_self_v(m[3]);
self[0] = self[0] - m[0];
self[1] = self[1] - m[1];
self[2] = self[2] - m[2];
self[3] = self[3] - m[3];
}
fn transpose_self(&mut self) {

View file

@ -69,14 +69,13 @@ impl<S: BaseNum> Point3<S> {
pub trait Point: Copy + Clone where
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
Self: Array<Element = <Self as Point>::Scalar>,
// FIXME: blocked by rust-lang/rust#20671
//
// for<'a, 'b> &'a Self: Add<&'b V, Output = Self>,
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = V>,
//
// for<'a> &'a Self: Mul<S, Output = Self>,
// for<'a> &'a Self: Div<S, Output = Self>,
// for<'a> &'a Self: Rem<S, Output = Self>,
Self: Add<<Self as Point>::Vector, Output = Self>,
Self: Sub<Self, Output = <Self as Point>::Vector>,
Self: Mul<<Self as Point>::Scalar, Output = Self>,
Self: Div<<Self as Point>::Scalar, Output = Self>,
Self: Rem<<Self as Point>::Scalar, Output = Self>,
{
/// The associated scalar.
///
@ -94,32 +93,6 @@ pub trait Point: Copy + Clone where
/// Convert a point to a vector.
fn to_vec(self) -> Self::Vector;
/// Multiply each component by a scalar, returning the new point.
#[must_use]
fn mul_s(self, scalar: Self::Scalar) -> Self;
/// Divide each component by a scalar, returning the new point.
#[must_use]
fn div_s(self, scalar: Self::Scalar) -> Self;
/// Subtract a scalar from each component, returning the new point.
#[must_use]
fn rem_s(self, scalar: Self::Scalar) -> Self;
/// Add a vector to this point, returning the new point.
#[must_use]
fn add_v(self, v: Self::Vector) -> Self;
/// Subtract another point from this one, returning a new vector.
fn sub_p(self, p: Self) -> Self::Vector;
/// Multiply each component by a scalar, in-place.
fn mul_self_s(&mut self, scalar: Self::Scalar);
/// Divide each component by a scalar, in-place.
fn div_self_s(&mut self, scalar: Self::Scalar);
/// Take the remainder of each component by a scalar, in-place.
fn rem_self_s(&mut self, scalar: Self::Scalar);
/// Add a vector to this point, in-place.
fn add_self_v(&mut self, v: Self::Vector);
/// This is a weird one, but its useful for plane calculations.
fn dot(self, v: Self::Vector) -> Self::Scalar;
}
@ -154,16 +127,6 @@ macro_rules! impl_point {
$VectorN::new($(self.$field),+)
}
#[inline] fn mul_s(self, scalar: S) -> $PointN<S> { self * scalar }
#[inline] fn div_s(self, scalar: S) -> $PointN<S> { self / scalar }
#[inline] fn rem_s(self, scalar: S) -> $PointN<S> { self % scalar }
#[inline] fn add_v(self, v: $VectorN<S>) -> $PointN<S> { self + v }
#[inline] fn sub_p(self, p: $PointN<S>) -> $VectorN<S> { self - p }
#[inline] fn mul_self_s(&mut self, scalar: S) { *self = *self * scalar; }
#[inline] fn div_self_s(&mut self, scalar: S) { *self = *self / scalar; }
#[inline] fn rem_self_s(&mut self, scalar: S) { *self = *self % scalar; }
#[inline] fn add_self_v(&mut self, vector: $VectorN<S>) { *self = *self + vector; }
#[inline]
fn dot(self, v: $VectorN<S>) -> S {
$VectorN::new($(self.$field * v.$field),+).sum()

View file

@ -363,7 +363,7 @@ impl<S: BaseFloat> Rotation3<S> for Quaternion<S> {
#[inline]
fn from_axis_angle(axis: Vector3<S>, angle: Rad<S>) -> Quaternion<S> {
let (s, c) = sin_cos(angle.mul_s(cast(0.5f64).unwrap()));
Quaternion::from_sv(c, axis.mul_s(s))
Quaternion::from_sv(c, axis * s)
}
/// - [Maths - Conversion Euler to Quaternion]

View file

@ -81,6 +81,8 @@ pub struct Decomposed<V: Vector, R> {
impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
<P as Point>::Scalar: BaseFloat,
// FIXME: Investigate why this is needed!
<P as Point>::Vector: Vector,
{
#[inline]
fn one() -> Decomposed<P::Vector, R> {
@ -93,8 +95,8 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
#[inline]
fn look_at(eye: P, center: P, up: P::Vector) -> Decomposed<P::Vector, R> {
let rot = R::look_at(center.sub_p(eye.clone()), up);
let disp = rot.rotate_vector(P::origin().sub_p(eye));
let rot = R::look_at(center - eye, up);
let disp = rot.rotate_vector(P::origin() - eye);
Decomposed {
scale: <P as Point>::Scalar::one(),
rot: rot,
@ -104,12 +106,12 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
#[inline]
fn transform_vector(&self, vec: P::Vector) -> P::Vector {
self.rot.rotate_vector(vec.mul_s(self.scale))
self.rot.rotate_vector(vec * self.scale)
}
#[inline]
fn transform_point(&self, point: P) -> P {
self.rot.rotate_point(point.mul_s(self.scale)).add_v(self.disp.clone())
self.rot.rotate_point(point * self.scale) + self.disp
}
fn concat(&self, other: &Decomposed<P::Vector, R>) -> Decomposed<P::Vector, R> {
@ -126,7 +128,7 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
} else {
let s = <P as Point>::Scalar::one() / self.scale;
let r = self.rot.invert();
let d = r.rotate_vector(self.disp.clone()).mul_s(-s);
let d = r.rotate_vector(self.disp.clone()) * -s;
Some(Decomposed {
scale: s,
rot: r,

View file

@ -41,7 +41,6 @@
//!
//! assert_eq!(a + b, Vector2::zero());
//! assert_eq!(-(a * b), Vector2::new(9.0f64, 16.0f64));
//! assert_eq!(a / Vector2::one(), a);
//!
//! // As with Rust's `int` and `f32` types, Vectors of different types cannot
//! // be added and so on with impunity. The following will fail to compile:
@ -73,13 +72,6 @@
//! // But there is also a top-level function:
//! assert_eq!(a.dot(b), dot(a, b));
//!
//! // Scalar multiplication can return a new object, or be done in place
//! // to avoid an allocation:
//! let mut c = Vector4::from_value(3f64);
//! let d: Vector4<f64> = c.mul_s(2.0);
//! c.mul_self_s(2.0);
//! assert_eq!(c, d);
//!
//! // Cross products are defined for 3-dimensional vectors:
//! let e: Vector3<f64> = Vector3::unit_x();
//! let f: Vector3<f64> = Vector3::unit_y();
@ -114,20 +106,18 @@ use num::{BaseNum, BaseFloat, PartialOrd};
pub trait Vector: Copy + Clone where
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
Self: Array<Element = <Self as Vector>::Scalar>,
// FIXME: blocked by rust-lang/rust#20671
//
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Mul<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Div<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Rem<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>,
//
// for<'a> &'a Self: Add<S, Output = Self>,
// for<'a> &'a Self: Sub<S, Output = Self>,
// for<'a> &'a Self: Mul<S, Output = Self>,
// for<'a> &'a Self: Div<S, Output = Self>,
// for<'a> &'a Self: Rem<S, Output = Self>,
Self: Add<Self, Output = Self>,
Self: Sub<Self, Output = Self>,
Self: Mul<Self, Output = Self>,
Self: Div<Self, Output = Self>,
Self: Rem<Self, Output = Self>,
Self: Add<<Self as Vector>::Scalar, Output = Self>,
Self: Sub<<Self as Vector>::Scalar, Output = Self>,
Self: Mul<<Self as Vector>::Scalar, Output = Self>,
Self: Div<<Self as Vector>::Scalar, Output = Self>,
Self: Rem<<Self as Vector>::Scalar, Output = Self>,
{
/// The associated scalar.
type Scalar: BaseNum;
@ -135,66 +125,9 @@ pub trait Vector: Copy + Clone where
/// Construct a vector from a single value, replicating it.
fn from_value(scalar: Self::Scalar) -> Self;
/// The zero vector (with all components set to zero)
/// The additive identity vector. Adding this vector with another has no effect.
#[inline]
fn zero() -> Self { Self::from_value(Self::Scalar::zero()) }
/// The identity vector (with all components set to one)
#[inline]
fn one() -> Self { Self::from_value(Self::Scalar::one()) }
/// Add a scalar to this vector, returning a new vector.
#[must_use]
fn add_s(self, scalar: Self::Scalar) -> Self;
/// Subtract a scalar from this vector, returning a new vector.
#[must_use]
fn sub_s(self, scalar: Self::Scalar) -> Self;
/// Multiply this vector by a scalar, returning a new vector.
#[must_use]
fn mul_s(self, scalar: Self::Scalar) -> Self;
/// Divide this vector by a scalar, returning a new vector.
#[must_use]
fn div_s(self, scalar: Self::Scalar) -> Self;
/// Take the remainder of this vector by a scalar, returning a new vector.
#[must_use]
fn rem_s(self, scalar: Self::Scalar) -> Self;
/// Add this vector to another, returning a new vector.
#[must_use]
fn add_v(self, v: Self) -> Self;
/// Subtract another vector from this one, returning a new vector.
#[must_use]
fn sub_v(self, v: Self) -> Self;
/// Multiply this vector by another, returning a new vector.
#[must_use]
fn mul_v(self, v: Self) -> Self;
/// Divide this vector by another, returning a new vector.
#[must_use]
fn div_v(self, v: Self) -> Self;
/// Take the remainder of this vector by another, returning a new scalar.
#[must_use]
fn rem_v(self, v: Self) -> Self;
/// Add a scalar to this vector in-place.
fn add_self_s(&mut self, scalar: Self::Scalar);
/// Subtract a scalar from this vector, in-place.
fn sub_self_s(&mut self, scalar: Self::Scalar);
/// Multiply this vector by a scalar, in-place.
fn mul_self_s(&mut self, scalar: Self::Scalar);
/// Divide this vector by a scalar, in-place.
fn div_self_s(&mut self, scalar: Self::Scalar);
/// Take the remainder of this vector by a scalar, in-place.
fn rem_self_s(&mut self, scalar: Self::Scalar);
/// Add another vector to this one, in-place.
fn add_self_v(&mut self, v: Self);
/// Subtract another vector from this one, in-place.
fn sub_self_v(&mut self, v: Self);
/// Multiply this matrix by another, in-place.
fn mul_self_v(&mut self, v: Self);
/// Divide this matrix by anothor, in-place.
fn div_self_v(&mut self, v: Self);
/// Take the remainder of this vector by another, in-place.
fn rem_self_v(&mut self, v: Self);
/// Vector dot product
fn dot(self, other: Self) -> Self::Scalar;
@ -253,30 +186,6 @@ macro_rules! impl_vector {
#[inline] fn from_value(scalar: S) -> $VectorN<S> { $VectorN { $($field: scalar),+ } }
#[inline] fn add_s(self, scalar: S) -> $VectorN<S> { self + scalar }
#[inline] fn sub_s(self, scalar: S) -> $VectorN<S> { self - scalar }
#[inline] fn mul_s(self, scalar: S) -> $VectorN<S> { self * scalar }
#[inline] fn div_s(self, scalar: S) -> $VectorN<S> { self / scalar }
#[inline] fn rem_s(self, scalar: S) -> $VectorN<S> { self % scalar }
#[inline] fn add_v(self, v: $VectorN<S>) -> $VectorN<S> { self + v }
#[inline] fn sub_v(self, v: $VectorN<S>) -> $VectorN<S> { self - v }
#[inline] fn mul_v(self, v: $VectorN<S>) -> $VectorN<S> { self * v }
#[inline] fn div_v(self, v: $VectorN<S>) -> $VectorN<S> { self / v }
#[inline] fn rem_v(self, v: $VectorN<S>) -> $VectorN<S> { self % v }
#[inline] fn add_self_s(&mut self, scalar: S) { *self = &*self + scalar; }
#[inline] fn sub_self_s(&mut self, scalar: S) { *self = &*self - scalar; }
#[inline] fn mul_self_s(&mut self, scalar: S) { *self = &*self * scalar; }
#[inline] fn div_self_s(&mut self, scalar: S) { *self = &*self / scalar; }
#[inline] fn rem_self_s(&mut self, scalar: S) { *self = &*self % scalar; }
#[inline] fn add_self_v(&mut self, v: $VectorN<S>) { *self = &*self + v; }
#[inline] fn sub_self_v(&mut self, v: $VectorN<S>) { *self = &*self - v; }
#[inline] fn mul_self_v(&mut self, v: $VectorN<S>) { *self = &*self * v; }
#[inline] fn div_self_v(&mut self, v: $VectorN<S>) { *self = &*self / v; }
#[inline] fn rem_self_v(&mut self, v: $VectorN<S>) { *self = &*self % v; }
#[inline] fn dot(self, other: $VectorN<S>) -> S { (self * other).sum() }
}
@ -415,13 +324,6 @@ impl<S: BaseNum> Vector3<S> {
(self.x * other.y) - (self.y * other.x))
}
/// Calculates the cross product of the vector and `other`, then stores the
/// result in `self`.
#[inline]
pub fn cross_self(&mut self, other: Vector3<S>) {
*self = self.cross(other)
}
/// Create a `Vector4`, using the `x`, `y` and `z` values from this vector, and the
/// provided `w`.
#[inline]
@ -505,7 +407,7 @@ pub trait EuclideanVector: Vector + Sized where
/// The norm of the vector.
#[inline]
fn length(self) -> Self::Scalar {
// Not sure why these annotations are needed
// FIXME: Not sure why this annotation is needed
<<Self as Vector>::Scalar as ::rust_num::Float>::sqrt(self.dot(self))
}
@ -524,7 +426,7 @@ pub trait EuclideanVector: Vector + Sized where
#[inline]
#[must_use]
fn normalize_to(self, length: Self::Scalar) -> Self {
self.mul_s(length / self.length())
self * (length / self.length())
}
/// Returns the result of linarly interpolating the length of the vector
@ -532,29 +434,7 @@ pub trait EuclideanVector: Vector + Sized where
#[inline]
#[must_use]
fn lerp(self, other: Self, amount: Self::Scalar) -> Self {
self.add_v(other.sub_v(self).mul_s(amount))
}
/// Normalises the vector to a length of `1`.
#[inline]
fn normalize_self(&mut self) {
// Not sure why these annotations are needed
let rlen = <<Self as Vector>::Scalar as ::rust_num::Float>::recip(self.length());
self.mul_self_s(rlen);
}
/// Normalizes the vector to `length`.
#[inline]
fn normalize_self_to(&mut self, length: Self::Scalar) {
let n = length / self.length();
self.mul_self_s(n);
}
/// Linearly interpolates the length of the vector towards the length of
/// `other` by the specified amount.
fn lerp_self(&mut self, other: Self, amount: Self::Scalar) {
let v = other.sub_v(*self).mul_s(amount);
self.add_self_v(v);
self + ((other - self) * amount)
}
}

View file

@ -15,7 +15,7 @@
extern crate cgmath;
use cgmath::{Vector4, ortho, Matrix, Matrix4, Vector};
use cgmath::{Vector4, ortho, Matrix, Matrix4};
#[test]
fn test_ortho_scale() {

View file

@ -90,10 +90,6 @@ fn test_cross() {
let b = Vector3::new(4isize, 5isize, 6isize);
let r = Vector3::new(-3isize, 6isize, -3isize);
assert_eq!(a.cross(b), r);
let mut a = a;
a.cross_self(b);
assert_eq!(a, r);
}
#[test]