Вычисление векторного произведения 2D

87

Из википедии:

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

Учитывая, что определение определено только в трех ( или семи, одном и нулевом ) измерениях, как вычислить перекрестное произведение двух двумерных векторов?

Я видел две реализации. Один возвращает новый вектор (но принимает только один вектор), другой возвращает скаляр (но является вычислением между двумя векторами).

Реализация 1 (возвращает скаляр):

float CrossProduct(const Vector2D & v1, const Vector2D & v2) const
{
    return (v1.X*v2.Y) - (v1.Y*v2.X);
}

Реализация 2 (возвращает вектор):

Vector2D CrossProduct(const Vector2D & v) const
{
    return Vector2D(v.Y, -v.X);
}

Почему разные реализации? Для чего мне использовать скалярную реализацию? Для чего мне использовать векторную реализацию?

Я спрашиваю, потому что я сам пишу класс Vector2D и не знаю, какой метод использовать.

Зак Человек
источник
10
Реализация 2 неверна. Вам нужны два вектора, чтобы образовать кросс-продукт.
bobobobo,
7
Реализация 2 поворачивает данный вектор v на -90 градусов. Подстановка -90 в x' = x cos θ - y sin θи y' = x sin θ + y cos θ. Другой вариант этой реализации return Vector2D(-v.Y, v.X);- повернуть v на +90 градусов.
legends2k
3
@ legends2k: Следует отметить, что реализация 2 является расширением использования определителя для оценки перекрестного произведения : просто удалите последнюю строку и столбец. Такое расширение всегда имеет N-1операнды для Nизмерений.
Тим Час
4
В реализации 1 рассчитывается величина перекрестного продукта.
Mateen Ulhaq
@MateenUlhaq рода, это « подписал величина»
Moritz Mahringer

Ответы:

101

Реализация 1 возвращает величину вектора, которая была бы результатом обычного трехмерного перекрестного произведения входных векторов, принимая их значения Z неявно как 0 (т.е. рассматривая двумерное пространство как плоскость в трехмерном пространстве). Трехмерное векторное произведение будет перпендикулярно этой плоскости и, следовательно, будет иметь 0 компонентов X и Y (таким образом, возвращаемый скаляр является значением Z вектора трехмерного перекрестного произведения).

Обратите внимание, что величина вектора, полученного в результате трехмерного перекрестного произведения, также равна площади параллелограмма между двумя векторами, что дает Реализации 1 еще одну цель. Кроме того, эта область подписана и может использоваться для определения того, движется ли вращение от V1 к V2 против часовой стрелки или по часовой стрелке. Также следует отметить, что реализация 1 является определителем матрицы 2x2, построенной из этих двух векторов.

Реализация 2 возвращает вектор, перпендикулярный входному вектору, все еще в той же 2D-плоскости. Не перекрестное произведение в классическом смысле, но непротиворечивое в смысле «дайте мне перпендикулярный вектор».

Обратите внимание, что трехмерное евклидово пространство закрывается операцией перекрестного произведения - то есть перекрестное произведение двух трехмерных векторов возвращает другой трехмерный вектор. Обе вышеупомянутые 2D-реализации так или иначе несовместимы с этим.

Надеюсь это поможет...

Дрю Холл
источник
7
Фактически, реализация 2 - это векторное произведение v и единичного вектора, направленного вверх в направлении z.
mattiast
@mattiast: Верно. Именно так операция «преступника» в 2D описывается в 3D.
Дрю Холл
@mattiast: реализацию 2 можно рассматривать как расширение использования определителя для вычисления перекрестного произведения - просто удалите последнюю строку и столбец. Следует отметить, что реализация 1 эквивалентна:, DotProduct(a, CrossProduct(b))что (очень элегантно!) Согласуется с понятием «перпендикулярного скалярного произведения» (это то, что реализация 1 также [и, возможно, более точно] известна как!).
Тим Час
В вашем первом абзаце величина - это абсолютное значение того, что возвращается. Это не совсем то же самое, что компонент Z. Как вы указываете во 2-м абзаце, вы можете использовать знак креста для отпугивания вампиров ... эээ, я имею в виду, например, чтобы определить, когда вектор уходит, а не входит в контур многоугольника.
Питер Кордес,
68

Вкратце: это сокращенное обозначение математического хака.

Длинное объяснение:

Вы не можете сделать кросс-произведение с векторами в 2D-пространстве. Операция там не определена.

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

Если вы расширите векторы таким образом и вычислите перекрестное произведение такой расширенной пары векторов, вы заметите, что только z-компонент имеет значимое значение: x и y всегда будут равны нулю.

По этой причине z-компонент результата часто просто возвращается как скаляр. Этот скаляр можно использовать, например, для нахождения намотки трех точек в 2D-пространстве.

С чисто математической точки зрения перекрестного произведения в 2D-пространстве не существует, скалярная версия - это взлом, а двумерное перекрестное произведение, возвращающее двумерный вектор, вообще не имеет смысла.

Нильс Пипенбринк
источник
«например, можно использовать для нахождения трех точек намотки в двухмерном пространстве» @ Нильс Пипенбринк, что ты подразумеваешь под намоткой в ​​этом контексте?
Надер
1
@NaderBelal Я полагаю, что обмотка здесь будет означать - если мы перейдем от точки a к b к c, будем ли мы двигаться по часовой стрелке или против часовой стрелки, с точки зрения угла, который мы только что охватили.
Амит Томар
12

Еще одно полезное свойство перекрестного произведения состоит в том, что его величина связана с синусом угла между двумя векторами:

| axb | = | а | . | б | . синус (тета)

или же

синус (тета) = | axb | / (| а |. | б |)

Итак, в реализации 1 выше, если заранее известно , что aи bявляются единичными векторами, то результатом этой функции будет именно то значение sine ().

Альнитак
источник
1
... который также в два раза больше площади треугольника между вектором a и вектором b.
Тим Ловелл-Смит
5

Реализация 1 - это скалярное произведение двух векторов. Лучшее из известных мне справочников по 2D-графике - это превосходная серия Graphics Gems . Если вы делаете скретч-2D-работу, очень важно иметь эти книги. В томе IV есть статья под названием «Удовольствие от продуктов Perp Dot», в которой рассказывается о множестве ее применений.

Одно из основных применений скалярного произведения - получить масштабированный sinугол между двумя векторами, точно так же, как скалярное произведение возвращает масштабированный cosугол. Конечно, вы можете использовать скалярное произведение и расчётное скалярное произведение вместе, чтобы определить угол между двумя векторами.

Вот пост об этом, а вот статья Wolfram Math World.

Билл Бердик
источник
3

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


источник
3

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

Из источника Chipmunk2D :

/// 2D vector cross product analog.
/// The cross product of 2D vectors results in a 3D vector with only a z component.
/// This function returns the magnitude of the z value.
static inline cpFloat cpvcross(const cpVect v1, const cpVect v2)
{
        return v1.x*v2.y - v1.y*v2.x;
}
Брэм
источник