Скалярное и векторное произведение - Алгоритмика
Скалярное и векторное произведение

Скалярное и векторное произведение

Помимо очевидных сложения, вычитания и умножения на константу, у векторов можно ввести и свои особенные операции, которые нам упростят жизнь.

#Скалярное произведение

Скалярное произведение (англ. dot product) двух векторов равно произведению их длин и косинуса угла между ними. Для него справедлива следующая формула:

$$ a \cdot b = |a| \cdot |b| \cdot \cos \theta = x_a x_b + y_a y_b $$

Она доказывается муторно и чисто технически, так что мы это делать не будем.

Геометрически, она равна проекции вектора $b$ на вектор $a$, помноженный на длину $а$:

Полезные свойства:

  • Скалярное произведение симметрично ($a \cdot b = b \cdot a$).
  • Перпендикулярные вектора должны иметь нулевое скалярное произведение.
  • Если угол острый, то скалярное произведение положительное.
  • Если угол тупой, то скалярное произведение отрицательное.

Добавим в нашу реализацию отдельный оператор для него:

int operator*(r a, r b) { return a.x * b.x + a.y * b.y; }

#Векторное произведение

Векторное произведение (англ. cross product, также называется косым или псевдоскалярным) для двух векторов равно произведению их длин и синуса угла между ними — причём знак этого синуса зависит от порядка операндов. Оно тоже удобно выражается в координатах:

$$ a \times b = |a| \cdot |b| \cdot \sin \theta = x_a y_b - y_a x_b $$

Так же, как и со скалярным произведением, доказательство координатной формулы оставляется упражнением читателю. Если кто-то захочет это сделать: это следует из линейности обоих произведений (что в свою очередь тоже нужно доказать) и разложения по базисным векторам $\overline{(0, 1)}$ и $\overline{(1, 0)}$.

Геометрически, это ориентированная площадь параллелограмма, натянутого на вектора $a$ и $b$:

Его свойства:

  • Векторное произведение антисимметрично: $a \times b = - (b \times a)$.
  • Коллинеарные вектора имеют нулевое векторное произведение.
  • Если $b$ «слева» от $a$, то векторное произведение положительное.
  • Если $b$ «справа» от $a$, то векторное произведение отрицательное.

Для него обычно тоже перегружают оператор — либо ^, либо %:

int operator^(r a, r b) { return a.x*b.y - b.x*a.y; }

Примечание. Вообще говоря, формально векторное произведение определяется не так. Оно определено как вектор такой же длины, но перпендикулярный обоим исходным векторам. Это имеет применение в трёхмерной геометрии и физике, но пока в нашем двумерном мире об этом думать не надо.


Скалярное и векторное произведения тесно связаны с углами между векторами и могут использоваться для подсчета величин вроде ориентированных углов и площадей, которые обычно используются для разных проверок.

Когда они уже реализованы, использовать произведения гораздо проще, чем опираться на алгебру. Например, можно легко вычислить угол между двумя векторами, подставив в знакомый нам atan2 векторное и скалярное произведение:

double angle(r a, r b) {
    return atan2(a ^ b, a * b);
}

В дальнейшем, свойства произведений помогут нам в определении взаимного расположения точек и, например, прямой, поэтому важно эти свойства понять и крепко запомнить.