1+ import math
2+
3+ from compas .geometry import close
14from compas .geometry .primitives import Frame
25from compas .geometry .primitives import Primitive
36
@@ -12,8 +15,24 @@ class Arc(Primitive):
1215 radius : float
1316 Radius of the arc's circle.
1417 end_angle : float
15- The angle in radians of the
16- end_angle :
18+ The angle in radians of the end of this Arc.
19+ start_angle :
20+ The angle in radians of the start of this Arc.
21+
22+ Attributes
23+ ----------
24+ length : float
25+ The length of the arc (radius * angle)
26+ angle : float
27+ The sweep angle in radians (between incrementing end angle and start angle).
28+ domain : tuple(float, float)
29+ A tuple containing the start and end angles of this arc, in radians.
30+ center : :class:`~compas.geometry.Point`
31+ The center point of the circle which coincides with this Arc.
32+ circumference : float
33+ The circumference of the circle which coincides with this Arc.
34+ diameter : float
35+ The diameter of the circle which coincides with this Arc.
1736
1837 """
1938
@@ -22,9 +41,12 @@ def __init__(self, frame=None, radius=None, end_angle=None, start_angle=None, **
2241
2342 self ._frame = frame
2443 self ._radius = radius
25- self ._start_angle = start_angle
44+ self ._start_angle = start_angle if start_angle is not None else 0.0
2645 self ._end_angle = end_angle
2746
47+ if self ._radius is not None and self ._end_angle is not None :
48+ self ._verify ()
49+
2850 @property
2951 def data (self ):
3052 return {"frame" : self ._frame .data , "radius" : self ._radius , "start" : self ._start_angle , "end" : self ._end_angle }
@@ -44,10 +66,65 @@ def frame(self):
4466 def radius (self ):
4567 return self ._radius
4668
69+ @property
70+ def length (self ):
71+ return self .radius * self .angle
72+
4773 @property
4874 def start_angle (self ):
4975 return self ._start_angle
5076
5177 @property
5278 def end_angle (self ):
5379 return self ._end_angle
80+
81+ @property
82+ def angle (self ):
83+ return self ._end_angle - self ._start_angle
84+
85+ @property
86+ def domain (self ):
87+ return self ._start_angle , self ._end_angle
88+
89+ @property
90+ def center (self ):
91+ return self .frame .point
92+
93+ @property
94+ def circumference (self ):
95+ return 2.0 * math .pi * self .radius
96+
97+ @property
98+ def diameter (self ):
99+ return 2.0 * self .radius
100+
101+ @property
102+ def is_circle (self ):
103+ return close (abs (abs (self .angle ) - 2.0 * math .pi ), 0.0 )
104+
105+ @classmethod
106+ def from_circle (cls , circle , start_angle , end_angle ):
107+ """Creates an Arc from a circle and start and end angles.
108+
109+ Parameters
110+ ----------
111+ circle : :class:`~compas.geometry.Circle`
112+ The center point and radius of this circle will be used to create an Arc.
113+ start_angle : float
114+ The start angle in radians.
115+ end_angle : float
116+ The end angle in radians.
117+
118+ Returns
119+ -------
120+ :class:`~compas.geometry.Arc`
121+
122+ """
123+ frame = Frame .worldXY ()
124+ # TODO: take circle.frame once it has one
125+ frame .point = circle .center .copy ()
126+ return cls (frame , circle .radius , end_angle , start_angle )
127+
128+ def _verify (self ):
129+ if self .angle < 0.0 or self .angle > 2.0 * math .pi :
130+ raise ValueError ("Sweep angle must satisfy 0 < angle < 2 * Pi. Currently:{}" .format (self .angle ))
0 commit comments