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

Разрабатываю игру. Появилась необходимость найти угол между вектором направления взгляда персонажа и центром объекта, но не понимаю как это сделать. Ниже приведу схему (вид сверху) для наглядности вопроса: a — вектор направления взгляда
B — точка, центр объекта, к которому надо найти угол
c — вектор a, повернутый на необходимый градус
α — угол, необходимый для поворота вектора a так, чтобы он смотрел на B Известны позиции: вектора a, точки B. Еще известен угол поворота вектора a вокруг своей оси. Проблема возникает из-за того что я не знаю длину вектора a, здесь он нарисован просто для визуализации проблемы.
Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
Направление и расстояние от одного объекта до другого.
Если вычесть координаты одной точки в пространстве из координат другой, то получим вектор, который “выходит” из второй точки и “заканчивается” в первой:
// Gets a vector that points from the player's position to the target's. var heading = target.position - player.position;
Помимо того, что этот вектор указывает в направлении объекта, модуль данного вектора равен расстоянию между двумя позициями. Часто нам требуется нормированный вектор, который показывает направление к цели, а также расстояние (скажем, для управления снарядом). Расстояние между двумя объектами равно модулю направляющего вектора, он может быть нормирован, достаточно разделить на его модуль:-
var distance = heading.magnitude; var direction = heading / distance; // This is now the normalized direction.
Лучше выбрать именно такой подход, нежели использовать модуль и нормаль отдельно, из-за их склонности нагружать CPU (оба используют вычисления квадратных корней).
Если расстояние нужно лишь для сравнения (скажем, проверка на достаточную удаленность), тогда вообще можно не вычислять значение модуля. Свойство sqrMagnitude возвращает квадрат модуля, оно высчитывается подобно расстоянию, но без затратной по времени операции нахождения квадратного корня. Вместо того, что сравнивать модуль с известным расстоянием, можно сравнить квадрат модуля с квадратом расстояния:-
if (heading.sqrMagnitude < maxRange * maxRange) < // Target is within range. >
Это намного более эффективно, чем вычислять именно модуль при сравнении.
Иногда, требуется узнать направление к надземной цели. Например, представьте, что игроку, который стоит на земле нужно приблизиться к парящему в воздухе предмету. Если вычесть координаты позиции игрока из координат цели, тогда полученный вектор будет указывать вверх и по направлению к цели. Этот вариант не подходит, чтобы придать ориентацию компоненту transform игрока, так как он тоже будет указывать вверх. Что тут действительно нужно сделать — это вычислить вектор от игрока к позиции на земле прямо под предметом. Это легко сделать, если у вектора, являющегося результатом вычитания, установить координату Y в ноль:-
var heading = target.position - player.position; heading.y = 0; // This is the overground heading.
Как определить направление векторов m e w
Я прочитал замечательную книгу, называется «Геометрические векторы», которая хороший порядок в голове навела. Помимо прочего, разобрался с тем, что мне с юности мешало и не нравилось в векторном произведении.
Мне казались странными две вещи. Во-первых, что векторное произведение, в отличие от скалярного, «привязано» к трехмерному пространству, а в другом количестве измерений его непонятно, как определять. Во-вторых, что для его определения нужно правило правой руки (оно же «правило буравчика»): мне казалось очень странным, что этот произвольный выбор правила правой руки (а не левой, например) может быть «зашит» в законы физики.
Про первый вопрос, о сути векторного произведения не только в трехмерном пространстве, я напишу потом в записи о всей книге и ее подходе, если соберусь. А о правиле правой руки постараюсь вкратце рассказать тут.
Будем смотреть на вектор «по-физически» как на отрезок в пространстве, с заданным на нем направлением. Длина отрезка определяет величину вектора. Направление, которое мы обозначаем стрелкой — просто выбор одного из двух концов отрезка. Если в векторе поменять направление на обратное, получится обратный вектор, и эту операцию логично обозначать знаком минус, потому что сложение двух этих векторов дает ноль (вектор нулевой величины).

