Arc angle in DXF file

276 views
Skip to first unread message

Massimiliano Zecchetto

unread,
Dec 21, 2020, 8:57:03 AM12/21/20
to python-ezdxf
Dear all,
I am trying to calculate the angle of an arc using ezdxf. It should be as simple as:
    abs(arc.dxf.start_angle - arc.dxf.end_angle) 
However I am having troubles in one simple case, when the start angle is equal to 360°.

For instance, in this case I get an angle of about 323° when it should be about 36°.
I am really struggling in find a way to manage this exception case, but to date I was not able to find any valid, effective workaround.

Any hints?

With best regards,

Massimiliano 

Manfred Moitzi

unread,
Dec 21, 2020, 2:04:58 PM12/21/20
to Massimiliano Zecchetto, python-ezdxf
A simple solution:

        end = arc.dxf.end_angle
        while end < arc.dxf.start_angle:
            end += 360
        angle_span = end - arc.dxf.start_angle

I am using a while loop, because the modulo operator (angle % 360) for angle normalization has a problem for start/end angle = (0, 360), (360 % 360) - 0 == 0.

--
You received this message because you are subscribed to the Google Groups "python-ezdxf" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-ezdxf...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python-ezdxf/c1843abd-6779-493c-804c-be4b2f9aa29dn%40googlegroups.com.

Manfred Moitzi

unread,
Dec 22, 2020, 3:14:21 AM12/22/20
to Massimiliano Zecchetto, python-ezdxf
Added a new helper function for this problem, because my previous solution was not correct for all cases:

def arc_angle_span_deg(start: float, end: float) -> float:
""" Returns the counter clockwise angle from `start` to `end` in degrees.
"""
# start == end is 0 by definition:
if math.isclose(start, end):
return 0.0

# Special treatment for end angle == 360 deg:
if not math.isclose(end, 360.0):
end %= 360.0

start %= 360.0
if end < start:
end += 360.0
return end - start
This solution covers most (all?) corner cases:

@pytest.mark.parametrize('start, end, expected', [
(0, 0, 0), # start == end is always 0 by definition
(360, 360, 0), # start == end is always 0 by definition
(-30, -30, 0), # start == end is always 0 by definition
(0, 360, 360), # end angle counter clockwise (ccw) 360 is 360 deg (special)
(270, 360, 90), # end angle ccw 360 is 360 deg (special)
(-90, 360, 90), # end angle ccw 360 is 360 deg (special)
(0, -360, 0), # end angle clockwise (cw) 360 deg is 0
(90, -360, 270), # end angle clockwise (cw) 360 deg is 0
(-90, -360, 90), # end angle clockwise (cw) 360 deg is 0
(360, 0, 0), # start angle 360 is 0
(360, 90, 90), # start angle 360 is 0
(360, -90, 270), # start angle 360 is 0
(-360, 0, 0), # start angle -360 is 0
(-360, 90, 90), # start angle -360 is 0
(-360, -90, 270), # start angle -360 is 0
(30, -30, 300), # crossing ccw 0 deg
(-30, 30, 60), # crossing cw 0 deg
(180, -180, 0), # 180 is equal to -180
(-180, 180, 0), # 180 is equal to -180
(90, -90, 180),
(-90, 90, 180),
(360, 400, 40),
(400, 360, 320),
])
def test_arc_angle_span_deg(start, end, expected):
assert arc_angle_span_deg(start, end) == pytest.approx(expected)

Best regards,
Manfred


Am Mo., 21. Dez. 2020 um 14:57 Uhr schrieb Massimiliano Zecchetto <massimilian...@gmail.com>:
--

Massimiliano Zecchetto

unread,
Dec 24, 2020, 3:49:42 AM12/24/20
to python-ezdxf
Thank you so much for your prompt reply Mr. Moitzi.
Your suggestion works fine for me.
Will this be available in ezdxf in the future?
Best regards,

Massimiliano

Reply all
Reply to author
Forward
0 new messages