Переваги використання типу даних Vector2 над окремими змінними x & y

Мені дуже цікаво, чому багато людей і ігрові двигуни використовують Vector2 як свою систему координат замість традиційного значення x і y.

Чи є така користь?

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

3
Чому ми використовуємо int замість 32 bool ? Тому що це більш зручно.
додано Автор bitbonk, джерело
Ніщо не заважає вам писати вбудовану функцію, яка робить окремі параметри для зручності побудови двох Vector2 для вас. Але з досвіду на практиці ви фактично заощаджуєте час, використовуючи Vector2, коли ваша система стає складною, як управління відносними об'єктами: object = object-> parent; while (об'єкт) {render_pos + = object-> pos; object = object-> parent; } Заощаджує багато записів у довгостроковій перспективі.
додано Автор Betlista, джерело
Чесно кажучи, все, що має «ледве користь, окрім організації коду», мені здається дуже корисним.
додано Автор Nax, джерело
З іншого боку, написання Object.pos + = Object.mov; значно швидше і простіше, ніж Object.x + = Object.movX; Object.y + = Object.movY;
додано Автор cst1992, джерело
Якщо введення тексту має значний внесок у "речі, які сповільнюють вас", то або ви не витрачаєте достатньо часу на роздуми про код або ваші проблеми виходять за межі тривіальності. Речі, які сповільнюють вас у реальних проблемах світу, - це розробка логіки та відстеження причин помилок/помилок, які не мають корисного повідомлення. У цих речах хороша організація золота .
додано Автор Cornelius Sicker, джерело
@ R.Schmitz Що було б найбільш "не приємно" тут, дозволяючи недосвідченому розробнику продовжувати думати, що друкування є проблемою, про яку вони ніколи не повинні витрачати час. Жорстоке заперечує комусь можливість переорієнтувати своє мислення, коли у них є така шкідлива помилка. Моє твердження є вірним. Невизначеною можливістю є те, що ОП переоцінює внесок типізації у свій час розвитку (іншими словами, попередник є помилковим.), Але я думав, що це безсумнівно, оскільки інші два варіанти настільки абсурдні.
додано Автор Cornelius Sicker, джерело
@ R.Schmitz Я часто сценарій в Notepad ++, і я до сих пір не турбуватися про друкування. Ваш IDE не заощадить введення тексту; це зменшує вигляд імен, які я досі не вважаю великою проблемою, але розумію бажання уникати. Моя заява говорить ОП, як абсурдно це турбуватися про друкування (і розуміння це смішно важливо) і дві речі, на які вони повинні зосередитися, замість цього. Це абсолютно конструктивно, хоча я вибрав різкі слова, щоб отримати відповідний акцент. І так, ви позбавляєте їх шансу на поліпшення, відмовляючись вказувати на велику помилку у своєму мисленні.
додано Автор Cornelius Sicker, джерело
@Aethenosity, наприклад, Object.x + = 1 має бути виконано за допомогою Object.pos + = Vector2 (1, 0). або деякі функції приймають тільки Vector2, наприклад, наприклад, малювання прямокутника в деяких ігрових движках вимагають використання Vector2, draw_rect (Vector2 (x, y), Vector2 (ширина, висота)) без Vector2, ви можете робити речі швидше, як draw_rect (x, y, ширина, висота). Він організовує ваш код, жертвуючи швидкістю написання коду, і нічого ви не можете зробити з ним, ви не можете скоротити його, використовуючи щось на зразок Vec2 = Vector2, це призведе до помилок
додано Автор user116696, джерело
@Nax, так .. але він повинен бути необов'язковим, ви навіть можете створити свою власну систему Vector2 на будь-якій мові, це просто дратує мене IMO.
додано Автор user116696, джерело
Як це уповільнило вас? З цікавості.
додано Автор Allen, джерело
@ jpmc26 "Ваш IDE не рятує вас від введення" Що ? Ви впевнені, що дійсно використовуєте IDE? Легко менше половини мого коду фактично набрано, більшість з них генерується IDE за допомогою ярликів тощо. єдиний цегла робить також поза мною. І ваше визначення "заперечення" також є сумнівним у кращому випадку, але гей, ви не збираєтеся бачити ці моменти, коли я вам скажу так ... так. Гарного дня.
додано Автор pantsburgh, джерело
@ jpmc26 У мене 7 років досвіду, і я безумовно турбуюся про друкування. Ось чому я використовую IDE та інших помічників, щоб набрати найменше часу, витраченого на рішення. Я навряд чи вірю, що ти кодуєш у блокноті. Я також не заперечую нічого, немає необхідності захищатися і викидати "розумні" слова. Ваша заява вірна в загальному сенсі, але краще показувати свої навички, ніж допомагає. особливо для початківців.
додано Автор pantsburgh, джерело
@ jpmc26 Я не знайшов нічого, що б змусило мене подумати "старший розробник з досвідом 5 років". Він, здається, ще не використовує IDE, і все питання про нього все ще цікаво, чому дані структуровані в розумних типів даних. Я припускаю, що ви дотримуєтеся політики "бути приємною" і просто суворо неправильно оцінюєте рівень кваліфікації ОП, тому що розповідаючи початківцю " ви не витрачаєте достатньо часу на міркування про код або ваші проблеми виходять за межі тривіальних > "просто не приємно.
додано Автор pantsburgh, джерело

