From 7eed120c277900b53dc15842e008f682def0972d Mon Sep 17 00:00:00 2001 From: PizzaIter Date: Sat, 13 Jan 2018 18:08:07 +0100 Subject: [PATCH 1/4] Remove divide by zero checks from normalize() --- src/vector.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/vector.rs b/src/vector.rs index 6bdef1a..981a3cf 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -152,12 +152,7 @@ where T: Copy + Mul + Add + Sub { #[inline] pub fn normalize(self) -> Self where T: Float + ApproxEq { - let dot = self.dot(self); - if dot.approx_eq(&T::zero()) { - self - } else { - self / dot.sqrt() - } + self / self.length() } #[inline] @@ -548,12 +543,7 @@ impl + #[inline] pub fn normalize(self) -> Self where T: Float + ApproxEq { - let dot = self.dot(self); - if dot.approx_eq(&T::zero()) { - self - } else { - self / dot.sqrt() - } + self / self.length() } #[inline] From 6f6b5283442b7be0d5585c7019753ffbd778f2a3 Mon Sep 17 00:00:00 2001 From: PizzaIter Date: Sat, 13 Jan 2018 18:20:34 +0100 Subject: [PATCH 2/4] Fix tests --- src/vector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vector.rs b/src/vector.rs index 981a3cf..e78a632 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -829,7 +829,7 @@ mod vector2d { let p0: Vec2 = Vec2::zero(); let p1: Vec2 = vec2(4.0, 0.0); let p2: Vec2 = vec2(3.0, -4.0); - assert_eq!(p0.normalize(), p0); + assert!(p0.normalize().x.is_nan() && p0.normalize().y.is_nan()); assert_eq!(p1.normalize(), vec2(1.0, 0.0)); assert_eq!(p2.normalize(), vec2(0.6, -0.8)); } @@ -940,7 +940,7 @@ mod vector3d { let p0: Vec3 = Vec3::zero(); let p1: Vec3 = vec3(0.0, -6.0, 0.0); let p2: Vec3 = vec3(1.0, 2.0, -2.0); - assert_eq!(p0.normalize(), p0); + assert!(p0.normalize().x.is_nan() && p0.normalize().y.is_nan() && p0.normalize().z.is_nan()); assert_eq!(p1.normalize(), vec3(0.0, -1.0, 0.0)); assert_eq!(p2.normalize(), vec3(1.0/3.0, 2.0/3.0, -2.0/3.0)); } From 22143331f97065499eae5a187623c54556d2cd9f Mon Sep 17 00:00:00 2001 From: PizzaIter Date: Sat, 13 Jan 2018 18:21:43 +0100 Subject: [PATCH 3/4] Remove unnecessary ApproxEq bounds --- src/rotation.rs | 49 ++++++++++++++++++++++++++++++++++++++----------- src/vector.rs | 6 +++--- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/rotation.rs b/src/rotation.rs index e25af1b..0c33a43 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -216,7 +216,6 @@ where T: Copy + Clone + Mul + Div + Neg + - ApproxEq + PartialOrd + Float + One + Zero @@ -330,7 +329,8 @@ impl TypedRotation3D where T: Copy { } impl TypedRotation3D -where T: Float + ApproxEq +where + T: Float, { /// Creates the identity rotation. #[inline] @@ -428,7 +428,10 @@ where T: Float + ApproxEq } #[inline] - pub fn is_normalized(&self) -> bool { + pub fn is_normalized(&self) -> bool + where + T: ApproxEq, + { // TODO: we might need to relax the threshold here, because of floating point imprecision. self.square_norm().approx_eq(&T::one()) } @@ -436,7 +439,10 @@ where T: Float + ApproxEq /// Spherical linear interpolation between this rotation and another rotation. /// /// `t` is expected to be between zero and one. - pub fn slerp(&self, other: &Self, t: T) -> Self { + pub fn slerp(&self, other: &Self, t: T) -> Self + where + T: ApproxEq, + { debug_assert!(self.is_normalized()); debug_assert!(other.is_normalized()); @@ -484,7 +490,10 @@ where T: Float + ApproxEq /// Returns the given 3d point transformed by this rotation. /// /// The input point must be use the unit Src, and the returned point has the unit Dst. - pub fn rotate_point3d(&self, point: &TypedPoint3D) -> TypedPoint3D { + pub fn rotate_point3d(&self, point: &TypedPoint3D) -> TypedPoint3D + where + T: ApproxEq, + { debug_assert!(self.is_normalized()); let two = T::one() + T::one(); @@ -501,7 +510,10 @@ where T: Float + ApproxEq /// /// The input point must be use the unit Src, and the returned point has the unit Dst. #[inline] - pub fn rotate_point2d(&self, point: &TypedPoint2D) -> TypedPoint2D { + pub fn rotate_point2d(&self, point: &TypedPoint2D) -> TypedPoint2D + where + T: ApproxEq, + { self.rotate_point3d(&point.to_3d()).xy() } @@ -509,7 +521,10 @@ where T: Float + ApproxEq /// /// The input vector must be use the unit Src, and the returned point has the unit Dst. #[inline] - pub fn rotate_vector3d(&self, vector: &TypedVector3D) -> TypedVector3D { + pub fn rotate_vector3d(&self, vector: &TypedVector3D) -> TypedVector3D + where + T: ApproxEq, + { self.rotate_point3d(&vector.to_point()).to_vector() } @@ -517,13 +532,19 @@ where T: Float + ApproxEq /// /// The input vector must be use the unit Src, and the returned point has the unit Dst. #[inline] - pub fn rotate_vector2d(&self, vector: &TypedVector2D) -> TypedVector2D { + pub fn rotate_vector2d(&self, vector: &TypedVector2D) -> TypedVector2D + where + T: ApproxEq, + { self.rotate_vector3d(&vector.to_3d()).xy() } /// Returns the matrix representation of this rotation. #[inline] - pub fn to_transform(&self) -> TypedTransform3D { + pub fn to_transform(&self) -> TypedTransform3D + where + T: ApproxEq, + { debug_assert!(self.is_normalized()); let i2 = self.i + self.i; @@ -563,7 +584,10 @@ where T: Float + ApproxEq } /// Returns a rotation representing the other rotation followed by this rotation. - pub fn pre_rotate(&self, other: &TypedRotation3D) -> TypedRotation3D { + pub fn pre_rotate(&self, other: &TypedRotation3D) -> TypedRotation3D + where + T: ApproxEq, + { debug_assert!(self.is_normalized()); TypedRotation3D::quaternion( self.i * other.r + self.r * other.i + self.j * other.k - self.k * other.j, @@ -575,7 +599,10 @@ where T: Float + ApproxEq /// Returns a rotation representing this rotation followed by the other rotation. #[inline] - pub fn post_rotate(&self, other: &TypedRotation3D) -> TypedRotation3D { + pub fn post_rotate(&self, other: &TypedRotation3D) -> TypedRotation3D + where + T: ApproxEq, + { other.pre_rotate(self) } diff --git a/src/vector.rs b/src/vector.rs index e78a632..473001c 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -151,7 +151,7 @@ where T: Copy + Mul + Add + Sub { } #[inline] - pub fn normalize(self) -> Self where T: Float + ApproxEq { + pub fn normalize(self) -> Self where T: Float { self / self.length() } @@ -542,7 +542,7 @@ impl + } #[inline] - pub fn normalize(self) -> Self where T: Float + ApproxEq { + pub fn normalize(self) -> Self where T: Float { self / self.length() } @@ -552,7 +552,7 @@ impl + } #[inline] - pub fn length(&self) -> T where T: Float + ApproxEq { + pub fn length(&self) -> T where T: Float { self.square_length().sqrt() } } From 2b819e8ca689f578a331e44a4ed9ef30b0a1a473 Mon Sep 17 00:00:00 2001 From: PizzaIter Date: Sat, 13 Jan 2018 22:52:16 +0100 Subject: [PATCH 4/4] Bump version to 0.16.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 315da3f..aa677df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "euclid" -version = "0.16.1" +version = "0.16.2" authors = ["The Servo Project Developers"] description = "Geometry primitives" documentation = "https://docs.rs/euclid/"