Draw a circle sector.
(
self,
center: point_like,
point: point_like,
beta: float,
fullSector: bool = True,
)
| 14992 | return self.draw_bezier(p1, k1, k2, p3) |
| 14993 | |
| 14994 | def draw_sector( |
| 14995 | self, |
| 14996 | center: point_like, |
| 14997 | point: point_like, |
| 14998 | beta: float, |
| 14999 | fullSector: bool = True, |
| 15000 | ) -> Point: |
| 15001 | """Draw a circle sector.""" |
| 15002 | center = Point(center) |
| 15003 | point = Point(point) |
| 15004 | l3 = lambda a, b: _format_g((a, b)) + " m\n" |
| 15005 | l4 = lambda a, b, c, d, e, f: _format_g((a, b, c, d, e, f)) + " c\n" |
| 15006 | l5 = lambda a, b: _format_g((a, b)) + " l\n" |
| 15007 | betar = math.radians(-beta) |
| 15008 | w360 = math.radians(math.copysign(360, betar)) * (-1) |
| 15009 | w90 = math.radians(math.copysign(90, betar)) |
| 15010 | w45 = w90 / 2 |
| 15011 | while abs(betar) > 2 * math.pi: |
| 15012 | betar += w360 # bring angle below 360 degrees |
| 15013 | if not (self.last_point == point): |
| 15014 | self.draw_cont += l3(*JM_TUPLE(point * self.ipctm)) |
| 15015 | self.last_point = point |
| 15016 | Q = Point(0, 0) # just make sure it exists |
| 15017 | C = center |
| 15018 | P = point |
| 15019 | S = P - C # vector 'center' -> 'point' |
| 15020 | rad = abs(S) # circle radius |
| 15021 | |
| 15022 | if not rad > EPSILON: |
| 15023 | raise ValueError("radius must be positive") |
| 15024 | |
| 15025 | alfa = self.horizontal_angle(center, point) |
| 15026 | while abs(betar) > abs(w90): # draw 90 degree arcs |
| 15027 | q1 = C.x + math.cos(alfa + w90) * rad |
| 15028 | q2 = C.y + math.sin(alfa + w90) * rad |
| 15029 | Q = Point(q1, q2) # the arc's end point |
| 15030 | r1 = C.x + math.cos(alfa + w45) * rad / math.cos(w45) |
| 15031 | r2 = C.y + math.sin(alfa + w45) * rad / math.cos(w45) |
| 15032 | R = Point(r1, r2) # crossing point of tangents |
| 15033 | kappah = (1 - math.cos(w45)) * 4 / 3 / abs(R - Q) |
| 15034 | kappa = kappah * abs(P - Q) |
| 15035 | cp1 = P + (R - P) * kappa # control point 1 |
| 15036 | cp2 = Q + (R - Q) * kappa # control point 2 |
| 15037 | self.draw_cont += l4(*JM_TUPLE( |
| 15038 | list(cp1 * self.ipctm) + list(cp2 * self.ipctm) + list(Q * self.ipctm) |
| 15039 | )) |
| 15040 | |
| 15041 | betar -= w90 # reduce param angle by 90 deg |
| 15042 | alfa += w90 # advance start angle by 90 deg |
| 15043 | P = Q # advance to arc end point |
| 15044 | # draw (remaining) arc |
| 15045 | if abs(betar) > 1e-3: # significant degrees left? |
| 15046 | beta2 = betar / 2 |
| 15047 | q1 = C.x + math.cos(alfa + betar) * rad |
| 15048 | q2 = C.y + math.sin(alfa + betar) * rad |
| 15049 | Q = Point(q1, q2) # the arc's end point |
| 15050 | r1 = C.x + math.cos(alfa + beta2) * rad / math.cos(beta2) |
| 15051 | r2 = C.y + math.sin(alfa + beta2) * rad / math.cos(beta2) |
no test coverage detected