Returns a pair of points as intersections of line and circle.
(line: Line, circle: Circle)
| 509 | |
| 510 | |
| 511 | def line_circle_intersection(line: Line, circle: Circle) -> tuple[Point, Point]: |
| 512 | """Returns a pair of points as intersections of line and circle.""" |
| 513 | a, b, c = line.coefficients |
| 514 | r = float(circle.radius) |
| 515 | center = circle.center |
| 516 | p, q = center.x, center.y |
| 517 | |
| 518 | if b == 0: |
| 519 | x = -c / a |
| 520 | x_p = x - p |
| 521 | x_p2 = x_p * x_p |
| 522 | y = solve_quad(1, -2 * q, q * q + x_p2 - r * r) |
| 523 | if y is None: |
| 524 | raise InvalidQuadSolveError() |
| 525 | y1, y2 = y |
| 526 | return (Point(x, y1), Point(x, y2)) |
| 527 | |
| 528 | if a == 0: |
| 529 | y = -c / b |
| 530 | y_q = y - q |
| 531 | y_q2 = y_q * y_q |
| 532 | x = solve_quad(1, -2 * p, p * p + y_q2 - r * r) |
| 533 | if x is None: |
| 534 | raise InvalidQuadSolveError() |
| 535 | x1, x2 = x |
| 536 | return (Point(x1, y), Point(x2, y)) |
| 537 | |
| 538 | c_ap = c + a * p |
| 539 | a2 = a * a |
| 540 | y = solve_quad( |
| 541 | a2 + b * b, 2 * (b * c_ap - a2 * q), c_ap * c_ap + a2 * (q * q - r * r) |
| 542 | ) |
| 543 | if y is None: |
| 544 | raise InvalidQuadSolveError() |
| 545 | y1, y2 = y |
| 546 | |
| 547 | return Point(-(b * y1 + c) / a, y1), Point(-(b * y2 + c) / a, y2) |
| 548 | |
| 549 | |
| 550 | def _check_between(a: Point, b: Point, c: Point) -> bool: |