@@ -273,6 +273,83 @@ def test_path_deepcopy():
273273 copy .deepcopy (path2 )
274274
275275
276+ def test_path_intersect_path ():
277+ # test for the range of intersection angles
278+ base_angles = np .array ([0 , 15 , 30 , 45 , 60 , 75 , 90 , 105 , 120 , 135 ])
279+ angles = np .concatenate ([base_angles , base_angles + 1 , base_angles - 1 ])
280+ eps_array = [1e-5 , 1e-8 , 1e-10 , 1e-12 ]
281+
282+ for phi in angles :
283+
284+ transform = transforms .Affine2D ().rotate (np .deg2rad (phi ))
285+
286+ # a and b intersect at angle phi
287+ a = Path ([(- 2 , 0 ), (2 , 0 )])
288+ b = transform .transform_path (a )
289+ assert a .intersects_path (b ) and b .intersects_path (a )
290+
291+ # a and b touch at angle phi at (0, 0)
292+ a = Path ([(0 , 0 ), (2 , 0 )])
293+ b = transform .transform_path (a )
294+ assert a .intersects_path (b ) and b .intersects_path (a )
295+
296+ # a and b are orthogonal and intersect at (0, 3)
297+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 3 )]))
298+ b = transform .transform_path (Path ([(1 , 3 ), (0 , 3 )]))
299+ assert a .intersects_path (b ) and b .intersects_path (a )
300+
301+ # a and b are collinear and intersect at (0, 3)
302+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 3 )]))
303+ b = transform .transform_path (Path ([(0 , 5 ), (0 , 3 )]))
304+ assert a .intersects_path (b ) and b .intersects_path (a )
305+
306+ # self-intersect
307+ assert a .intersects_path (a )
308+
309+ # a contains b
310+ a = transform .transform_path (Path ([(0 , 0 ), (5 , 5 )]))
311+ b = transform .transform_path (Path ([(1 , 1 ), (3 , 3 )]))
312+ assert a .intersects_path (b ) and b .intersects_path (a )
313+
314+ # a and b are collinear but do not intersect
315+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
316+ b = transform .transform_path (Path ([(3 , 0 ), (3 , 3 )]))
317+ assert not a .intersects_path (b ) and not b .intersects_path (a )
318+
319+ # a and b are on the same line but do not intersect
320+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
321+ b = transform .transform_path (Path ([(0 , 6 ), (0 , 7 )]))
322+ assert not a .intersects_path (b ) and not b .intersects_path (a )
323+
324+ # Note: 1e-13 is the absolute tolerance error used for
325+ # `isclose` function from src/_path.h
326+
327+ # a and b are parallel but do not touch
328+ for eps in eps_array :
329+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
330+ b = transform .transform_path (Path ([(0 + eps , 1 ), (0 + eps , 5 )]))
331+ assert not a .intersects_path (b ) and not b .intersects_path (a )
332+
333+ # a and b are on the same line but do not intersect (really close)
334+ for eps in eps_array :
335+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
336+ b = transform .transform_path (Path ([(0 , 5 + eps ), (0 , 7 )]))
337+ assert not a .intersects_path (b ) and not b .intersects_path (a )
338+
339+ # a and b are on the same line and intersect (really close)
340+ for eps in eps_array :
341+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
342+ b = transform .transform_path (Path ([(0 , 5 - eps ), (0 , 7 )]))
343+ assert a .intersects_path (b ) and b .intersects_path (a )
344+
345+ # b is the same as a but with an extra point
346+ a = transform .transform_path (Path ([(0 , 1 ), (0 , 5 )]))
347+ b = transform .transform_path (Path ([(0 , 1 ), (0 , 2 ), (0 , 5 )]))
348+ assert a .intersects_path (b ) and b .intersects_path (a )
349+
350+ return
351+
352+
276353@pytest .mark .parametrize ('offset' , range (- 720 , 361 , 45 ))
277354def test_full_arc (offset ):
278355 low = offset
0 commit comments