(я сознательно не ввожу систему координат и не говорю о координатах векторов — во всем этом обсуждении можно без них обойтись, и так проще)
Далее, векторное произведение двух векторов определяется обычно так: это отрезок, перпендикулярный плоскости, в которой лежат оба вектора, и его длина равна произведению их длин умноженному на синус угла между ними. Но чтобы этот отрезок стал вектором, осталось еще дать ему направление, т.е. решить, в каком конце рисуется стрелка. Или — что то же самое — в какую из двух сторон от плоскости он уходит. Для этого используют правило правой руки: если расположить руку так, чтобы четыре пальца загибались от первого вектора ко второму, то отставленный большой палец покажет направление векторного произведения.

При этом векторное произведение несколько странно ведет себя по сравнению с обычными векторами, и поэтому, если нужна точность, его называют псевдовектором (или аксиальным вектором). Вот что это значит. Предположим, мы используем векторы для изображения каких-то физических величин, которые мы в принципе можем измерить: например, скорость, или сила, или магнитное поле и так далее. Тогда понятно, что если мы просто посмотрим на ту же физическую систему с другой стороны, под другим углом, то от этого скорости, силы, и другие физические величины не изменятся. Раз наши вектора-стрелки изображают эти физические величины, они тоже не должны от этого измениться. И действительно, с чего бы стрелкам в пространстве меняться от того, что на них посмотрели с другой стороны. Это все просто и тривиально. Далее, есть и другой способ посмотреть «по-другому» на физическую систему: посмотреть на ее зеркальное отражение. Зеркальное отражение некоторое векторы оставляет без изменений: я стою перед зеркалом, моя правая рука направлена вправо — ее отражение в зеркале направлено в ту же сторону: для меня-зеркального это «лево», да, но это то же направление. Другие векторы меняет: если я потянусь рукой к зеркалу, мое отражение потянется в обратном направлении. Но так или иначе, логично ожидать, что все физические величины при зеркальном отражении всей системы изменятся одинаковым «зеркальным» способом.
Но векторное произведение так не работает. Оно в зеркальном отражении меняется на обратное тому, каким, казалось бы, должно быть. И понятно, почему так происходит: из-за правила правой руки. Ведь в зеркальном отражении правая рука становится левой, а векторное произведение там, в отражении, все равно нужно по определению делать по правилу правой.

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

У колес машины есть угловая скорость, которая определяется через векторное произведение. У машины слева оно направлено влево (красная стрелка). Справа зеркальное отражение той же машины. Мы бы ожидали, что в зеркальном направлении стрелка будет теперь идти вправо, но из-за правила правой руки она опять направлена влево.

В общем, векторное произведение ведет себя как обычный вектор, если мы всего лишь поворачиваем систему координат (т.е. смотрим под другим углом) или двигаем ее. Но если мы делаем отражение системы координат (т.е. смотрим на зеркальное отражение), то оно меняет знак в сравнении с обычными векторами, и поэтому называется псевдовектором. Это лишний раз подчеркивает странность произвольного выбора правила правой руки, и того, что физические величины, которые ведут себя в соответствии с законами природы, должны почему-то ему подчиняться.
Теперь другой взгляд на все это, из книги Вайнрайха «Геометрические векторы».
У нас есть отрезок в пространстве, и мы хотим дать ему направление, чтобы он стал вектором. Мы привыкли к тому, что это значит — выбрать одну из его вершин и назвать ее началом, а другую концом (или хвостом и головой), и нарисовать стрелку. Но давайте представим себе, что на самом деле есть два разных вида «направления». Есть два разных способа выбрать что-то, одно из двух, касающееся этого отрезка. Один, когда мы выбираем одну из вершин и рисуем стрелку, называется «полярное направление». Другой вид, когда мы задаем направление вращения отрезка вокруг своей оси, называется «аксиальное направление».

