Déterminer la position d'un objet le long d'une courbe dans le temps

8

J'ai des objets dans mon jeu qui sont "jetés". Pour l'instant, j'essaie de mettre en œuvre cela en faisant suivre à ces objets une courbe parabolique. Je connais le point de départ, le point final, le sommet et la vitesse de l'objet.

  1. Comment puis-je déterminer à un moment ou à un cadre donné quelles sont les coordonnées x & y?
  2. Une courbe parabolique est-elle même la bonne courbe à utiliser?
Ben Williams
la source
Vos commentaires sont ambigus. Je suppose que le sommet signifie la position de départ. Et le point final signifie la position finale. Que signifie la vitesse? Jusqu'où l'objet peut-il voyager en une seconde? Est-ce que la vitesse combien de temps l'objet devrait prendre pour aller du début à la fin?
deft_code
Toutes mes excuses pour le manque de clarté. Je vais essayer de faire simple - je voudrais faire bouger une balle d'un côté de l'écran (x = 0) à l'autre côté (x = 480), en commençant par y = 0 et en atteignant un maximum de y = 320 (à mi-chemin, x = 240). Je veux que cela se fasse en 2 secondes. À partir de ces informations, puis-je déterminer à partir d'une formule mes coordonnées x et y pour chaque image?
Ben Williams

Réponses:

4

Qu'est-ce que vous cherchez pour un tracé paramétrique de la fonction parabolique. Il est plus simple de faire en sorte que la fonction paramétrique utilise une plage de p ∈ [0,1].

La forme canonique d'une parabole paramétrique est

k: = une constante
f_x (p) = 2kp
f_y (p) = kp²

En utilisant cette formule et une algèbre de base pour le morphing de fonction et j'ai

p ∈ [0,1] → x, y ∈ [0,1]
ou en d'autres termes garder p entre 0 et 1 et x, y sera également entre 0 et 1.
x = p
y = 4p - 4p²

Donc, pour obtenir ces fonctions, vous obtiendrez les chiffres que vous recherchez.

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);
}
deft_code
la source
votre notation est un peu déroutante. votre accélération f_xutilise sa demi-vitesse? Vous devriez le faire etf_yax(t) = x0 + vx0*ty(t) = y0 + vy0*t + .5*ay*t*t
Tobias Kienzler
Je n'ai délibérément pas utilisé les formules euler motion. aet tn'étaient que des noms mal choisis. Vous devriez remarquer qu'il n'y a pas de composante de vitesse dans les formules. Le mouvement d'Euler et les paraboles paramétriques ne sont pas la même chose, mais ils sont très similaires car le vol balistique trace un chemin parabolique.
deft_code
4

Trouver l'équation d'une courbe selon laquelle vous voulez que votre objet se déplace est une façon d'accomplir ce que vous voulez, mais probablement pas la meilleure.

Au lieu de cela, on garde généralement une trace des propriétés locales d'un objet (vitesse, accélération) et utilise ensuite ces valeurs pour mettre à jour la position de l'objet à chaque image.

Puisque vous avez mentionné une parabole, je suppose que vous lancez une balle en 2D et que vous voulez qu'elle tombe le long de l'axe des y. Ainsi, votre objet a une accélération constante dans la direction y (appelons cela g) et aucune accélération dans la direction x. Lorsque l'objet est lancé, il reçoit une certaine vitesse, appelons cela vxet vy.

Ensuite, à chaque image de votre application, vous ajouteriez l'accélération de l'objet à sa vitesse, puis vous ajoutiez sa vitesse à sa position. Quelque chose comme:

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

Faites-le à chaque image et votre balle commencera à bouger. Il y a beaucoup plus à savoir à ce sujet, mais c'est un début.

Brandon Williams
la source
Je lance une balle en 2D, mais la balle a une accélération dans la direction x. Je veux qu'il soit jeté d'un côté à l'autre de l'écran (voir commentaire sur la question d'origine). Je comprends comment mettre à jour en fonction de vx et vy, mais je ne sais pas comment mettre à jour ces valeurs elles-mêmes.
Ben Williams
2
@Ben Williams Il vous suffit de définir le vx et le vy au début. Et ajoutez de la gravité à chaque image. Vous pouvez également avoir un frottement en multipliant à la fois le vx et le vy par un nombre inférieur à 1 (quelque chose comme .95 pourrait fonctionner en fonction de votre fréquence d'images). Recherchez sur google "bouncing ball YourProgrammingLanguageHere" et vous obtiendrez probablement des didacticiels basiques mais utiles.
AttackingHobo
3
En fait, si vous savez que votre objet suit une trajectoire parabolique, il est préférable de l'implémenter comme une fonction de courbe plutôt que comme des étapes physiques discrètes. Oui, il peut être «plus difficile» de coder au départ, mais le résultat est que le mouvement de votre objet se dissocie des problèmes de fréquence d'images.
Blair Holloway,
1
J'appuie @Blair, sauf si vous séparez le framerate physique du framerate vidéo, cela peut provoquer des effets horribles comme des erreurs d'écrêtage
Tobias Kienzler
0

Dans les jeux sur console, nous utilisons souvent l' interpolation bicubique pour résoudre ce problème. Tout d'abord, échantillonnez la position d'un objet à intervalles réguliers de temps t. Pour un projectile, ajoutez l'accélération gravitationnelle [0, dy / dt / dt] à sa vitesse [dx / dt, dy / dt] à chaque intervalle. Enregistrez toutes les coordonnées [x, y] ainsi générées dans un tableau.

Plus tard, pour reconstruire la position de l'objet [x, y] pour un t donné, lisez les quatre échantillons les plus proches de ce t dans le tampon que vous avez enregistré: [t-1, t, t + 1, t + 2]. Mélangez les quatre échantillons selon les coefficients de l'article wikipedia lié pour obtenir un mouvement fluide dans l'espace.

Ce n'est pas aussi précis physiquement que d'effectuer des calculs physiques à la volée, mais cela permet une licence artistique et une économie d'échelle pour aider votre simulation.

bmcnett
la source