1414
1515import math
1616import unittest
17- from gz .math8 import Line2d
18- from gz .math8 import Vector2d
17+ from gz .math8 import Line2d , Line2f , Line2i
18+ from gz .math8 import Vector2d , Vector2i
1919
2020
2121class TestLine2d (unittest .TestCase ):
@@ -35,6 +35,43 @@ def test_construction(self):
3535
3636 self .assertAlmostEqual (line_b [2 ].x (), line_b [1 ].x ())
3737
38+ # Test set method with Vector2d
39+ line_a .set (Vector2d (5 , 6 ), Vector2d (7 , 8 ))
40+ self .assertEqual (line_a [0 ], Vector2d (5 , 6 ))
41+ self .assertEqual (line_a [1 ], Vector2d (7 , 8 ))
42+
43+ def test_cross_product (self ):
44+ line_a = Line2d (0 , 0 , 10 , 0 )
45+ line_b = Line2d (0 , 0 , 0 , 10 )
46+ self .assertAlmostEqual (line_a .cross_product (line_b ), 100.0 )
47+
48+ pt = Vector2d (5 , 5 )
49+ self .assertAlmostEqual (line_a .cross_product (pt ), 50.0 )
50+
51+ def test_on_segment_and_within (self ):
52+ line = Line2d (0 , 0 , 10 , 10 )
53+
54+ # Point on segment
55+ pt1 = Vector2d (5 , 5 )
56+ self .assertTrue (line .within (pt1 , 1e-6 ))
57+ self .assertTrue (line .on_segment (pt1 , 1e-6 ))
58+
59+ # Point collinear with line, but outside segment bounds
60+ pt2 = Vector2d (15 , 15 )
61+ self .assertFalse (line .within (pt2 , 1e-6 ))
62+ self .assertFalse (line .on_segment (pt2 , 1e-6 ))
63+
64+ # Point within bounding box of segment, but not collinear
65+ pt3 = Vector2d (5 , 6 )
66+ self .assertTrue (line .within (pt3 , 1e-6 ))
67+ self .assertFalse (line .on_segment (pt3 , 1e-6 ))
68+
69+ # Endpoints
70+ self .assertTrue (line .within (line [0 ], 1e-6 ))
71+ self .assertTrue (line .on_segment (line [0 ], 1e-6 ))
72+ self .assertTrue (line .within (line [1 ], 1e-6 ))
73+ self .assertTrue (line .on_segment (line [1 ], 1e-6 ))
74+
3875 def test_length (self ):
3976 line_a = Line2d (0 , 0 , 10 , 10 )
4077 self .assertAlmostEqual (line_a .length (), math .sqrt (200 ), delta = 1e-10 )
@@ -53,26 +90,31 @@ def test_parallel_line(self):
5390 # Line is always parallel with itself
5491 line = Line2d (0 , 0 , 10 , 0 )
5592 self .assertTrue (line .parallel (line , 1e-10 ))
93+ self .assertAlmostEqual (line .cross_product (line ), 0.0 )
5694
5795 # Degenerate line segment
5896 # Still expect Line is parallel with itself
5997 line = Line2d (0 , 0 , 0 , 0 )
6098 self .assertTrue (line .parallel (line , 1e-10 ))
99+ self .assertAlmostEqual (line .cross_product (line ), 0.0 )
61100
62101 line_a = Line2d (0 , 0 , 10 , 0 )
63102 line_b = Line2d (0 , 0 , 10 , 0 )
64103 self .assertTrue (line_a .parallel (line_b , 1e-10 ))
104+ self .assertAlmostEqual (line_a .cross_product (line_b ), 0.0 )
65105
66106 line_b .set (0 , 0 , 0 , 10 )
67107 self .assertFalse (line_a .parallel (line_b ))
68108
69109 line_b .set (0 , 10 , 10 , 10 )
70110 self .assertTrue (line_a .parallel (line_b ))
111+ self .assertAlmostEqual (line_a .cross_product (line_b ), 0.0 )
71112
72113 line_b .set (0 , 10 , 10 , 10.00001 )
73114 self .assertFalse (line_a .parallel (line_b , 1e-10 ))
74115 self .assertFalse (line_a .parallel (line_b ))
75116 self .assertTrue (line_a .parallel (line_b , 1e-3 ))
117+ self .assertAlmostEqual (line_a .cross_product (line_b ), 0.0 , delta = 1e-3 )
76118
77119 def test_collinear_line (self ):
78120 # Line is always collinear with itself
@@ -187,12 +229,36 @@ def test_intersect(self):
187229 self .assertTrue (line_a .intersect (line_b , pt ))
188230 self .assertEqual (pt , Vector2d (5 , 5 ))
189231
232+ # Collinear parallel non-overlapping lines
233+ line_a .set (0 , 0 , 10 , 0 )
234+ line_b .set (20 , 0 , 30 , 0 )
235+ self .assertFalse (line_a .intersect (line_b , pt ))
236+ self .assertFalse (line_a .intersect (line_b ))
237+
238+ # Collinear lines where line_b end point is within line_a but start point is not
239+ line_a .set (0 , 0 , 10 , 0 )
240+ line_b .set (- 5 , 0 , 5 , 0 )
241+ self .assertTrue (line_a .intersect (line_b , pt ))
242+ self .assertEqual (pt , Vector2d (5 , 0 ))
243+
244+ # Lines whose extensions intersect, but intersection Y is outside bounds
245+ line_a .set (- 10 , 0 , 10 , 0 )
246+ line_b .set (0 , 2 , 0 , 10 )
247+ self .assertFalse (line_a .intersect (line_b , pt ))
248+
249+ # Lines whose extensions intersect, but intersection X is outside bounds
250+ line_a .set (0 , - 10 , 0 , 10 )
251+ line_b .set (2 , 0 , 10 , 0 )
252+ self .assertFalse (line_a .intersect (line_b , pt ))
253+
190254 def test_equality (self ):
191255 line_a = Line2d (1 , 1 , 2 , 1 )
192256 line_b = Line2d (1 , 2 , 2 , 2 )
193257
194258 self .assertTrue (line_a != line_b )
259+ self .assertFalse (line_a == line_b )
195260 self .assertTrue (line_a == line_a )
261+ self .assertFalse (line_a != line_a )
196262
197263 line_b .set (1 , 1 , 2 , 1.1 )
198264 self .assertFalse (line_a == line_b )
@@ -210,6 +276,18 @@ def test_serialization(self):
210276 line = Line2d (0 , 1 , 2 , 3 )
211277 self .assertEqual (str (line ), "0 1 2 3" )
212278
279+ def test_template_types (self ):
280+ line_i = Line2i (0 , 0 , 10 , 10 )
281+ self .assertEqual (line_i [0 ], Vector2i (0 , 0 ))
282+ self .assertEqual (line_i [1 ], Vector2i (10 , 10 ))
283+ self .assertEqual (line_i .length (), 14 )
284+
285+ line_f = Line2f (0.0 , 0.0 , 10.0 , 10.0 )
286+ self .assertAlmostEqual (line_f [0 ].x (), 0.0 )
287+ self .assertAlmostEqual (line_f [1 ].y (), 10.0 )
288+ self .assertAlmostEqual (line_f .length (), 14.1421356 , delta = 1e-4 )
289+
213290
214291if __name__ == '__main__' :
215292 unittest .main ()
293+
0 commit comments