7 Відповіді

Перш за все, це набагато менше перешкод. Якщо у вас є позиція, швидкість і прискорення, це вже 6 змінних, з якими ви маєте справу, 9 в 3d.

По-друге, і це найважливіша частина, вона надає вам доступ до багатьох способів їх використання або зміни. Наприклад, отримання довжини вектора, його нормалізація, додавання їх разом, точковий продукт, перехресний продукт у 3d, тощо. .

Що стосується уповільнення, я не впевнений, чому це зробить це. Окрім того, що потрібно створити новий вектор замість 2-х змінних, потрібно звернути увагу лише на використання vector.x і vector.y, які не повинні бути такими жорсткими і не гіршими, ніж vectorX і vectorY

40
додано
Коментарі не для розширеного обговорення; цю бесіду було переміщено до чату .
додано Автор Alexandre Vaillancourt, джерело
У мовах, які підтримують прозорі типи структур, декларація структури може, як правило, оброблятися на машинному рівні таким чином, що це принаймні так само ефективно, як дві окремі декларації int або float. Однак у мовах, які не підтримують такі типи, інкапсулювання пар чисел у об'єкти класу накладатиме вартість, яку можна було б уникнути, обробляючи номери окремо.
додано Автор Brad Roekle, джерело
@supercat з іншого боку, багато комп'ютерів можуть робити векторну арифметику, яка прискорює обчислення 2, 3 або навіть 4 рази в залежності від кількості координат
додано Автор Bálint, джерело

Порівняйте підписи функцій обох версій RotatePoints .

Одинокі змінні:

void RotatePoints(
   float *out_x, 
   int x_interleave_out,
   const float *in_x, 
   int x_interleave_in,
   float *out_y, 
   int y_interleave_out, 
   const float *in_y, 
   int y_interleave_in,
   float angle, 
   int count
) 
{
  float s = sinf(angle);
  float c = cosf(angle);

  while(count--){
    *out_x = *in_x * c + *in_y * -s;
    *out_y = *in_x * s + *in_y * c;
    out_x += x_interleave_out;
    out_y += y_interleave_out;
    in_x += x_interleave_in;
    in_x += y_interleave_in;
  }
}

Порівняно з використанням структур/класів:

void RotatePoints(
  Vector2 *out, 
  const Vector2 *in, 
  float angle, 
  int count)
{
   Matrix2x2 rotation;
   rotation.SetRotation(angle);

   while(count--){
     *out++ = *in++ * rotation;
   }
}

Вам потрібно повідомити першу версію, якщо ваші масиви x та y перемежовуються або розділяються:

float all_together[200];//x0,y0,x1,y1,x2,y2...

Або:

float x[100];
float y[100];

Набагато менше розбійниць просто мати масив Vector2 і передавати його, і внутрішній код більш читабельний.

І чим складнішою є математика, тим метр і хайєр вона отримує, якщо ви не використовуєте класи Vector і Matrix;

15
додано
Тому що він покаже лише один раз, коли ви досягаєте розширених проблем . Використання окремої змінної є більш короткочасним. Але коли ви потрапили до розширених тем, де це стає нездійсненним.
додано Автор Betlista, джерело
@ R.Schmitz Plus, він може навіть не знати c. Напр. У Unity, ви не програмуєте з c/c ++, ви просто працюєте з посиланнями (Сподіваюся, що це був пункт їх у цьому коді: D). Структура циклу, можливо, не так зрозуміла для програміста, що теж не знає c. (Як приклад)
додано Автор Jon, джерело
Цей код трохи вищий, ніж рівень кваліфікації питання. Ви навіть вводять вказівники на це і використовуєте ... 8 (?) Параметрів для того, що має бути таким же, як 2 Vector2s?
додано Автор pantsburgh, джерело
Ах так, це точно суть моєї відповіді, але я відчуваю, що вам не доведеться йти що просунулося, щоб продемонструвати це. Я маю на увазі, у мене є 7 років досвіду програмування, але тільки дуже мало з C/C + +, і я не розумію, що відбувається тут. OP говорив про ints x і y проти Vector2, але я не маю ідеї, яка є реальною x та y у вашому першому прикладі.
додано Автор pantsburgh, джерело

Readability > Writeability

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

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

Найменування речей

Тепер у вас можуть виникнути труднощі з тим, як draw_rect (Vector2 (x, y), Vector2 (ширина, висота)) має бути більш читабельним, ніж draw_rect (x, y, width, height ) , але, чесно кажучи, обидва вони не є такими читабельними, як могли б бути.

Подивіться на цей псевдокод:

position = Vector2(x, y)
size = Vector2(width, height)
draw_rect(position, size)

Yes, this takes 2 lines more and in the beginning I also thought that was bad. It isn't though. Giving things names makes this take less brain power to read, which you will be very thankful for as soon as the program gets more complex. Especially when you're debugging it. Найменування речей well will also improve other things and make you faster in the long run.

Ще дуже короткий, але трохи довший запуск

Ви згадали Object.x + = 1 vs Object.pos + = Vector2 (1, 0) Знову ви маєте рацію, ваш шлях швидше для цього (єдиний рядок). Але давайте подивимося на мінімально складніший клас, який ви можете мати:

position;
velocity;

void UpdatePosition(){
    position += velocity;
}

Порівняйте з:

xPosition;
yPosition;
xVelocity;
yVelocity;


void UpdatePosition(){
    xPosition += xVelocity;
    yPosition += xVelocity;
}

Це швидше для читання і для запису. До речі, з таким маленьким прикладом це не suuuper прихований, але ви помітили друкарську помилку у другій версії? Це легко пропустити, особливо якщо клас є більш складним, ніж цей нереально маленький приклад (Там тема ...). Це одна помилка, що не може статися при використанні Vector2.

IDE

Ви не можете його скоротити, використовуючи щось подібне до Vec2 = Vector2

Можливо, ви працюєте над завданням школи, де вам не дозволяється використовувати IDE. Якщо ви цього не зробите, скористайтеся ним і знайдіть ярлик автозаповнення (більшу частину часу це Ctrl + пробіл).

Потім ви можете написати "Vec" і використовувати цей ярлик, і IDE покаже вам список всіх класів, які починаються з "Vec". Я не думаю, що будь-який професійний кодер працює без цього, тому що це набагато швидше. Альтернативою є навчитися кожен клас напам'ять, з правильним введенням до одного символу. Ніхто не має часу на це, особливо в діловому світі, де час - гроші.