Отрезок может вращаться (или вокруг него можно описывать круги, если желаете) в одном из двух направлений. Обратите внимание, это важно! — неверно называть их «по часовой стрелке» или «против часовой стрелки», это неправильно, потому что каждое из этих аксиальных направлений будет «по часовой стрелке», если смотреть с одного конца отрезка, и «против часовой стрелки», если смотреть с другого. Это просто два противоположных направления. Отрезок, у которого задано такое аксиальное направление, называется аксиальным вектором. Важно уяснить, что у такого вектора нигде нет стрелки, у него нет выбранной вершины, у него есть только выбранное аксиальное направление (направление вращения).
Такие векторы можно складывать друг с другом, или умножать на скаляры, так же легко, как и обычные полярные векторы. Например, как мы складываем обычные векторы? Мы сдвигаем их так, чтобы начало одного уткнулось в конец другого, т.е. пользуемся их стрелками, и потом соединяем дальние концы. Чтобы сложить два аксиальных вектора, нам нужно понять, как их соединить концами: ведь стрелок нет. Но на самом деле это просто: они соединяются так, чтобы они крутились в одном и том же направлении, если переходить с одного на другой. Можно представить себе такие векторы веревками, которые вращаются в своем направлении; если мы их свяжем двумя концами, то они будут либо мешать друг другу крутиться — и тогда мы связали неправильно — либо крутиться вместе, и это правильный способ. И потом мы соединяем дальние концы и закручиваем то, что получилось, в том же направлении.

Зачем нужны аксиальные векторы? Так вот векторное произведение как раз естественным образом и является аксиальным вектором. Мы умножаем два вектора a и b, получаем отрезок определенной величины, перпендикулярный их плоскости. Для того, чтобы дать ему «стрелку», нам нужно что-то вроде правила правой руки. Но чтобы дать ему аксиальное направление, ничего особенного не нужно: оно естественным образом задается как направление вращения от a к b. При этом, как и требуется, от перестановки мест множителей направление произведение меняется на обратное.

Теперь при зеркальном отражении аксиальный вектор ведет себя так же естественно, как и (обычный) полярный вектор. Его направление вращение может измениться на противоположное, в зависимости от его ориентации в пространстве, но это нормально, обычный вектор тоже может измениться на противоположный, если он направлен к зеркалу. Главное — это что все происходит в точности как мы ожидаем: изогнутая стрелка вокруг вектора отражается в зеркале точно так же, как и все остальное. Нет этого странного прыжка стрелки от сверху вниз к снизу вверх, как было, когда мы рисовали у векторного произведения стрелку. Нет такого, что есть обычный нормальный вектор и «плохой» псевдовектор: полярный и аксиальный векторы равноправны и симметричны по своим свойствам.
В этом подходе мы работаем с двумя разными видами векторов, и соответственно разных операций получается больше, и надо с ними разобраться. Но это все выходит довольно просто. Скажем, векторное произведение двух полярных векторов дает аксиальный, как мы только что увидели, и двух аксиальных — тоже дает аксиальный (надо разобраться, как соединить их концы и как определить вращение результата). Зато векторное произведение полярного и аксиального векторов дает обычный полярный вектор. Это объясняет, кстати, почему магнитное поле странным образом переворачивается в зеркальном отражении — в обычной формулировке векторного произведения — но у этого нет физических последствий: потому что когда оно действует на движущуюся заряженную частицу, то ее приложение вычисляется через еще одно векторное произведение, и получается обычный вектор, так что частица будет двигаться «правильно» в отражении.
Скалярное произведение двух аксиальных векторов дает обычный скаляр, как и скалярное произведение двух полярных векторов. Обычный скаляр можно считать «полярным», и у него задано «направление» — просто его знак: 10 и -10 это два полярных скаляра противоположного направления. А вот если составить скалярное произведение полярного и аксиального векторов, получается такая смешная штука, которую называют псевдоскаляр или аксиальный скаляр. Это число, у которого есть одно из двух направлений, но они не совпадают ни с плюсом, ни с минусом. Само число обязано быть положительным, потому что же это просто длина отрезка, но мы его как бы считаем без знака, не +10 и не -10, а «просто 10», и при этом у него есть одно из двух направлений вращения, которые можно условно назвать, например, правым и левым. То есть это будет «правое 10» или «левое 10».
А какое же отношение ко всему этому имеет «правило правой руки», спросите вы? Очень просто. Мы определили новый вид вектора, и с его помощью векторное произведение, без правила правой руки. Но если нам хочется, то правило правой руки просто-напросто дает способ перевести любой аксиальный вектор в полярный, и наоборот. То, как загибаются пальцы — это аксиальное направление, то, куда указывает большой палец — полярное.

