@@ -800,8 +800,9 @@ def contact_detect_and_extract(C1, C2, seed_uv=(0.5, 0.5), envelope_prune=None,
800800
801801 # Try to land on G=0
802802 u0 , v0 = seed_uv
803- u , v , G , J = newton_project_G0 (C1 , C2 , u0 , v0 , tol = 1e-12 , rational = rational )
803+ u , v , G , J = newton_project_G0 (C1 , C2 , u0 , v0 , tol = 1e-12 ,it = 5 , rational = rational )
804804 if np .linalg .norm (G ) > 1e-8 :
805+
805806 return {"type" : "none" }
806807
807808 cls = classify_contact (J , sv_thresh )
@@ -1129,11 +1130,13 @@ def subdivide_u(dist_net, su_net, sv_net, u: float):
11291130
11301131def subdivide_v (dist_net , su_net , sv_net , v : float ):
11311132 left , right = zip (
1132- de_casteljau_split_nd (dist_net , axis = 1 , t = v ), de_casteljau_split_nd (su_net , axis = 1 , t = v ), de_casteljau_split_nd (sv_net , axis = 1 , t = v )
1133+ de_casteljau_split_nd (dist_net , axis = 1 , t = v ), de_casteljau_split_nd (su_net , axis = 1 , t = v ),
1134+ de_casteljau_split_nd (sv_net , axis = 1 , t = v )
11331135 )
11341136 return left , right
11351137
11361138
1139+
11371140def bern_restrict_face (ctrl , axis , which ):
11381141 """
11391142 Restrict tensor Bernstein grid to a parameter face.
@@ -1336,7 +1339,7 @@ def bezier_intersect_certified_full(C1: NDArray, C2: NDArray, sv_thresh: float
13361339 atol_sq = atol ** 2
13371340 result = None
13381341
1339- sq_dist_net = distance_squared_net (C1 , C2 , rational = rational )[...,np .newaxis ]
1342+ sq_dist_net = distance_squared_net (C1 , C2 , rational = rational )[...,np .newaxis ]- atol_sq
13401343 tol_c1 = _bez_get_tol_adapter (C1 , atol , rational = rational )
13411344 tol_c2 = _bez_get_tol_adapter (C2 , atol , rational = rational )
13421345 su_net = bernstein_partial_derivative_coeffs (sq_dist_net , 0 )
@@ -1368,8 +1371,7 @@ def cell_contains_known_isolated(u0, u1, v0, v1, margin=1e-9):
13681371 if scale == 0 :
13691372 scale = 1.0
13701373
1371- root_tol = 1e-9 * scale # or 1e-10 * scale, tweak as you like
1372- root_tol_sq = root_tol * root_tol
1374+
13731375 while stack :
13741376 Pseg , Qseg , dnet , sunet , svnet , u0 , u1 , v0 , v1 , depth = stack .pop ()
13751377 stats ["cells" ] += 1
@@ -1523,12 +1525,12 @@ def cell_contains_known_isolated(u0, u1, v0, v1, margin=1e-9):
15231525 #if not bernstein_eval_nd(dnet, (ug, vg)) < atol_sq:
15241526 # continue
15251527 #print(ug,vg)
1526- x = eval_bezier ( C1 , ug , rational = rational )
1528+ x = res [ 'point' ]
15271529
15281530 if is_strictly_inside ((ug , vg , ug , vg ), (u0 , v0 , u1 , v1 )):
15291531 if not near_existing_isolated (ug , vg , x ):
15301532 #print(Pseg.tolist(), Qseg.tolist(), )
1531- if not bernstein_eval_nd (dnet , (uc , vc )) < atol_sq :
1533+ if not bernstein_eval_nd (dnet , (uc , vc )). min () < atol_sq :
15321534 continue
15331535
15341536 isolated .append ({"u" : ug , "v" : vg , "point" : x })
@@ -1550,7 +1552,7 @@ def cell_contains_known_isolated(u0, u1, v0, v1, margin=1e-9):
15501552 abs (vc - 0 ) <= _tol_c2 or abs (1 - vc ) <= _tol_c2 )):
15511553 if not near_existing_isolated (ug , vg , x ):
15521554 print ('LLLLL' )
1553- if bernstein_eval_nd (dnet , (uc , vc )) < atol_sq :
1555+ if bernstein_eval_nd (dnet , (uc , vc )). min () < atol_sq :
15541556
15551557
15561558 kk = np .array ((abs (uc - 0 ) < _tol_c1 , abs (1 - uc ) < tol_c1 , abs (vc - 0 ) <= _tol_c2 , abs (1 - vc ) <= _tol_c2 ),bool )
@@ -1576,7 +1578,7 @@ def cell_contains_known_isolated(u0, u1, v0, v1, margin=1e-9):
15761578 u1g , v1g = map_local_to_global (u_1 , v_1 , u0 , u1 , v0 , v1 )
15771579 stack .append ((_p , _q , subpatch , sub_sunet , sub_svnet , u0g , u1g , v0g , v1g , depth + 1 ))
15781580 print ( (u0g , v0g ),(u1g ,v1g ))
1579- continue
1581+ continue
15801582
15811583
15821584
@@ -1702,6 +1704,25 @@ def make_rich_table(inter1, inter2, *args,**kwargs):
17021704 print ('Pretty output requires "pip install rich"' )
17031705 print ("verify with OCC (mmcore result, occ result):" , inter1 ["isolated" ], inter2 ["isolated" ])
17041706 np .set_printoptions (edgeitems = 3 )
1707+
1708+
1709+ def _gen_cpts_to_display (scalar_net , interval : list [tuple [float , float ]] = None ):
1710+ def get_interv (n ) -> tuple [float , float ]:
1711+ if interval is None :
1712+ return (0. , 1. )
1713+ else :
1714+ return interval [n ]
1715+
1716+ Pts = np .zeros ((* scalar_net .shape , scalar_net .ndim + 1 ))
1717+
1718+ mgr = np .mgrid [* (slice (* get_interv (i ), complex (scalar_net .shape [i ])) for i in range (scalar_net .ndim ))]
1719+
1720+ Pts [..., - 1 ] = scalar_net
1721+ Pts [..., :- 1 ] = np .moveaxis (mgr , 0 , - 1 )
1722+
1723+ return Pts
1724+
1725+
17051726 curve1 = np .array (
17061727 [
17071728 [- 19.77608536 , 23.10065701 , 0.0 ],
@@ -1737,6 +1758,7 @@ def make_rich_table(inter1, inter2, *args,**kwargs):
17371758 )
17381759 curve6 = np .array ([[- 13.12449258 , 9.10030377 , 0.0 ], [- 27.74989311 , 10.37986052 , 0.0 ], [- 29.02944985 , - 4.24554001 , 0.0 ]])
17391760
1761+
17401762 # case 1: One true overlap, no isolated points
17411763 s = time .perf_counter ()
17421764 inter12 = bezier_intersect_certified_full (curve1 , curve2 )
0 commit comments