From 0f038d58b469760cd707490b6954574274be01be Mon Sep 17 00:00:00 2001
From: jnyfah <jnyfaah@gmail.com>
Date: Sat, 9 Nov 2024 16:20:00 +0100
Subject: [PATCH] Implement From<Point<T>> for Vector<T>

---
 src/geometry/point_conversion.rs | 27 +++++++++++++++++------
 tests/geometry/point.rs          | 38 +++++++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/src/geometry/point_conversion.rs b/src/geometry/point_conversion.rs
index ac723c6bf..f7c39fec9 100644
--- a/src/geometry/point_conversion.rs
+++ b/src/geometry/point_conversion.rs
@@ -6,8 +6,8 @@ use crate::base::allocator::Allocator;
 use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
 use crate::base::{Const, DefaultAllocator, Matrix, OVector, Scalar};
 
-use crate::geometry::Point;
-use crate::{DimName, OPoint};
+use crate::geometry::{Point, Point2, Point3};
+use crate::{DimName, OPoint, Vector3, Vector4};
 
 /*
  * This file provides the following conversions:
@@ -70,14 +70,27 @@ where
     }
 }
 
-impl<T: Scalar + Zero + One, D: DimName> From<OPoint<T, D>> for OVector<T, DimNameSum<D, U1>>
+impl<T: Scalar + Zero + One> From<Point2<T>> for Vector3<T> {
+    #[inline]
+    fn from(p: Point2<T>) -> Self {
+        p.to_homogeneous()
+    }
+}
+
+impl<T: Scalar + Zero + One> From<Point3<T>> for Vector4<T> {
+    #[inline]
+    fn from(p: Point3<T>) -> Self {
+        p.to_homogeneous()
+    }
+}
+
+impl<T: Scalar, D: DimName> From<OPoint<T, D>> for OVector<T, D>
 where
-    D: DimNameAdd<U1>,
-    DefaultAllocator: Allocator<DimNameSum<D, U1>> + Allocator<D>,
+    DefaultAllocator: Allocator<D>,
 {
     #[inline]
-    fn from(t: OPoint<T, D>) -> Self {
-        t.to_homogeneous()
+    fn from(p: OPoint<T, D>) -> Self {
+        p.coords
     }
 }
 
diff --git a/tests/geometry/point.rs b/tests/geometry/point.rs
index 42adf118e..29910ac68 100644
--- a/tests/geometry/point.rs
+++ b/tests/geometry/point.rs
@@ -1,4 +1,4 @@
-use na::{Point3, Vector3, Vector4};
+use na::{Point2, Point3, Point4, Vector2, Vector3, Vector4};
 use num::Zero;
 
 #[test]
@@ -100,3 +100,39 @@ fn display_fmt_respects_modifiers() {
     assert_eq!(&format!("{p:.1}"), "{1.2, 3.5, 5.7}");
     assert_eq!(&format!("{p:.0}"), "{1, 3, 6}");
 }
+
+#[test]
+fn homogeneous_conversions() {
+    // 2D -> 3D homogeneous conversion
+    let p = Point2::new(1.0, 2.0);
+    let expected = Vector3::new(1.0, 2.0, 1.0);
+    let v1: Vector3<f64> = p.into();
+    assert_eq!(v1, expected);
+
+    // 3D -> 4D homogeneous conversion
+    let p = Point3::new(1.0, 2.0, 3.0);
+    let expected = Vector4::new(1.0, 2.0, 3.0, 1.0);
+    let v1: Vector4<f64> = p.into();
+    assert_eq!(v1, expected);
+}
+
+#[test]
+fn dimension_preserving_conversions() {
+    // 2D point -> 2D vector
+    let p = Point2::new(1.0, 2.0);
+    let expected = Vector2::new(1.0, 2.0);
+    let v1: Vector2<f64> = p.into();
+    assert_eq!(v1, expected);
+
+    // 3D point -> 3D vector
+    let p = Point3::new(1.0, 2.0, 3.0);
+    let expected = Vector3::new(1.0, 2.0, 3.0);
+    let v1: Vector3<f64> = p.into();
+    assert_eq!(v1, expected);
+
+    // 4D point -> 4D vector
+    let p = Point4::new(1.0, 2.0, 3.0, 4.0);
+    let expected = Vector4::new(1.0, 2.0, 3.0, 4.0);
+    let v1: Vector4<f64> = p.into();
+    assert_eq!(v1, expected);
+}