Что геометрически означает скалярное произведение и как через него найти угол и проекцию?
Знаю формулу a·b = ax*bx + ay*by, но не понимаю, что она значит и как этим пользоваться на практике — например, чтобы понять, острый угол между векторами или тупой, и как найти длину проекции одного вектора на другой.
2 ответа
Скалярное произведение a·b = |a||b|cos(θ), где θ — угол между векторами. Отсюда два рабочих следствия:
- Знак угла.
a·b > 0— угол острый,a·b == 0— векторы перпендикулярны,a·b < 0— тупой. Это вычисляется в целых числах точно:
long long d = a.dot(b);
if (d == 0) /* перпендикулярны */;
else if (d > 0) /* острый угол */;
else /* тупой угол */;
- Проекция. Длина проекции
aна направлениеbравна(a·b)/|b|, а сам вектор проекции —b * (a·b)/(b·b). Деление уже даётdouble, но знак и сравнения до этого момента целые.
Сам угол: θ = acos(dot / (|a|*|b|)), но acos — крайняя мера. На олимпиаде почти всегда достаточно знака dot и cross, без явного вычисления угла в радианах — так избегаешь ошибок double. Всё O(1).
Частая ловушка: проверять перпендикулярность через acos(...) == M_PI/2 — это почти всегда даст ошибку из-за double. Перпендикулярность — это ровно a.dot(b) == 0 в целых числах, точно и без epsilon. Аналогично, чтобы сравнить, какой из двух углов больше, не считай сами углы — сравнивай cos через dot, помня, что cos убывает: больший dot (при равных длинах) = меньший угол.