e-olymp 839. Пересечение отрезков

Задача

Два отрезка на плоскости заданы целочисленными координатами своих концов в декартовой системе координат.

Требуется определить, существует ли у них общая точка.

Входные данные

В первой строке содержатся координаты первого конца первого отрезка, во второй — второго конца первого отрезка, в третьей и четвёртой — координаты концов второго отрезка. Координаты целые и по модулю не превосходят $10000$.

Выходные данные

Вывести слово $Yes$, если общая точка есть, или слово $No$ в противном случае.

Тесты

Входные данные Выходные данные
1 0 0
1 0
1 0
1 1
Yes
2 0 0
1 0
2 0
3 0
No
3 7 4
1 1
1 1
3 2
Yes
4 -9725 -8992
9812 9925
-9999 7011
8122 -9248
Yes
5 -9999 -1
10000 1
0 0
0 1
No

Код программы

С ветвлением:

без ветвления:

Решение задачи

Чтобы проверить пересекаются ли заданные отрезки построим прямые, которым они принадлежат, затем найдём точку их пересечения и проверим принадлежит ли она каждому из отрезков.
Для построения прямых воспользуемся формулой прямой проходящей через две точки и немного её преобразуем:
$\frac{x — x_1}{x_2 — x_1} = \frac{y — y_1}{y_2 — y_1}$ ~ $(x — x_1) \cdot (y_2 — y_1) = (y — y_1) \cdot (x_2 — x_1)$ ~ $x \cdot (y_2 — y_1) — y_2 \cdot x_1 + y_1 \cdot x_1 = y \cdot (x_2 — x_1) — x_2 \cdot y_1 + x_1 \cdot y_1$ ~ $y \cdot (x_2 — x_1) = x \cdot (y_2 — y_1) + x_2 \cdot y_1 — x_1 \cdot y_2$.
Обозначим за $k_x$ множитель при $x$, за $k_y$ множитель при $y$, а всё остальное за $b$. Тогда имеем уравнение вида:
$y \cdot k_y = x \cdot k_x + b$, таких у нас будет 2:

  1. $y \cdot k_{y_1} = x \cdot k_{x_1} + b_1$
  2. $y \cdot k_{y_2} = x \cdot k_{x_2} + b_2$

Теперь рассмотрим несколько случаев:
1. Прямые параллельны, следовательно могут не иметь точки пересечения или совпадать.
Проверим совпадают ли $b_1$ и $b_2$. Так как уравнения не сокращены на НОД, то рассмотрим равенство отношений $b_1$ и $b_2$ на $k_{y_1}$, $k_{x_1}$ и $k_{y_2}$, $k_{x_2}$ соответственно. Если они равны, то прямые совпадают. Иначе не имеют точек пересечения, а следовательно и отрезки тоже не пересекаются.
Когда прямые совпадают, необходимо проверить, что отрезки на этой прямой имеют хоть какую-то общую точку. Каждый из концов каждого отрезка проверим на вхождение в другой. Если такое вхождение есть, то отрезки пересекаются, иначе нет.
2. Прямые не параллельны, а следовательно имеют точку пересечения.
Тогда, решив систему двух линейных уравнений в общем виде получим что:

  • $x = \frac{b_1 \cdot k_{x_2} — b_2 \cdot k_{x_1}}{k_{y_1} \cdot k_{x_2} — k_{x_1} \cdot k_{y_2}}$
  • $y = \frac{b_2 \cdot k_{y_1} — b_1 \cdot k_{y_2}}{k_{x_1} \cdot k_{y_2} — k_{y_1} \cdot k_{x_2}}$

Осталось проверить находится ли точка с координатами $(x, y)$ в каждом из отрезков. Для этого просуммируем расстояния от этой точки до границ каждого отрезка и сравним с длинами отрезков. Если суммы соответственно совпали с длинами, то отрезки пересекаются, иначе — нет.

Ссылки

Related Images:

Ю1.13

Задача. Заданы уравнения двух пересекающихся прямых на плоскости: [latex]y=k_{1}+b_{1}[/latex]; [latex]y=k_{2}+b_{2}[/latex] . Найти (в градусах и минутах) угол между ними, используя формулу: [latex]\tan\varphi=\frac{(k_{2}-k_{1})}{(1+k_{2}*k_{1})} [/latex] .

 Значение k1  Значение k2 Ответ
 -6  -38  -7 градусов 57 минут (два целых отрицательных числа)
 13  15  0 градусов 35 минут (два целых числа)
 33.7  21.6  0 градусов 57 минут (два числа с запятой)
 1  1  0 градусов 0 минут (получаем 0 в числителе)
 1  -1  0 градусов (получаем ноль в знаменателе)

 

Для вычисления угла между двумя прямыми, зная тангенс, воспользуемся формулой [latex]\varphi=atan\tan\varphi[/latex]. Полученный результат переводим в градусы по формуле: [latex]\varphi=\frac{180*\varphi}{\Pi}[/latex] . Далее переведем результат в градусы и минуты. Для этого сначала найдем ближайшее целое число меньше полученного и запишем его, как градусы(при этом, если градусы отрицательные, то мы найдем ближайшее большее целое число, и запишем его, как градусы). После этого, от первоначального  числа отнимем полученное и переведем его в минуты( если градусы были отрицательными, то от полученного отнимем первоначальное). Для этого результат вычитания домножим на 60. Этот результат запишем в минуты. ( Примечание: если [latex]k2*k1=-1[/latex] , то ответ — 0 градусов )

Related Images: