Нужен ли мне объект Point и Vector? Или просто использовать объект Vector для представления точки - это нормально?

18

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

Изначально у нас был конструктор Point, например:

var Point = function( x, y ) {
    this.x = x;
    this.y = y;
};

Но затем мы начали добавлять к ней векторную математику, и они решили переименовать ее в Vector2d.

Но теперь некоторые методы немного сбивают с толку (по крайней мере, на мой взгляд), такие как следующие, которые используются для построения строки:

//before the renaming of Point to Vector2, the parameters were startingPoint and endingPoint
Geometry.Line = function( startingVector, endingVector ) {
    //...
};

Я должен сделать конкретный конструктор для объекта Point, или нет проблем с определением точки как вектора?

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

JCM
источник
1
Поскольку позиция - это просто вектор из (0,0 {, 0}), вектор можно использовать.

Ответы:

8

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

Что бы я ни делал, это относился бы к ним одинаково в вашем коде; если вы используете вектор и точку взаимозаменяемо, то нет никаких причин, чтобы в вашем объявлении для функции Line () говорилось о «initialVector» и «endVector». Я настоятельно рекомендую вернуться к

Geometry.Line = function( Vector startingPoint, Vector endingPoint ) {
    //...
};

Точки - это то, что представляют эти параметры, даже если они используют класс Vector для этого.

Стивен Стадницки
источник
Я бы пошел дальше и получил бы typedef Vector Pointзаголовок, который определяет точки. Таким образом, это выглядит и ощущается как Point, никто не остается поцарапать голову при использовании его, почему он вызывается, Vectorно на внутренней стороне это только одна база кода.
tpg2114
4

Просто используйте объект Vector. Даже если вы чувствуете, что это использовалось / использовалось неправильно в прошлом, это то, что люди ожидают. Кроме того, не обязательно неправильно использовать вектор в качестве точки. И это было бы трудно сделать вне обсуждения, поскольку обе структуры данных требуют одинаковых примитивных типов. Единственными отличиями будут функции-члены, и достаточно просто поместить их в один класс, так как между ними не так много противоречивых методов.

Так как вы учитесь, хорошо учиться тому, что выполнение того, что ожидают люди, часто является лучшим способом сделать что-то (для тривиальных вариантов, подобных представленному).

MichaelHouse
источник
Функции-члены не единственная разница между точками и векторами; так же и wкомпонент, который имеет решающее значение.
Kevintodisco
3

Точки - это места в космосе. Если у вас есть система координат, вы можете описать эти точки как расстояние и направление от начала координат (вектор). Поэтому совершенно разумно использовать векторы для описания начальной и конечной точек линии.

Просто знайте, что все точки могут быть представлены как вектор, но векторы не являются точками. Большинство векторов, например, скорость, нормаль и т. Д., Не имеют никакого чувства местоположения.

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

кругозор
источник
2

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

Нет проблем с определением точки как вектора, потому что точка - это вектор с направлением, равным ее координатам, и величиной, равной ее расстоянию от 0,0.

Таким образом, вам не нужны два отдельных класса для представления Point и Vector2d, хотя Point может предположительно быть подклассом Vector2d с различными функциями-членами, непосредственно связанными с вашим рисованием или обработкой, в то время как Vector2d может выполнять только строгие математические функции вектора, такие как точечные продукты.

Эрик Б
источник
2

Да, можно использовать один Vectorкласс для определения как точек, так и векторов, при условии, что wкомпонент вектора равен0 .

Ключ разница между точкой и вектором является то , что точка представляет собой физическое местоположение в пространстве, смещение от начала координат, в то время как вектор представляет собой направление . Точка может быть переведена, вектор не может . wКомпонент 2- или 3-мерного Vectorкласса является то , что позволяет компоненту перевода матрицы преобразования вступили в силу. Если wесть 1, то будет применен перевод и ротация; если это так 0, то будет применено только вращение.

Отсутствие wкомпонента набора векторов 0может вернуться к вам; это приводит к ошибкам, которые довольно сложно отследить. Чтобы быть в безопасности, вы можете сделать Pointкласс , который наследует от Vectorкласса и явно устанавливает wв 1, где Vectorкласс по умолчанию wдля 0.

kevintodisco
источник
2
Многие векторные классы не используют компонент w явно; многие рассматривают его как неявный элемент или имеют то, что составляет класс «ProjectiveVector», который его реализует, но большая часть кода движка (по сути, всего вне рендеринга) использует «классический» 3-вектор, который содержит компонент w совершенно лишнее. Это деталь реализации, а не существенная часть векторов или точек.
Стивен Стадницки
@StevenStadnicki Это правда, но для того, чтобы класс представлял и точку, и вектор, wкомпонент должен присутствовать, иначе нет способа определить, как должен использоваться объект.
Kevintodisco
1
@ ktodisco Я думаю, что способ определить, как его следует использовать, - это посмотреть, в каком контексте он используется.
JCM
1
Не хватило времени на редактирование комментария :(. Я собирался сказать, что если части движка, которые используют класс, определяют контекст, в котором он будет использоваться, то это работает.
kevintodisco
2

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

В математике векторы иногда используются для представления позиции. Когда используется в этом смысле, вектор представляет, где некоторая сущность расположена относительно начальной точки. Например, предположим, что вы делаете дерьмо и хотите отслеживать, где находится корабль игрока в игровой зоне. Если вы рассматриваете нижний левый угол игровой зоны как (0, 0), то вы можете представить местоположение игрока с помощью Vector:

   * Player (3,3)
  /
 /
. (0,0)

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

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

             * (8, 2)
             |
     . (0,0) |
             |
             * (8, -2)

Таким образом, один конец линии находится на 8 единиц справа и на 2 единицы выше центра игрового поля, а другой - на 8 единиц справа и на 2 единицы вниз.

Просто чтобы быть ясно, это не значит, что вы должны использовать Vectorкласс вместо Pointкласса. Это всего лишь один из способов осмысления этой ситуации, который может помочь решить, как реализовать эти идеи.

Кевин - Восстановить Монику
источник
Вектор как смещение к другой точке в пространстве все еще должен рассматриваться как точка в относительных координатах. Называть это вектором неправильно, если говорить об игровом движке.
Kevintodisco
0

Это зависит от реализации. Если вам нужно иметь методы на Vector2d вместо его прототипа, то для этого есть цена, учитывая количество очков, которое вам понадобится в игре, причем главное. Это просто, как работает JavaScript. В этой ситуации лучше создать класс Point2d, который не имеет всех ненужных функций.

Dreta
источник
Методы добавляются в прототип, так что это не проблема.
JCM