Надо найти координаты p2 и p3
Обозначим x-координату P_i как P_{ix}, y-координату как P_{iy}.
Если P_1 лежит внутри окружности, т. е. P_0P_1 < P_0P_2 \iff (P_{0x} - P_{1x})^2 + (P_{0y} - P_{1y})^2 < (P_{0x} - P_{2x})^2 + (P_{0y} - P_{2y})^2, то точек касания 0. Если P_1 на окружности, то мы имеем единственную точку касания совпадающей с P_1. Пусть теперь P_1 вне окружности.
Заметим, что точка P_2 задается двумя условиями: P_0P_2 = r и \angle P_0P_2P_1 = 90^{\circ}. Первое условие равносильно тому, что P_2 лежит на окружности с центром в P_0 и с радиусом r, второе условие равносильно тому, что P_2 лежит на окружности с диаметром P_0P_1 (или с радиусом \frac{P_0P_1}{2}) и с центром в середине отрезка P_0P_1, т. е. \left(\frac{P_{0x} + P_{1x}}{2}, \frac{P_{0y} + P_{1y}}{2}\right).
Тогда искомые точки касания – это пересечение этих двух окружностей. На питоне пересечение окружностей можно реализовать так,
def circles_inter(x0: float, y0: float,
x1: float, y1: float,
r0: float, r1: float) -> tuple:
"""
Входные данные:
x0, y0, r0 - координаты центра и радиус первой окружности
x1, y1, r1 - координаты центра и радиус второй окружности
Выходные данные:
x2, y2 - координаты середины отрезка с концами в точках пересечения
x3, y3 - координаты первой точки пересечения
x4, y4 - координаты второй точки пересечения
"""
d = sqrt((x1 - x0)**2 + (y1 - y0)**2)
a = (r0**2 - r1**2 + d**2) / (2*d)
h = sqrt(r0**2 - a**2)
x2 = x0 + a*(x1 - x0) / d
y2 = y0 + a*(y1 - y0) / d
x3 = x2 + h*(y1 - y0) / d
y3 = y2 - h*(x1 - x0) / d
x4 = x2 - h*(y1 - y0) / d
y4 = y2 + h*(x1 - x0) / d
return x3, y3, x4, y4
Почему это работает и что такое a
, d
и h
можно почитать в этой статье под пунктом Intersection of two circles.
Как только вычислим координаты точек пересечения, можем сразу получить P_3 как середину отрезка с концами в этих точках. А дальше длины векторов \overrightarrow{P_1P_3} и \overrightarrow{P_2P_3} вычислить несложно.
Откуда кстати задача?
А я хотел находить расстояние \overline{P_1P_2} через прямоугольный треугольник, потом его углы, потом угол наклона прямой P_1P_0 и оттуда находить P_2. А для P_3 использовать подобие треугольников P_0P_2P_1 и P_0P_3P_2. Однако твоё решение выглядит гораздо более красиво, чем моё что неудивительно)
Решение задачи на путоне, вроде как работает
from math import sqrt
def distance(x0: float, y0: float,
x1: float, y1: float) -> float:
"""
Входные данные:
x0, y0 - координаты первой точки
x1, y1 - координаты второй точки
Выходные данные:
d - расстояние между двумя точками
"""
d = sqrt((x0 - x1)**2 + (y0 - y1)**2)
return d
def circles_inter(x0: float, y0: float,
x1: float, y1: float,
r0: float, r1: float) -> tuple:
"""
Входные данные:
x0, y0, r0 - координаты центра и радиус первой окружности
x1, y1, r1 - координаты центра и радиус второй окружности
Выходные данные:
x2, y2 - координаты середины отрезка с концами в точках пересечения
x3, y3 - координаты первой точки пересечения
x4, y4 - координаты второй точки пересечения
"""
d = distance(x0, y0, x1, y1)
a = (r0**2 - r1**2 + d**2) / (2*d)
h = sqrt(r0**2 - a**2)
x2 = x0 + a * (x1 - x0) / d
y2 = y0 + a * (y1 - y0) / d
x3 = x2 + h * (y1 - y0) / d
y3 = y2 - h * (x1 - x0) / d
x4 = x2 - h * (y1 - y0) / d
y4 = y2 + h * (x1 - x0) / d
return x3, y3, x4, y4
with open('tangent.in', 'r') as f:
p0x, p0y = map(int, f.readline().split())
r = int(f.readline())
p1x, p1y = map(int, f.readline().split())
d = distance(p1x, p1y, p0x, p0y)
if d < r:
ans = "0"
elif d == r:
ans = "1\n{:.6f} {:.6f}".format(p1x, p1y)
else:
ans = "2\n"
midx, midy = (p0x + p1x) / 2, (p0y + p1y) / 2
r2 = d / 2
p21x, p21y, p22x, p22y = circles_inter(p0x, p0y, midx, midy, r, r2)
p3x, p3y = (p21x + p22x) / 2, (p21y + p22y) / 2
d13, d23 = distance(p1x, p1y, p3x, p3y), distance(p21x, p21y, p3x, p3y)
ans += "{:.6f} {:.6f}\n".format(p3x, p3y) + \
"{:.6f} {:.6f}\n".format(d13, d23) + \
"{:.6f} {:.6f}\n{:.6f} {:.6f}".format(p21x, p21y, p22x, p22y)
with open('tangent.out', 'w') as f:
f.write(ans)
2012-2013 Тренировка СПбГУ C #9. Геометрия. Продолжение.
Если точка находится внутри круга то ответ 0. Проверить можно сравнив радиус круга и расстояние между точкой и центром круга.
Если точка находится на окружности то ответ 1, и это и есть сама эта точка. Проверить можно сравнив радиус круга и расстояние между точкой и центром круга .
Иначе достаточно вычислить то что просят в задаче, Пользователи выше написали подробное объяснение того как это делать.