Bestimmen der Position eines Objekts entlang einer Kurve über die Zeit


8

Ich habe einige Objekte in meinem Spiel, die "geworfen" werden. Im Moment versuche ich dies zu implementieren, indem diese Objekte einer parabolischen Kurve folgen. Ich kenne den Startpunkt, den Endpunkt, den Scheitelpunkt und die Geschwindigkeit des Objekts.

  1. Wie kann ich zu einem bestimmten Zeitpunkt oder Rahmen die x & y-Koordinaten bestimmen?
  2. Ist eine Parabelkurve überhaupt die richtige Kurve?

Ihre Eingaben sind nicht eindeutig. Ich nehme an, Scheitelpunkt bedeutet die Starposition. Und Endpunkt bedeutet die Endposition. Was bedeutet Geschwindigkeit? Wie weit kann sich das Objekt in einer Sekunde bewegen? Wie schnell sollte das Objekt von Anfang bis Ende sein?
Deft_code

Entschuldigung für die Unklarheit. Ich werde versuchen, es einfach zu machen - ich möchte einen Ball von einer Seite des Bildschirms (x = 0) zur anderen Seite (x = 480) bewegen, beginnend mit y = 0 und bis zu einem Maximum von y = 320 (auf halber Strecke x = 240). Ich möchte, dass es dies über 2 Sekunden tut. Kann ich anhand dieser Informationen aus einer Formel meine x- und y-Koordinaten für jeden Frame ermitteln?
Ben Williams

Antworten:


4

Was suchen Sie nach einer parametrischen Darstellung der Parabelfunktion? Es ist am einfachsten, die parametrische Funktion in einem Bereich von p ∈ [0,1] zu verwenden.

Die kanonische Form für eine parametrische Parabel ist

k: = eine Konstante
f_x (p) = 2 kp f_y
(p) = kp²

Mit dieser Formel und einigen grundlegenden Algebra für Funktionsmorphing und ich bekam

p ∈ [0,1] → x, y ∈ [0,1]
oder mit anderen Worten, halte p zwischen 0 und 1 und x, y liegt ebenfalls zwischen 0 und 1.
x = p
y = 4p - 4p²

Um diese Funktionen zu erhalten, werden die gesuchten Zahlen erzeugt.

float total_time = 2;
float x_min = 0;
float x_max = 480;
float y_min = 0;
float y_max = 320;

float f_x( float time )
{
   float p = time/total_time;
   return x_min + (x_max-x_min)*p;
}

float f_y( float time )
{
   float p = time/total_time;
   return y_min + (y_max-y_min)*(4*p-4*p*p);
}

Ihre Notation ist etwas verwirrend. Sie f_xverwenden die f_yBeschleunigung aals halbe Geschwindigkeit? Sie sollten das machen x(t) = x0 + vx0*tundy(t) = y0 + vy0*t + .5*ay*t*t
Tobias Kienzler

Ich habe die Euler-Bewegungsformeln absichtlich nicht verwendet. aund twaren nur schlecht gewählte Namen. Sie sollten beachten, dass die Formeln keine Geschwindigkeitskomponente enthalten. Euler-Bewegung und parametrische Parabeln sind nicht dasselbe, aber sie sind sehr ähnlich, da der ballistische Flug einen parabolischen Pfad verfolgt.
Deft_code

4

Das Finden der Gleichung einer Kurve, entlang der sich Ihr Objekt bewegen soll, ist eine Möglichkeit, das zu erreichen, was Sie wollen, aber wahrscheinlich nicht die beste.

Stattdessen verfolgt man normalerweise die lokalen Eigenschaften eines Objekts (Geschwindigkeit, Beschleunigung) und verwendet diese Werte dann, um die Position des Objekts in jedem Frame zu aktualisieren.

Da Sie eine Parabel erwähnt haben, gehe ich davon aus, dass Sie einen Ball in 2D werfen und möchten, dass er entlang der y-Achse herunterfällt. Ihr Objekt hat also eine konstante Beschleunigung in y-Richtung (nennen wir das g) und keine Beschleunigung in x-Richtung. Wenn das Objekt geworfen wird, erhält es eine gewisse Geschwindigkeit. Nennen wir das vxund vy.

Dann würden Sie in jedem Frame Ihrer Anwendung die Beschleunigung des Objekts zu seiner Geschwindigkeit hinzufügen und dann seine Geschwindigkeit zu seiner Position hinzufügen. Etwas wie:

vy += g;
x += vx;
y += vy;

Tun Sie dies bei jedem Frame und Ihr Ball beginnt sich zu bewegen. Es gibt noch viel mehr zu wissen, aber es ist ein Anfang.


Ich werfe einen Ball in 2D, aber der Ball hat eine Beschleunigung in x-Richtung. Ich möchte, dass es von einer Seite des Bildschirms zur anderen geworfen wird (siehe Kommentar zur ursprünglichen Frage). Ich verstehe, wie man basierend auf vx und vy aktualisiert, bin mir aber nicht sicher, wie man diese Werte selbst aktualisiert.
Ben Williams

2
@ Ben Williams Sie müssen nur die vx und die vy am Start einstellen. Und fügen Sie jedem Rahmen Schwerkraft hinzu. Sie könnten auch eine Reibung haben, indem Sie sowohl vx als auch vy mit einer Zahl unter 1 multiplizieren (etwas wie 0,95 könnte abhängig von Ihrer Bildrate funktionieren). Suchen Sie auf Google "Bouncing Ball YourProgrammingLanguageHere" und Sie werden wahrscheinlich einige grundlegende, aber hilfreiche Tutorials erhalten.
AttackingHobo

3
Wenn Sie wissen, dass Ihr Objekt einer parabolischen Flugbahn folgt, ist es viel, viel besser, es als Kurvenfunktion zu implementieren, als diskrete physikalische Schritte. Ja, es kann anfangs "schwieriger" sein, zu codieren, aber die Auszahlung besteht darin, dass die Bewegung Ihres Objekts von Bedenken hinsichtlich der Bildrate entkoppelt wird.
Blair Holloway

1
Ich zweite @Blair, wenn Sie nicht die Physik-Framerate von der Video-Framerate trennen, kann dies schreckliche Effekte wie Clipping-Fehler verursachen
Tobias Kienzler


0

In Konsolenspielen verwenden wir häufig die bikubische Interpolation , um dieses Problem zu lösen. Probieren Sie zunächst die Position eines Objekts in regelmäßigen Zeitabständen t aus. Addieren Sie für ein Projektil in jedem Intervall die Gravitationsbeschleunigung [0, dy / dt / dt] zu seiner Geschwindigkeit [dx / dt, dy / dt]. Zeichnen Sie alle so erzeugten [x, y] -Koordinaten in einem Array auf.

Um später die Position des Objekts [x, y] für ein gegebenes t zu rekonstruieren, lesen Sie die vier Abtastwerte, die diesem t am nächsten liegen, aus dem von Ihnen aufgezeichneten Puffer: [t-1, t, t + 1, t + 2]. Mischen Sie die vier Proben gemäß den Koeffizienten im verknüpften Wikipedia-Artikel, um eine gleichmäßige Bewegung im Raum zu erzielen.

Dies ist physikalisch nicht so genau wie das direkte Ausführen von Physikberechnungen, ermöglicht jedoch eine künstlerische Lizenz und Skaleneffekte, um Ihre Simulation zu unterstützen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.