diff --git a/Cargo.toml b/Cargo.toml index 5a94a237..f73f34ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "euclid" -version = "0.11.1" +version = "0.11.2" authors = ["The Servo Project Developers"] description = "Geometry primitives" documentation = "https://docs.rs/euclid/" diff --git a/src/point.rs b/src/point.rs index 285b5aa8..8e6986a4 100644 --- a/src/point.rs +++ b/src/point.rs @@ -110,6 +110,16 @@ where T: Copy + Mul + Add + Sub { pub fn cross(self, other: TypedPoint2D) -> T { self.x * other.y - self.y * other.x } + + #[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() + } + } } impl, U> Add for TypedPoint2D { @@ -386,6 +396,16 @@ impl + self.z * other.x - self.x * other.z, self.x * other.y - self.y * other.x) } + + #[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() + } + } } impl, U> Add for TypedPoint3D { @@ -414,6 +434,22 @@ impl , U> Neg for TypedPoint3D { } } +impl, U> Mul for TypedPoint3D { + type Output = Self; + #[inline] + fn mul(self, scale: T) -> Self { + Self::new(self.x * scale, self.y * scale, self.z * scale) + } +} + +impl, U> Div for TypedPoint3D { + type Output = Self; + #[inline] + fn div(self, scale: T) -> Self { + Self::new(self.x / scale, self.y / scale, self.z / scale) + } +} + impl TypedPoint3D { pub fn min(self, other: TypedPoint3D) -> TypedPoint3D { TypedPoint3D::new(self.x.min(other.x), @@ -800,6 +836,16 @@ mod point2d { assert_eq!(r, -59.0); } + #[test] + pub fn test_normalize() { + let p0: Point2D = Point2D::zero(); + let p1: Point2D = Point2D::new(4.0, 0.0); + let p2: Point2D = Point2D::new(3.0, -4.0); + assert_eq!(p0.normalize(), p0); + assert_eq!(p1.normalize(), Point2D::new(1.0, 0.0)); + assert_eq!(p2.normalize(), Point2D::new(0.6, -0.8)); + } + #[test] pub fn test_min() { let p1 = Point2D::new(1.0, 3.0); @@ -872,6 +918,16 @@ mod point3d { assert_eq!(p3, Point3D::new(-51.0, 105.0, -59.0)); } + #[test] + pub fn test_normalize() { + let p0: Point3D = Point3D::zero(); + let p1: Point3D = Point3D::new(0.0, -6.0, 0.0); + let p2: Point3D = Point3D::new(1.0, 2.0, -2.0); + assert_eq!(p0.normalize(), p0); + assert_eq!(p1.normalize(), Point3D::new(0.0, -1.0, 0.0)); + assert_eq!(p2.normalize(), Point3D::new(1.0/3.0, 2.0/3.0, -2.0/3.0)); + } + #[test] pub fn test_min() { let p1 = Point3D::new(1.0, 3.0, 5.0);