circle_math.py 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  1. import numpy as np
  2. from typing import Tuple
  3. # nearest to (1,0) point is omitted
  4. def point_of_intersection(x1: float, y1: float, r1: float, x2: float,
  5. y2: float, r2: float) -> Tuple[float, float]:
  6. p1 = x1 + y1 * 1j
  7. p2 = x2 + y2 * 1j
  8. d = abs(p2 - p1)
  9. q = (r1**2 - r2**2 + d**2) / (2 * d)
  10. h = (r1**2 - q**2)**0.5
  11. p = p1 + q * (p2 - p1) / d
  12. intersect = [(p.real + h * (p2.imag - p1.imag) / d,
  13. p.imag - h * (p2.real - p1.real) / d),
  14. (p.real - h * (p2.imag - p1.imag) / d,
  15. p.imag + h * (p2.real - p1.real) / d)]
  16. intersect = [x + 1j * y for x, y in intersect]
  17. intersect_shift = [p - (1 + 0j) for p in intersect]
  18. intersect_shift = abs(np.array(intersect_shift))
  19. p = intersect[0]
  20. if intersect_shift[0] < intersect_shift[1]:
  21. p = intersect[1]
  22. return p.real, p.imag
  23. def point_of_intersection_with_unit(x: float, y: float,
  24. r: float) -> Tuple[float, float]:
  25. return point_of_intersection(x, y, r, 0, 0, 1)