diff --git a/src/point.rs b/src/point.rs index 613e1df..3378b86 100644 --- a/src/point.rs +++ b/src/point.rs @@ -66,7 +66,7 @@ impl Point3 { } /// Specifies the numeric operations for point types. -pub trait Point>: Array1 + Clone // where +pub trait Point: Array1 + Clone // where // FIXME: blocked by rust-lang/rust#20671 // // for<'a, 'b> &'a Self: Add<&'b V, Output = Self>, @@ -76,13 +76,16 @@ pub trait Point>: Array1 + Clone // where // for<'a> &'a Self: Div, // for<'a> &'a Self: Rem, { + /// The associated displacement vector. + type Vector: Vector; + /// Create a point at the origin. fn origin() -> Self; /// Create a point from a vector. - fn from_vec(v: &V) -> Self; + fn from_vec(v: &Self::Vector) -> Self; /// Convert a point to a vector. - fn to_vec(&self) -> V; + fn to_vec(&self) -> Self::Vector; /// Multiply each component by a scalar, returning the new point. #[must_use] @@ -96,9 +99,9 @@ pub trait Point>: Array1 + Clone // where /// Add a vector to this point, returning the new point. #[must_use] - fn add_v(&self, v: &V) -> Self; + fn add_v(&self, v: &Self::Vector) -> Self; /// Subtract another point from this one, returning a new vector. - fn sub_p(&self, p: &Self) -> V; + fn sub_p(&self, p: &Self) -> Self::Vector; /// Multiply each component by a scalar, in-place. fn mul_self_s(&mut self, s: S); @@ -108,10 +111,10 @@ pub trait Point>: Array1 + Clone // where fn rem_self_s(&mut self, s: S); /// Add a vector to this point, in-place. - fn add_self_v(&mut self, v: &V); + fn add_self_v(&mut self, v: &Self::Vector); /// This is a weird one, but its useful for plane calculations. - fn dot(&self, v: &V) -> S; + fn dot(&self, v: &Self::Vector) -> S; #[must_use] fn min(&self, p: &Self) -> Self; @@ -122,7 +125,9 @@ pub trait Point>: Array1 + Clone // where impl Array1 for Point2 {} -impl Point> for Point2 { +impl Point for Point2 { + type Vector = Vector2; + #[inline] fn origin() -> Point2 { Point2::new(S::zero(), S::zero()) @@ -195,7 +200,9 @@ impl ApproxEq for Point2 { impl Array1 for Point3 {} -impl Point> for Point3 { +impl Point for Point3 { + type Vector = Vector3; + #[inline] fn origin() -> Point3 { Point3::new(S::zero(), S::zero(), S::zero()) diff --git a/src/quaternion.rs b/src/quaternion.rs index 29ddcc5..73cdff5 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -339,7 +339,7 @@ impl From> for Basis3 { fn from(quat: Quaternion) -> Basis3 { Basis3::from_quaternion(&quat) } } -impl Rotation, Point3> for Quaternion { +impl Rotation> for Quaternion { #[inline] fn one() -> Quaternion { Quaternion::one() } diff --git a/src/rotation.rs b/src/rotation.rs index ec683d9..f7340b1 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -25,19 +25,19 @@ use vector::{Vector, Vector2, Vector3}; /// A trait for a generic rotation. A rotation is a transformation that /// creates a circular motion, and preserves at least one point in the space. -pub trait Rotation, P: Point>: PartialEq + ApproxEq + Sized { +pub trait Rotation>: PartialEq + ApproxEq + Sized { /// Create the identity transform (causes no transformation). fn one() -> Self; /// Create a rotation to a given direction with an 'up' vector - fn look_at(dir: &V, up: &V) -> Self; + fn look_at(dir: &P::Vector, up: &P::Vector) -> Self; /// Create a shortest rotation to transform vector 'a' into 'b'. /// Both given vectors are assumed to have unit length. - fn between_vectors(a: &V, b: &V) -> Self; + fn between_vectors(a: &P::Vector, b: &P::Vector) -> Self; /// Rotate a vector using this rotation. - fn rotate_vector(&self, vec: &V) -> V; + fn rotate_vector(&self, vec: &P::Vector) -> P::Vector; /// Rotate a point using this rotation, by converting it to its /// representation as a vector. @@ -67,7 +67,7 @@ pub trait Rotation, P: Point>: PartialEq + Appr } /// A two-dimensional rotation. -pub trait Rotation2: Rotation, Point2> +pub trait Rotation2: Rotation> + Into> + Into> { /// Create a rotation by a given angle. Thus is a redundant case of both @@ -76,7 +76,7 @@ pub trait Rotation2: Rotation, Point2> } /// A three-dimensional rotation. -pub trait Rotation3: Rotation, Point3> +pub trait Rotation3: Rotation> + Into> + Into> + Into> { @@ -172,7 +172,7 @@ impl From> for Matrix2 { fn from(b: Basis2) -> Matrix2 { b.mat } } -impl Rotation, Point2> for Basis2 { +impl Rotation> for Basis2 { #[inline] fn one() -> Basis2 { Basis2 { mat: Matrix2::one() } } @@ -213,7 +213,7 @@ impl ApproxEq for Basis2 { } } -impl Rotation2 for Basis2 { +impl Rotation2 for Basis2 { fn from_angle(theta: Rad) -> Basis2 { Basis2 { mat: Matrix2::from_angle(theta) } } } @@ -248,12 +248,12 @@ impl From> for Matrix3 { fn from(b: Basis3) -> Matrix3 { b.mat } } -impl From> for Quaternion { +impl From> for Quaternion { #[inline] fn from(b: Basis3) -> Quaternion { b.mat.into() } } -impl Rotation, Point3> for Basis3 { +impl Rotation> for Basis3 { #[inline] fn one() -> Basis3 { Basis3 { mat: Matrix3::one() } } @@ -295,7 +295,7 @@ impl ApproxEq for Basis3 { } } -impl Rotation3 for Basis3 { +impl Rotation3 for Basis3 { fn from_axis_angle(axis: &Vector3, angle: Rad) -> Basis3 { Basis3 { mat: Matrix3::from_axis_angle(axis, angle) } } diff --git a/src/transform.rs b/src/transform.rs index 6560eb2..900df11 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -27,24 +27,24 @@ use vector::*; /// A trait representing an [affine /// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that /// can be applied to points or vectors. An affine transformation is one which -pub trait Transform, P: Point>: Sized { +pub trait Transform>: Sized { /// Create an identity transformation. That is, a transformation which /// does nothing. fn one() -> Self; /// Create a transformation that rotates a vector to look at `center` from /// `eye`, using `up` for orientation. - fn look_at(eye: &P, center: &P, up: &V) -> Self; + fn look_at(eye: &P, center: &P, up: &P::Vector) -> Self; /// Transform a vector using this transform. - fn transform_vector(&self, vec: &V) -> V; + fn transform_vector(&self, vec: &P::Vector) -> P::Vector; /// Transform a point using this transform. fn transform_point(&self, point: &P) -> P; /// Transform a vector as a point using this transform. #[inline] - fn transform_as_point(&self, vec: &V) -> V { + fn transform_as_point(&self, vec: &P::Vector) -> P::Vector { self.transform_point(&P::from_vec(vec)).to_vec() } @@ -78,23 +78,18 @@ pub struct Decomposed { pub disp: V, } -impl< - S: BaseFloat, - V: Vector, - P: Point, - R: Rotation, -> Transform for Decomposed { +impl, R: Rotation> Transform for Decomposed { #[inline] - fn one() -> Decomposed { + fn one() -> Decomposed { Decomposed { scale: S::one(), rot: R::one(), - disp: V::zero(), + disp: P::Vector::zero(), } } #[inline] - fn look_at(eye: &P, center: &P, up: &V) -> Decomposed { + fn look_at(eye: &P, center: &P, up: &P::Vector) -> Decomposed { let rot = R::look_at(¢er.sub_p(eye), up); let disp = rot.rotate_vector(&P::origin().sub_p(eye)); Decomposed { @@ -105,7 +100,7 @@ impl< } #[inline] - fn transform_vector(&self, vec: &V) -> V { + fn transform_vector(&self, vec: &P::Vector) -> P::Vector { self.rot.rotate_vector(&vec.mul_s(self.scale.clone())) } @@ -114,7 +109,7 @@ impl< self.rot.rotate_point(&point.mul_s(self.scale.clone())).add_v(&self.disp) } - fn concat(&self, other: &Decomposed) -> Decomposed { + fn concat(&self, other: &Decomposed) -> Decomposed { Decomposed { scale: self.scale * other.scale, rot: self.rot.concat(&other.rot), @@ -122,7 +117,7 @@ impl< } } - fn invert(&self) -> Option> { + fn invert(&self) -> Option> { if self.scale.approx_eq(&S::zero()) { None } else { @@ -138,13 +133,10 @@ impl< } } -pub trait Transform2: Transform, Point2> + Into> {} -pub trait Transform3: Transform, Point3> + Into> {} +pub trait Transform2: Transform> + Into> {} +pub trait Transform3: Transform> + Into> {} -impl< - S: BaseFloat + 'static, - R: Rotation2, -> From, R>> for Matrix3 { +impl> From, R>> for Matrix3 { fn from(dec: Decomposed, R>) -> Matrix3 { let m: Matrix2<_> = dec.rot.into(); let mut m: Matrix3<_> = m.mul_s(dec.scale).into(); @@ -153,10 +145,7 @@ impl< } } -impl< - S: BaseFloat + 'static, - R: Rotation3, -> From, R>> for Matrix4 { +impl> From, R>> for Matrix4 { fn from(dec: Decomposed, R>) -> Matrix4 { let m: Matrix3<_> = dec.rot.into(); let mut m: Matrix4<_> = m.mul_s(dec.scale).into(); @@ -165,20 +154,11 @@ impl< } } -impl< - S: BaseFloat + 'static, - R: Rotation2, -> Transform2 for Decomposed, R> {} +impl> Transform2 for Decomposed, R> {} -impl< - S: BaseFloat + 'static, - R: Rotation3, -> Transform3 for Decomposed, R> {} +impl> Transform3 for Decomposed, R> {} -impl< - S: BaseFloat, - R: fmt::Debug + Rotation3, -> fmt::Debug for Decomposed, R> { +impl> fmt::Debug for Decomposed, R> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "(scale({:?}), rot({:?}), disp{:?})", self.scale, self.rot, self.disp) @@ -191,7 +171,7 @@ pub struct AffineMatrix3 { pub mat: Matrix4, } -impl Transform, Point3> for AffineMatrix3 { +impl Transform> for AffineMatrix3 { #[inline] fn one() -> AffineMatrix3 { AffineMatrix3 { mat: Matrix4::one() } @@ -227,22 +207,22 @@ impl From> for Matrix4 { #[inline] fn from(aff: AffineMatrix3) -> Matrix4 { aff.mat } } -impl Transform3 for AffineMatrix3 {} +impl Transform3 for AffineMatrix3 {} /// A trait that allows extracting components (rotation, translation, scale) /// from an arbitrary transformations -pub trait ToComponents, P: Point, R: Rotation> { +pub trait ToComponents, R: Rotation> { /// Extract the (scale, rotation, translation) triple - fn decompose(&self) -> (V, R, V); + fn decompose(&self) -> (P::Vector, R, P::Vector); } pub trait ToComponents2>: - ToComponents, Point2, R> {} + ToComponents, R> {} pub trait ToComponents3>: - ToComponents, Point3, R> {} + ToComponents, R> {} -pub trait CompositeTransform, P: Point, R: Rotation>: - Transform + ToComponents {} +pub trait CompositeTransform, R: Rotation>: + Transform + ToComponents {} pub trait CompositeTransform2>: Transform2 + ToComponents2 {} pub trait CompositeTransform3>: @@ -250,31 +230,16 @@ pub trait CompositeTransform3>: impl< S: BaseFloat, - V: Vector + Clone, - P: Point, - R: Rotation + Clone, -> ToComponents for Decomposed { - fn decompose(&self) -> (V, R, V) { - (V::one().mul_s(self.scale), self.rot.clone(), self.disp.clone()) + P: Point, + R: Rotation + Clone, +> ToComponents for Decomposed { + fn decompose(&self) -> (P::Vector, R, P::Vector) { + (P::Vector::one().mul_s(self.scale), self.rot.clone(), self.disp.clone()) } } -impl< - S: BaseFloat, - R: Rotation2 + Clone, -> ToComponents2 for Decomposed, R> {} +impl + Clone> ToComponents2 for Decomposed, R> {} +impl + Clone> ToComponents3 for Decomposed, R> {} -impl< - S: BaseFloat, - R: Rotation3 + Clone, -> ToComponents3 for Decomposed, R> {} - -impl< - S: BaseFloat + 'static, - R: Rotation2 + Clone, -> CompositeTransform2 for Decomposed, R> {} - -impl< - S: BaseFloat + 'static, - R: Rotation3 + Clone, -> CompositeTransform3 for Decomposed, R> {} +impl + Clone> CompositeTransform2 for Decomposed, R> {} +impl + Clone> CompositeTransform3 for Decomposed, R> {}