Зігнутий рух між двома точками


15

Яка хороша техніка, щоб об’єкт міг рухатися між точками приємним вигнутим рухом?

Кінцеве положення також може бути в русі, наприклад, траєкторія навісної ракети.

Відповіді:


11

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

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

Ви можете визначити, чи слід обертати за годинниковою стрілкою або проти годинникової стрілки, дивлячись на знак перехресного виробу між двома векторами.


[Редагувати] XNA-код (у мене немає XNA, щоб перевірити це):

//Once a frame:

//Get vector spanning from missile to target
Vector2 vectorToTarget = target.Position - missile.Position;

//Convert to Vector3 to do cross-product
Vector3 vectorToTarget3 = new Vector3(vectorToTarget, 0);
Vector3 missileVelocity3 = new Vector3(missile.Velocity, 0);

//Rotate clockwise/counter-clockwise is determined by sign of cross-product
int crossProductSign = Vector3.Cross(missileVelocity3, vectorToTarget3).Z;

//Positive cross-product means rotate counter-clockwise, negative is clockwise
double rotationAngle = 0;
if(crossProductSign > 0)
    rotationAngle = -0.05;
else if(crossProductSign < 0)
    rotationAngle = 0.05;

//I'm not sure how to do rotation in XNA, but the internets tell me it's something like this:
missile.velocity = Vector2.Transform(missile.velocity, Matrix.CreateRotationZ(rotationAngle))

Зауважте, що, оскільки rotationAngleмає лише три можливі значення, усі можливі значення Matrix.CreateRotationZ(rotationAngle)можна кешувати, тому вам не доведеться називати це кожен кадр.


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

@anonymouse: впевнено, спробуйте це
BlueRaja - Danny Pflughoeft

15

Існує дві можливі методи:

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

У цьому випадку потрібно відстежувати положення та швидкість руху об'єкта. Кожен кадр дивиться на напрямок до цілі та напрям поточного руху та відповідно регулює швидкість.

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

Другий прийом - використання параметричного методу. Це корисно для анімації речей, де ви хочете точно та передбачувано вразити свою ціль. У цьому випадку ви зазвичай приймаєте "час" як свій параметр і ставите його у якусь функцію.

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

XNA також забезпечує ряд функцій інтерполяції та вигнутого руху. Погляньте на документацію дляVector2 та дляMathHelper . Вони забезпечують деякі функції інтерполяції, які ви можете використовувати і навіть комбінувати, щоб робити цікаві речі. Наприклад, вистрілення ракети: Lerp(лінійний інтерполятор) позицію ракети від її початкової точки до цільової позиції, а також лерпувати це цільове положення від якоїсь початкової цілі до реальної (мінливої) позиції об'єкта. Це дасть приємний ефект "фіксації".

(Існують також деякі функції для створення кривих, наприклад: CatmulRom , Hermite. Це, мабуть, важче успішно використовувати з рухомою ціллю.)

Якщо ви заглянете в "полегшення" (в контексті анімації), ви можете отримати ще цікаві функції інтерполяції, які можуть дати вам такі цікаві ефекти, як прискорення.

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


3

Ви можете шукати синусоїди або, можливо, криві Безьє . Я не знаю, чи нормально синусоїдальний підхід, але я не можу зрозуміти, чому це було б так погано.


Використання кривих Безьє з B-Splines дозволяє досить точно представити будь-яку криву. Якщо вам потрібна точність, сплави кубічного відлюдника трохи точніші. Майте на увазі, іноді неточність забезпечує привітність органічності.
doppelgreener

+1 для кривих Безьє. Для описаного використання це, мабуть, найпростіший і найбільш керований.
ggambett

1

Ви можете подивитися на рульові поведінки, як їх визначив Крейг Рейнольдс: http://red3d.com/cwr/steer/

Це часто використовується в ШІ, щоб НПС рухалися до своєї мети.

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