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

Как определить направление векторов m e w

  • автор:

Направление и расстояние от одного объекта до другого.

Если вычесть координаты одной точки в пространстве из координат другой, то получим вектор, который “выходит” из второй точки и “заканчивается” в первой:

// 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. 

Понимание векторной арифметики

Векторная арифметика — основа 3D графики, физики и анимации, и, для получения максимальной отдачи от Unity, весьма полезно досконально разбираться в этой теме. Ниже приведены описания основных операций и несколько советов о том, для чего они могут быть использованы.

Сложение

При сложении 2 векторов результат эквивалентен тому, что получится если исходные векторы принять за следующие друг за другом “шаги”. Заметьте, что порядок двух слагаемых не важен, т.к. в любом случае результат будет одинаковый.

Если первый вектор принять за точку в пространстве, то второй вектор можно интерпретировать как сдвиг или “прыжок” из этой точки. Например, чтобы для поиска точки 5-тью единицами выше точки на земле, вы могли бы использовать следующий расчёт:-

 var pointInAir = pointOnGround + new Vector3(0, 5, 0); 

Если векторы представляют собой силы, то более естественно будет думать о них с точки зрения их направления и величины (величина определяет мощность силы). Сложение двух векторов силы в результате даёт новый вектор, эквивалентный комбинации этих сил. Этот концепт зачастую очень полезен при применении сил с различными раздельными компонентами, которые работают одновременно (например, на летящую вперёд ракету может влиять встречный или боковой ветер).

Вычитание

Вычитание векторов чаще всего используется, чтобы узнать расстояние и направление одного объекта относительно другого. Заметьте, что при вычитании порядок параметров имеет значение:-

// The vector d has the same magnitude as c but points in the opposite direction. var c = b - a; var d = a - b; 

Как и с обычными числами, прибавление отрицательного вектора — это то же самое, что и вычитание положительного.

// These both give the same result. var c = a - b; var c = a + -b; 

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

Скалярные умножение и деление

Говоря о векторах, в порядке вещей обращаться к обычным числам (например, значениям типа float) как к скалярам. Это значит, что у них есть только “размер” или величина, в то время как у векторов есть и величина и направление.

Умножение вектора на скаляр даёт в результате вектор, с тем же направлением, что и исходный вектор. Тем не менее, величина нового вектора равна исходной величине умноженной на скалярное значение.

Аналогично, скалярное деление делит исходную величину вектора на скаляр.

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

Когда любой вектор делится на собственную величину, то в результате получается вектор величиной 1, известный как нормированный (единичный) вектор. Если нормированный вектор умножить на скаляр, то величина результата будет равна значению скаляра. Это полезно, когда направление силы постоянно, а величина — нет (например, сила от колеса автомобиля всегда толкает вперёд, но её мощность контролируется водителем).

Скалярное произведение (Dot Product)

Скалярное произведение получает 2 вектора и возвращает скаляр. Этот скаляр равен произведению величин этих векторов, умноженному на косинус угла между ними. Когда оба вектора — нормированные, косинус по сути дела утверждает, как далеко первый вектор простирается в направлении второго (или наоборот — порядок параметров роли не играет).

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

Скалярное произведение — это очень простая операция, которую, при некоторых обстоятельствах, можно использовать вместо функции Mathf.Cos или операции векторных величин (оно не делает в точности то же самое, но иногда эффект получается одинаковый). Тем не менее, вычисление скалярного произведения на уровне процессора проходит значительно быстрее, так что оно может оказаться ценной оптимизацией.

Векторное произведение (Cross Product)

Другие операции предназначены для 2D или 3D векторов и для действительных векторов с любым числом измерений. Векторное произведение же, напротив, имеет смысл применять только для 3D векторов. Оно использует 2 вектора как входную информацию и возвращает ещё один вектор в качестве результата.

Итоговый вектор перпендикулярен двум исходным векторам. Можно использовать “правило левой руки”, чтобы запомнить направление выходного вектора относительно исходных векторов. Если первый параметр совпадает с большим пальцем руки, а второй параметр с указательным пальцем, то результат будет указывать в направлении среднего пальца. Если использовать обратный порядок параметров, то тогда итоговый вектор будет указывать в противоположном направлении, но его величина не изменится.

Величина результата равна произведению величин исходных векторов, умноженному на синус угла между ними. Некоторые полезные значения функции синуса указаны ниже:-

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

Вектора

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

  • указатель на данные
  • длина
  • вместимость

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

fn main() < // Итераторы могут быть собраны в вектора let collected_iterator: Vec= (0..10).collect(); println!("(0..10) собраны в: ", collected_iterator); // Макрос `vec!` может быть использован для инициализации вектора let mut xs = vec![1i32, 2, 3]; println!("Исходный вектор: ", xs); // Вставка нового элемента в конец вектора println!("Добавим 4 в конец вектора"); xs.push(4); println!("Вектор: ", xs); // Ошибка! Неизменяемые вектора не могут увеличиваться collected_iterator.push(0); // ИСПРАВЬТЕ ^ Закомментируйте эту строку // Метод `len` отдаёт количество элементом, сохранённых в векторе println!("Длина вектора: <>", xs.len()); // Индексация выполняется при помощи квадратных скобок (индексация начинается с 0) println!("Второй элемент: <>", xs[1]); // `pop` удаляет последний элемент из вектора и возвращает его println!("Последний элемент: ", xs.pop()); // Выход за пределы индексации вызывает панику println!("Четвёртый элемент: <>", xs[3]); // ИСПРАВЬТЕ ^ Закомментируйте эту строку // По векторами легко итерироваться println!("Содержимое `xs`:"); for x in xs.iter() < println!("><>", x); > // Также можно итерироваться по вектору с получением индекса элемента // (который будет содержаться в отдельной переменной `i`) for (i, x) in xs.iter().enumerate() < println!("<>-ый элемент имеет значение <>", i, x); > // Благодаря `iter_mut`, у изменяемых векторов можно менять значения // во время итерирования for x in xs.iter_mut() < *x *= 3; >println!("Обновлённый вектор: ", xs); > 

Подробную информацию о методах объекта Vec можно почитать в разделе модуля std::vec

Как найти косое (псевдоскалярное) произведение векторов?

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

если векторы заданы координатами a(x1, y1), b(x2, y2) то косое произведение [a, b] = x1y2 — x2y1.

Вопрос 1: Каким образом каждый вектор задается одной точкой? Я правильно понял, что при такой записи предполагается, что начало вектора совпадает с началом координат, а указанные координаты вектора - это координаты конца вектора? Вопрос 2: Если в моем случае каждый вектор задан двумя точками, то мне надо перед вычислением их косого произведение преобразовать каждый из векторов так, чтобы их начала совпадали с началом координат?

  • математика
  • вычислительная-геометрия

Отслеживать

397 2 2 золотых знака 10 10 серебряных знаков 39 39 бронзовых знаков

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *