Перейти к содержимому

Дополнительно · 3

Масштаб вокруг точки

В уроке «Направление» уже было умножение вектора на число — direction_x * LENGTH, direction_y * LENGTH — чтобы растянуть его до нужной длины. А в уроке «Точка плюс вектор» — что точка A плюс вектор B даёт новую точку: конец вектора B, если его приставить к A.

Возьмём обе идеи сразу: пусть вектор B начинается не в нуле, а в конце вектора A, и мы хотим его растянуть в k раз — так, чтобы A осталось на месте, а длиннее стал именно B.

Самое короткое, что приходит в голову, — взять уже готовую сумму A + B и умножить её целиком:

let x = (ax + bx) * k;
let y = (ay + by) * k;

Не выйдет: (ax + bx, ay + by) — это не вектор, а уже готовая точка, место на экране. Умножение растягивает её от нуля, а не от A — ax внутри скобок тоже умножается на k, хотя его вообще не должны были трогать. В итоге результат уезжает совсем не туда.

Чтобы растянуть именно B, не трогая A, нужно вернуться к тому, с чего начали в «Точке плюс вектор»: B сам по себе — вектор, и умножать на число нужно именно его, отдельно от A, а A прибавить уже после:

let x = ax + bx * k;
let y = ay + by * k;

Разница ровно в одной паре скобок: ax здесь не участвует в умножении вообще, он прибавляется к уже готовому растянутому B.

Правильно

Неправильно

Серый — вектор A, тащи его мышью за кончик в левой картинке — правая повторяет за ней. Бледно-голубой — вектор B, фиксированный, растёт из кончика A. Зелёный пунктир — их сумма: место, где на самом деле окажется то, что мы рисуем. Кнопка увеличивает B в 2 раза двумя разными способами одновременно.

  • Серый вектор A — тащи его мышью, растягиваемый B всегда начинается от его кончика.
  • Слева — правильный способ: B на время “уезжает” в ноль, там растягивается, и едет обратно к кончику A. Зелёный пунктир — сумма A + B — после этого тоже удлиняется, но именно в направлении B, а A остаётся на месте.
  • Справа — та же самая операция над (A + B) * k без возврата в ноль. (ax + bx) * k — это то же самое, что ax * k + bx * k, поэтому на картинке видно честно: растягивается не только сумма, но и сам A, и сам B — оба, хотя A вообще не должны были трогать. Именно поэтому результат улетает совсем не туда, куда нужно.
  • Это касается не только умножения — любая подобная операция над вектором работает правильно, только когда он отсчитан от нуля. Если вектор начинается не в нуле, а в какой-то точке A — сначала A вычитается, операция делается над тем, что осталось, и A прибавляется обратно.