10
додано
Якщо ви не можете скористатися автозаповненням, не викликайте ваш векторний тип Vector2 для початку, викликайте vec2 або просто vec, якщо у вас є в основному 2D гра.
додано Автор bitbonk, джерело
Я дивуюся, що ви не згадали, що вам навіть не потрібно робити object.pos + = Vector2 (1, 0) (принаймні, поза C#, якщо Vector2 є структурою), тому що ви можете просто зробити object.pos.x + = 1 .
додано Автор Nic Hartley, джерело
"Ви правильно, що (трохи) уповільнює написання цього коду." Це очевидно невірно в будь-якій програмі, де речі рухаються в більш ніж одному напрямку. Написання коду, який перетворює координату або вектор в декількох вимірах, було б значно важче записувати.
додано Автор Cornelius Sicker, джерело
Я вважаю, що в методі "оновлення позиції" є помилка. Це має бути yPosition + = yVelocity вірно? Замість yPosition + = xVelocity?
додано Автор Allen, джерело
@Aethenosity Точно, щось подібне може легко статися під час набору тексту або копіювання, особливо якщо ви пам'ятаєте про це.
додано Автор pantsburgh, джерело
@ jpmc26 Якщо ви подивитеся на приклади OP дали (або перший рядок у розділі "Все ще дуже короткий, але трохи довше запускається" у цій відповіді), то більше коду можна написати у версії Vector2. Що займе більше часу. Ось чому я написав " той код", а потім дав приклад, як буде швидше писати в інших місцях. Ви читали більше, ніж перший абзац, перш ніж ви судили, чи не так?
додано Автор pantsburgh, джерело
@NicHartley Тому що ви втрачаєте контекст, який дає вам Vector2. Навіть якщо змінюється лише одне значення, я все одно віддаю перевагу Vector2 oneStepRight = Vector2 (1,0) . Vector2 просто ... відчуває себе правильно , що є рух (або розмір, швидкість тощо) в 2-мірному просторі. У результаті, коли я хочу зосередитися на механіці гри, мені не потрібно дбати про плавання або подвійні або ints або про кількість розмірів, я просто повинен зробити position + = oneStepRight .
додано Автор pantsburgh, джерело

Перевантаження оператора.

Vector v3 = v2 + v1;

Зараз у вашому коді є тільки одне місце, де ви повинні писати, тестувати та налагоджувати векторні додатки, на відміну від десятків, сотень або тисяч.

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

8
додано

Using structures & classes in place of a pile of primitive variables allows us to focus more of our attention on the higher levels of problem solving.

Знято з коду Завершено:

Зменшити складність - головна мета розробки та створення програмного забезпечення   перемагає складність. Мотивація багатьох програм   практик полягає у зменшенні складності програми та зменшенні складності   є, мабуть, найважливішим ключем до того, щоб бути ефективним програмістом.

     

Програма в умовах проблемного домену - інший особливий метод   Справа зі складністю полягає в тому, щоб працювати на найвищому рівні   абстракції. Один із способів роботи на високому рівні абстракції - це   працювати з точки зору проблеми програмування, а не комп'ютера   рішення науки.

Використання векторного класу/структури відтворюється в обох цих точках.

2
додано

Такі ж причини, що і примітивна манія - це запах коду, який застосовується до використання вектора замість окремих змінних. Vector2D/3D - це лише окремий випадок уникнення примітивів.

1
додано

Математично вектор є точкою у векторному просторі . Це щось з реальною фізичною актуальністю - простір, в якому ми живемо, в основному векторний простір.

The individual components x and y are not. They depend on a choice of coordinate frame, and generally there is no clear reason why some particular coordinate frame should be used. It's an implementation detail, so it's best encapsulated in an opaque type. Indeed, you'll mostly access individual components in very simple applications like 2D platformers, but in anything with somewhat serious physics handling you'll much more typically have offsets pointing in some direction that's unrelated to the coordinate axes. Doing that with coordinates would always require basically duplicating each calculation.

1
додано