Skip to content

Commit 8d318bc

Browse files
committed
Refactor _bez_ccx3.py to enhance pruning logic, optimize tolerances, and improve data splitting routines:
- Adjust pruning conditions for better isolated point detection. - Introduce additional control point display utility. - Refine input tolerances with squared values for clearer logic. - Simplify and improve subdivision and evaluation logic.
1 parent e2f5d39 commit 8d318bc

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

mmcore/numeric/intersection/ccx/_bez_ccx3.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

11301131
def 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+
11371140
def 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

Comments
 (0)