Чи потрібні мені точка та векторний об’єкт? Або просто використовувати об’єкт 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, або немає проблем із визначенням точки як вектора?

Я знаю, що вектор має величину та напрямок, але я бачу так багато людей, які використовують вектор, щоб просто представляти положення об'єкта.


1
Оскільки позиція є просто вектором з (0,0 {, 0}), вектор прекрасний у використанні.

Відповіді:


8

Навряд чи виникнуть проблеми зі складанням визначень та трактуванням точок як векторів - але будьте обережні, оскільки деякі API мають клас "Point", який, можливо, вам знадобиться використовувати (для представлення, наприклад, вершин багатокутників) і якщо Ви визначаєте свій власний клас, Ви хочете мати можливість переносити їх туди-назад.

Що я б хотів зробити, це ставитися до них рівнозначно у вашому коді; якщо ви використовуєте вектор і точку взаємозамінно, то немає жодної причини, щоб у вашому оголошенні функції Line () говорилося про "startVector" і "endingVector". Я б настійно закликав повернутися до

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

Бали - це те, що представляють ці параметри, навіть якщо для цього вони використовують клас Vector.


Я б пішов на крок далі і мав typedef Vector Pointдесь у заголовку, який визначає точки. Таким чином, це виглядає і здається Point, що нікому не залишається чухати голову при використанні, чому його називають, Vectorале з внутрішньої сторони це лише одна база коду.
tpg2114

4

Просто використовуйте об’єкт Vector. Навіть якщо ви вважаєте, що це / було використано неправильно в минулому, люди цього очікують. Плюс до цього, не обов’язково неправильно використовувати вектор як точку. І це важко зробити поза дискусією, оскільки обидві структури даних вимагають однакових примітивних типів. Єдині відмінності полягають у функціях членів, і досить просто розмістити їх у одному класі, оскільки між ними не так вже й багато способів суперечливих методів.

Оскільки ви навчаєтесь, добре дізнатися, що робити те, що очікують люди, найчастіше найкращий спосіб робити (для дрібницьких варіантів, як той, що подається).


Функції-члени не є єдиною різницею між точками та векторами; так само є wскладовою, яка є критичною.
kevintodisco

3

Точки - це місця в просторі. Щойно у вас є система координат, ви можете описати ці точки як відстань і напрямок від початку (вектор). Тому цілком розумно використовувати вектори для опису початкової та кінцевої точок лінії.

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

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


2

Для визначення точки потрібен лише один вектор. Щоб визначити лінію, вам потрібно два. Як правило, у вас є або дві точки, які лежать на прямій, або один вектор, що представляє собою точку, що лежить на прямій, а інший вектор, що представляє напрямок лінії.

Немає проблем із визначенням точки як вектора, оскільки точка IS вектор, з напрямком, рівним її координатам, і величиною, що дорівнює його відстані від 0,0.

Таким чином, вам не потрібні два окремі класи для представлення точки і "Vector2d", хоча точка, імовірно, може бути підкласом Vector2d з різними функціями членів, безпосередньо пов'язаними з вашим малюнком або обробкою, тоді як Vector2d може виконувати лише суворі функції векторної математики, наприклад крапкові вироби.


2

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

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

Не маючи wкомпонента векторного набору, 0можна повернутися, щоб вкусити вас; це призводить до помилок, які досить складно знайти. Щоб бути в безпеці, ви можете зробити Pointклас , який успадковує від Vectorкласу і явно встановлює wв 1, де Vectorклас по замовчуванням wдля 0.


2
Багато векторних класів не використовують w компонент явно; дуже багато трактують це як неявний елемент або мають те, що становить клас "ProjectiveVector", який реалізує його, але стільки коду двигуна (усе, що стосується рендерингу, по суті) використовує "класичний" 3-векторний, який переносить компонент aw абсолютно зайвий. Це деталізація реалізації, а не істотна частина векторів чи точок.
Стівен Стадницький

@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, який не має всіх зайвих функцій.


Методи додаються до прототипу, тому це не проблема.
JCM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.