Numerical circle.
| 386 | |
| 387 | |
| 388 | class Circle: |
| 389 | """Numerical circle.""" |
| 390 | |
| 391 | def __init__( |
| 392 | self, |
| 393 | center: Optional[Point] = None, |
| 394 | radius: Optional[float] = None, |
| 395 | p1: Optional[Point] = None, |
| 396 | p2: Optional[Point] = None, |
| 397 | p3: Optional[Point] = None, |
| 398 | ): |
| 399 | if not center: |
| 400 | if not (p1 and p2 and p3): |
| 401 | self.center = self.radius = self.r2 = None |
| 402 | return |
| 403 | # raise ValueError('Circle without center need p1 p2 p3') |
| 404 | |
| 405 | l12 = _perpendicular_bisector(p1, p2) |
| 406 | l23 = _perpendicular_bisector(p2, p3) |
| 407 | center = line_line_intersection(l12, l23) |
| 408 | |
| 409 | self.center = center |
| 410 | self.a, self.b = center.x, center.y |
| 411 | |
| 412 | if not radius: |
| 413 | if not (p1 or p2 or p3): |
| 414 | raise ValueError('Circle needs radius or p1 or p2 or p3') |
| 415 | p = p1 or p2 or p3 |
| 416 | self.r2 = (self.a - p.x) ** 2 + (self.b - p.y) ** 2 |
| 417 | self.radius = math.sqrt(self.r2) |
| 418 | else: |
| 419 | self.radius = radius |
| 420 | self.r2 = radius * radius |
| 421 | |
| 422 | def intersect(self, obj: Union[Line, Circle]) -> tuple[Point, ...]: |
| 423 | if isinstance(obj, Line): |
| 424 | return obj.intersect(self) |
| 425 | if isinstance(obj, Circle): |
| 426 | return circle_circle_intersection(self, obj) |
| 427 | |
| 428 | def sample_within(self, points: list[Point], n: int = 5) -> list[Point]: |
| 429 | """Sample a point within the boundary of points.""" |
| 430 | result = None |
| 431 | best = -1.0 |
| 432 | for _ in range(n): |
| 433 | ang = unif(0.0, 2.0) * np.pi |
| 434 | x = self.center + Point(np.cos(ang), np.sin(ang)) * self.radius |
| 435 | mind = min([x.distance(p) for p in points]) |
| 436 | if mind > best: |
| 437 | best = mind |
| 438 | result = x |
| 439 | |
| 440 | return [result] |
| 441 | |
| 442 | |
| 443 | class HoleCircle(Circle): |
no outgoing calls
no test coverage detected