fix: use mid-point to determine arc direction instead of clockwise flag
The clockwise flag from NX extractor can be inverted depending on face normal orientation. The sampled mid-point is always reliable. Now _arc_angles checks which direction (CW vs CCW) passes through the mid-point and uses that.
This commit is contained in:
@@ -16,6 +16,39 @@ def _arc_angles(seg: Dict[str, Any]):
|
||||
ex, ey = seg["end"]
|
||||
a0 = math.atan2(sy - cy, sx - cx)
|
||||
a1 = math.atan2(ey - cy, ex - cx)
|
||||
|
||||
# If a midpoint is available, use it to determine the correct arc direction
|
||||
# (more reliable than the clockwise flag, which can be inverted by face normal orientation)
|
||||
mid = seg.get("mid")
|
||||
if mid is not None:
|
||||
mx, my = float(mid[0]), float(mid[1])
|
||||
a_mid = math.atan2(my - cy, mx - cx)
|
||||
|
||||
# Try CCW direction (a1 > a0)
|
||||
a1_ccw = a1
|
||||
if a1_ccw < a0:
|
||||
a1_ccw += 2.0 * math.pi
|
||||
# Check if mid angle falls within CCW sweep
|
||||
a_mid_ccw = a_mid
|
||||
if a_mid_ccw < a0:
|
||||
a_mid_ccw += 2.0 * math.pi
|
||||
ccw_ok = (a0 <= a_mid_ccw <= a1_ccw)
|
||||
|
||||
# Try CW direction (a1 < a0)
|
||||
a1_cw = a1
|
||||
if a1_cw > a0:
|
||||
a1_cw -= 2.0 * math.pi
|
||||
a_mid_cw = a_mid
|
||||
if a_mid_cw > a0:
|
||||
a_mid_cw -= 2.0 * math.pi
|
||||
cw_ok = (a1_cw <= a_mid_cw <= a0)
|
||||
|
||||
if ccw_ok and not cw_ok:
|
||||
return a0, a1_ccw
|
||||
elif cw_ok and not ccw_ok:
|
||||
return a0, a1_cw
|
||||
# If both or neither match, fall through to clockwise flag
|
||||
|
||||
cw = bool(seg.get("clockwise", False))
|
||||
if cw:
|
||||
if a1 > a0:
|
||||
|
||||
Reference in New Issue
Block a user