Перейти до основного вмісту

Точка перетину прямих

Нам задано дві прямі, описані рівняннями a1x+b1y+c1=0a_1 x + b_1 y + c_1 = 0 та a2x+b2y+c2=0a_2 x + b_2 y + c_2 = 0. Потрібно знайти точку перетину цих прямих або визначити, що прямі паралельні.

Коли підходить цей алгоритм?
  • Об'єкти — нескінченні прямі, а не відрізки скінченної довжини? (якщо ні → Перевірка перетину двох відрізків)
  • Прямі задані (або легко зводяться) до загального вигляду Ax+By+C=0Ax + By + C = 0?
  • Потрібні саме координати точки перетину, а не лише факт «перетинаються чи ні»?

Розв'язок

Якщо дві прямі не паралельні, то вони перетинаються. Щоб знайти їхню точку перетину, нам треба розв'язати таку систему лінійних рівнянь:

{a1x+b1y+c1=0a2x+b2y+c2=0\begin{cases} a_1 x + b_1 y + c_1 = 0 \\ a_2 x + b_2 y + c_2 = 0 \end{cases}

Скориставшись правилом Крамера, ми можемо одразу виписати розв'язок системи, який дасть нам шукану точку перетину прямих:

x=c1b1c2b2a1b1a2b2=c1b2c2b1a1b2a2b1,x = - \frac{\begin{vmatrix}c_1 & b_1 \cr c_2 & b_2\end{vmatrix}}{\begin{vmatrix}a_1 & b_1 \cr a_2 & b_2\end{vmatrix} } = - \frac{c_1 b_2 - c_2 b_1}{a_1 b_2 - a_2 b_1}, y=a1c1a2c2a1b1a2b2=a1c2a2c1a1b2a2b1.y = - \frac{\begin{vmatrix}a_1 & c_1 \cr a_2 & c_2\end{vmatrix}}{\begin{vmatrix}a_1 & b_1 \cr a_2 & b_2\end{vmatrix}} = - \frac{a_1 c_2 - a_2 c_1}{a_1 b_2 - a_2 b_1}.

Якщо знаменник дорівнює 00, тобто

a1b1a2b2=a1b2a2b1=0\begin{vmatrix}a_1 & b_1 \cr a_2 & b_2\end{vmatrix} = a_1 b_2 - a_2 b_1 = 0

то або система не має розв'язків (прямі паралельні й різні), або розв'язків нескінченно багато (прямі збігаються). Якщо нам треба розрізнити ці два випадки, ми маємо перевірити, чи коефіцієнти cc пропорційні з тим самим відношенням, що й коефіцієнти aa і bb. Для цього достатньо обчислити такі визначники, і якщо вони обидва дорівнюють 00, то прямі збігаються:

a1c1a2c2,b1c1b2c2\begin{vmatrix}a_1 & c_1 \cr a_2 & c_2\end{vmatrix}, \begin{vmatrix}b_1 & c_1 \cr b_2 & c_2\end{vmatrix}

Зауважимо, що інший підхід до обчислення точки перетину пояснюється у статті Основи геометрії.

Реалізація

struct pt {
double x, y;
};

struct line {
double a, b, c;
};

const double EPS = 1e-9;

double det(double a, double b, double c, double d) {
return a*d - b*c;
}

bool intersect(line m, line n, pt & res) {
double zn = det(m.a, m.b, n.a, n.b);
if (abs(zn) < EPS)
return false;
res.x = -det(m.c, m.b, n.c, n.b) / zn;
res.y = -det(m.a, m.c, n.a, n.c) / zn;
return true;
}

bool parallel(line m, line n) {
return abs(det(m.a, m.b, n.a, n.b)) < EPS;
}

bool equivalent(line m, line n) {
return abs(det(m.a, m.b, n.a, n.b)) < EPS
&& abs(det(m.a, m.c, n.a, n.c)) < EPS
&& abs(det(m.b, m.c, n.b, n.c)) < EPS;
}

Відеоматеріали