@@ -273,6 +273,83 @@ def test_path_deepcopy():
273
273
copy .deepcopy (path2 )
274
274
275
275
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
+
276
353
@pytest .mark .parametrize ('offset' , range (- 720 , 361 , 45 ))
277
354
def test_full_arc (offset ):
278
355
low = offset
0 commit comments