Поскольку аксиальное и полярное направления не зависят друг от друга, нет естественного способа перевести одно в другое. Надо выбрать один из двух таких способов: либо правило правой руки, либо правило левой руки (кстати, выбор системы координат — тоже является выбором такого правила: то, как оси x,y,z расположены друг относительно друга, задает либо правую, либо левую руку). Как только мы выбираем одно из них, мы можем все наши аксиальные вектора заменить на сооветствующие полярные, и избавиться от «отрезка с направлением вращения» (а «правое 10» становится соответственно +10 или -10, смотря какое правило мы выбрали). Но тогда мы возвращаемся к старой картине мира, в которой эти вновь полученные вектора начинают вести себя странно в зеркальном отражении, и за это в старой картине мира их называли ‘аксиальными’ или ‘псевдовекторами’. А псевдоскаляры в зеркальном отражении, хоть и выглядят обычными числами, теперь почему-то меняют знак на противоположный. Теперь мы видим, что это странное несимметричное поведение не присутствует в природе, а возникает, когда мы выбираем произвольным образом одно из двух правил для того, чтобы упростить себе жизнь и работать только с одним типом векторов. Но если использовать оба, то законы и движение и все такое происходит логично, отражается в зеркале так, как мы того ожидаем, и не нужно правило правой руки.
По-моему, очень красиво.
Как определить направление векторов m e w
1. Основные определения
Удивительно, но с векторными величинами разной природы (перемещением, скоростью, силой, импульсом и др.) можно работать в значительной мере единообразно — как с геометрическими объектами — геометрическими векторами, или просто векторами, хотя есть и нюансы (см. ниже).
Определение
Вектор представляет собой направленный отрезок прямой, для которого определены правила (законы) сложения с другими векторами, правило вычитания векторов, правило умножения вектора на число, скалярное произведение двух векторов и некоторые другие операции.
Стрелка компаса — не вектор, т. к. для неё нет таких операций.
Мы будем рассматривать векторы на плоскости и в соответствии со сложившейся традицией обозначать их латинскими буквами со стрелками наверху, например: `vec v`, `vec F`, `vec a`, `vec b` и т. п. Часто в целях экономии используют упрощённое обозначение — букву с чертой, например, `bar v` или `bar F`.
Одну из граничных точек вектора называют его началом, а другую — концом. Направление вектора задаётся от начала к концу, причём на чертеже конец вектора отмечают стрелкой. Начало вектора называют также точкой его приложения. Если точка `A` является началом вектора `vec a`, то мы будем говорить, что вектор `vec a` приложен в точке `A` (рис. 2).
Число, выражающее длину направленного отрезка, называют модулем вектора и обозначают той же буквой, что и сам вектор, но без стрелки наверху, например: модулем вектора `vec v` является число `v`. Часто для обозначения модуля вектора прибегают к помощи знака абсолютной величины и пишут, например, `|vec v|` или `|vec F|`.
Вектор называется нулевым, если его начало и конец совпадают. Нулевой вектор не имеет определённого направления и его длина (модуль) равна нулю.
Векторы называются коллинеарными, если они лежат либо на одной прямой, либо на параллельных прямых. Так, например, на рис. 3 векторы `vec a`, `vec b` и `vec c` коллинеарны.
Два вектора называются равными, если они коллинеарны, имеют одинаковую длину и одинаковое направление.
На рис. 4 слева изображены неравные векторы `vec a` и `vec f`, `vec g` и `vec h`, а справа — равные векторы `vec p` и `vec q`. Точка приложения геометрического вектора `vec a` может быть выбрана произвольно. Мы не различаем двух равных векторов, имеющих разные точки приложения и получающихся один из другого параллельным переносом. В соответствии с этим векторы, изучаемые в геометрии, называют свободными (они определены с точностью до точки приложения).
В физике точка приложения вектора иногда имеет принципиальное значение. Достаточно вспомнить рычаг: две равные по модулю силы, направленные в одну и ту же сторону, производят на рычаг разное действие, если плечи сил не равны друг другу. И всё же сами силы равны друг другу! Бывают и случаи, когда вектору трудно приписать конкретную точку приложения. Например, если одна система отсчёта движется относительно другой со скоростью `vec v`, то какой точке приписать эту скорость? Всем точкам движущейся системы!
2. Сложение двух векторов.
Пусть даны два произвольных вектора `vec a` и `vec b` (рис. 5а).
Для нахождения их суммы нужно перенести вектор `vec b` параллельно самому себе так, чтобы его начало совпало с концом вектора `vec a`. Тогда вектор, проведённый из начала вектора `vec a` в конец перенесённого вектора `vec b`, и будет являться суммой `vec a` и `vec b`. На рис. 5б — это вектор `vec c`.
Описанное правило есть просто определение суммы векторов. Как и в случае с числами, сумма векторов не зависит от порядка слагаемых, и поэтому можно записать
`vec c = vec a + vec b = vec b + vec a`. (1)
Приведённое выше правило геометрического сложения векторов называется правилом треугольника .
Сумма векторов может быть найдена и по правилу параллелограмма. В этом случае параллельным переносом нужно совместить начала векторов `vec a` и `vec b` и построить на них, как на сторонах, параллелограмм. Тогда сумма `vec a` и `vec b` будет представлять собой диагональ этого параллелограмма, конкретно — суммой `vec a` и `vec b` будет вектор, начало которого совпадает с общим началом векторов `vec a` и `vec b` конец расположен в противоположной вершине параллелограмма, а длина равна длине указанной диагонали (рис. 5в).
Оба способа сложения дают идентичный результат и одинаково часто применяются на практике. Когда речь идёт о нахождении суммы трёх и более векторов, часто последовательно используют правило треугольника. Поясним сказанное.
3. Сложение трёх и более векторов.
Пусть нужно сложить три вектора `vec a`, `vec b` и `vec d` (рис. 6).
Для этого по правилу треугольника сначала находится сумма любых двух векторов, например `vec a` и `vec b`, потом полученный вектор `vec c = vec a + vec b` по тому же правилу складывается с третьим вектором `vec d`. Тогда полученный вектор `vec f = vec c + vec d` и будет представлять собой сумму трёх векторов `vec a`, `vec b` и `vec d`: `vec f = vec a + vec b + vec d`. Как и в случае с двумя векторами, порядок слагаемых не влияет на конечный результат.
Чтобы упростить процесс сложения трёх и более векторов, обычно не находят промежуточные суммы типа `vec c = vec a + vec b`, а применяют правило многоугольника: параллельными переносами из конца первого вектора откладывают второй, из конца второго — откладывают третий, из конца третьего — четвёртый и т. д.
Так, на рис. 7 вектор `vec g` представляет собой сумму векторов `vec a`, `vec b`, `vec d`, `vec e`, найденную по правилу многоугольника: `vec g = vec a + vec b + vec d + vec e`.
Не всякая векторная сумма может иметь физический смысл. Не всякие величины вообще имеет смысл складывать. Так, например, бессмысленно говорить, что, если у меня температура `36,6^@` и у вас тоже `36,6^@`, то вместе у нас температура `73,2^@`, хотя складывать температуры (числа) никто не запрещает. Всё же чаще всего сумма температур представляет собой никому не нужную величину; она редко входит в какие-либо уравнения (входит почти случайно).
Иное дело – с массой. Если система состоит из тел с массами `m_1`, `m_2`, `m_3` и т. д., то масса всей системы равна `m = m_1 + m_2 + m_3 + ` и т. д. (Если на лифте написано, что максимальный груз, перевозимый лифтом, равен `500` кг, то перед входом в лифт нужно убедиться, что сумма масс вносимых в лифт грузов не превышает `500` кг.) Говорят, что масса – есть аддитивная величина (от английского слова add – добавлять, прибавлять, складывать). А вот температура – не аддитивная величина.
Сила есть аддитивная векторная величина. Если к телу в точке (или к системе тел в разных точках!) приложены силы `vec(F_1)`, `vec(F_2)`, `vec(F_3)` и т. д., то сумма векторов сил `vec(F_1) + vec(F_2) + vec(F_3) + . ` есть осмысленная и даже очень нужная величина. Например, в условиях равновесия тела сумма всех приложенных к нему сил `vec(F_1) + vec(F_2) + vec(F_3) + . = 0`, даже если силы приложены в разных точках тела. Причём это относится не только к твёрдым телам. Если нитка подвешена за два конца к двум гвоздям, а в промежутке перекинута еще через какие-нибудь гвозди, то сначала нужно найти силы со стороны каждого из гвоздей и силу со стороны Земли (силу тяжести) `vec F_1`, `vec(F_2)`, `vec(F_3)`, `…`; при этом говорят, что к нитке приложена сумма сил `vec(F_1) + vec(F_2) + vec(F_3) + . `; в условиях равновесия эта сумма будет равна нулю.
Не так со скоростями. Если система состоит из двух частиц, имеющих в некоторый момент времени скорости `vec(v_1)` и `vec(v_2)`, то это не означает, что в этот момент вся система обладает скоростью равной векторной сумме `vec(v_1) + vec(v_2)`. Никто не запрещает складывать векторы скорости разных частиц; но с точки зрения физики вектор `vec(v_1) + vec(v_2)` ничему приписать нельзя. В этом смысле скорость — не аддитивная величина. Суммой скоростей (векторной суммой) интересуются, когда одно движение накладывается на другое (например, Земля вращается вокруг Солнца, но вместе с Солнцем движется вокруг центра Галактики). А вот сумма скоростей отдельных частиц системы (например, сумма скоростей звезд в Галактике) физического интереса не представляет.
Родственная скорости величина, с которой вы еще не раз встретитесь в курсе физики, импульс материальной точки, равный произведению массы на скорость, `vec p = m vec v` снова — величина аддитивная.
В последнем равенстве мы встречаемся с умножением вектора на скаляр. Поясним эту процедуру.
4. Умножение вектора на скаляр.
Произведением вектора `vec a` на число `k` называют новый вектор `vec b = k vec a`, коллинеарный вектору `vec a`, направленный в ту же сторону, что и вектор `vec a`, если `k > 0`, и в противоположную сторону, если `k < 0`, а модуль `b` равен
где `|k|` — абсолютная величина числа `k`.
Если два вектора коллинеарны, то они отличаются только скалярным множителем. Наоборот, если два вектора отличаются только скалярным множителем, не равным нулю, то они коллинеарны.
В случае, когда `k = 0` или `vec a = 0`, произведение `k vec a` представляет собой нулевой вектор, направление которого не определено.
Если `k = 1`, то согласно (2) `vec b = vec a` и векторы `vec a` и `vec b` равны (рис. 8а).
При `k = — 1` получим `vec b = — vec a`. Вектор `- vec a` имеет модуль, равный модулю вектора `vec a`, но направлен в противоположную сторону (рис. 8б).
Два вектора, противоположно направленные и имеющие равные длины, называются противоположными.
Импульс тела `vec p = m vec v` коллинеарен вектору скорости и направлен с ней в одну сторону, т. к. массы всех тел положительны. Чуть ранее говорилось об аддитивности импульса. Если система состоит из материальных точек с массами `m_1`, `m_2`, `m_3`, `. `, которые в некоторый момент времени имели скорости `vec(v_1)`, `vec(v_2)`, `vec(v_3)`, `…`, т. е. имели импульсы `vec(p_1) = m_1 vec(v_1)`, `vec(p_2) = m_2 vec(v_2)`, `vec(p_3) = m_3 vec(v_3)`, `…`, то вся система в этот момент обладает импульсом
`vec p = vec(p_1) + vec(p_2) + vec(p_3) + . = m_1 vec(v_1) + m_2 vec(v_2) + m_3 vec(v_3) + . `.
При этом каждое из слагаемых здесь должно быть найдено по правилу умножения вектора (скорости данной частицы) на скаляр (её массу), а затем все эти векторы должны быть сложены, например, по правилу многоугольника.
5. Разность двух векторов.
Вычесть из вектора `vec a` вектор `vec b` означает прибавить к вектору `vec a` вектор `- vec b`:
`vec a — vec b = vec a + (- vec b)`;