Je suis tellement à court de maths que ça fait mal, mais pour certains d'entre vous, cela devrait être un morceau de gâteau. Je veux déplacer un objet autour d'un autre le long de son âge ou de sa circonférence sur une simple trajectoire circulaire. À l'heure actuelle, mon algorithme de jeu sait comment déplacer et positionner un sprite juste au bord d'un obstacle et maintenant il attend que le point suivant se déplace en fonction de diverses conditions.
Donc, le problème mathématique ici est de savoir comment obtenir les positions (aX, aY) et (bX, bY) , quand je connais le centre (cX, cY), la position de l'objet (oX, oY) et la distance requise pour se déplacer (d)
java
mathematics
Lumis
la source
la source
d
une distance linéaire ou est-ce un arc?Réponses:
( CAVEAT: j'utilise deux approximations ici: la première prend d comme longueur d'arc et la seconde prend comme longueur orthogonale. Ces deux approximations devraient être bonnes pour des valeurs relativement petites de d, mais elles ne remplissent pas la question précise telle que clarifiée dans les commentaires.)
Heureusement, les calculs à ce sujet sont relativement simples. Tout d'abord, nous pouvons trouver le vecteur relatif de notre position centrale à notre position actuelle:
Et une fois que nous avons ce vecteur relatif, nous pouvons alors connaître le rayon du cercle sur lequel nous travaillons en trouvant sa longueur:
De plus, à partir de notre vecteur relatif, nous pouvons trouver l'angle précis de la ligne de cX à oX:
Maintenant, les choses deviennent un peu plus compliquées. Tout d'abord, comprenez que la circonférence d'un cercle - c'est-à-dire la «longueur d'arc» d'un arc avec une mesure angulaire de 2π - est de 2πr. En général, la longueur d'arc d'un arc avec une mesure angulaire de θ le long d'un cercle de rayon r est juste θr. Si nous devions utiliser le d dans votre diagramme comme longueur d'arc, et puisque nous connaissons le rayon, nous pouvons trouver le changement de thêta pour nous amener à la nouvelle position en divisant simplement:
Dans le cas où d doit être une distance linéaire, les choses sont un peu plus compliquées, mais heureusement pas beaucoup. Là, d est un côté d'un triangle isocèle dont les deux autres côtés sont le rayon du cercle (de cX / cY à oX / oY et aX / aY respectivement), et la bissection de ce triangle isocèle nous donne deux triangles rectangles, dont chacun a d / 2 comme un côté et un rayon comme l'hypoténuse; cela signifie que le sinus de la moitié de notre angle est (d / 2) / rayon, et donc l'angle complet est juste le double de ceci:
Remarquez comment si vous retiriez l'asin de cette formule et annuliez les 2, ce serait la même chose que la dernière formule; cela revient à dire que sin (x) est approximativement x pour de petites valeurs de x, ce qui est une approximation utile à connaître.
Maintenant, nous pouvons trouver le nouvel angle en ajoutant ou en soustrayant simplement:
Une fois que nous avons le nouvel angle, nous pouvons utiliser un trig de base pour trouver notre vecteur relatif mis à jour:
et à partir de notre position centrale et de notre vecteur relatif, nous pouvons (enfin) trouver le point cible:
Maintenant, avec tout cela, il y a de grandes mises en garde à prendre en compte. D'une part, vous remarquerez que ce calcul est principalement à virgule flottante, et en fait il doit presque l'être; essayer d'utiliser cette méthode pour mettre à jour dans une boucle et arrondir à des valeurs entières à chaque étape peut faire tout, de faire que votre cercle ne se ferme pas (soit en spirale vers l'intérieur ou vers l'extérieur chaque fois que vous faites le tour de la boucle) jusqu'à ne pas le démarrer dans la première endroit! (Si votre d est trop petit, vous découvrirez peut-être que les versions arrondies de aX / aY ou bX / bY sont exactement là où se trouvait votre position de départ oX / oY.) Pour un autre, cela coûte très cher, surtout pour ce qu'il essaie de faire; en général, si vous savez que votre personnage va se déplacer dans un arc circulaire, vous devez planifier tout l'arc à l'avance et noncochez-le d'une image à l'autre comme ceci, car la plupart des calculs les plus coûteux peuvent être téléchargés en amont pour réduire les coûts. Un autre bon moyen de réduire les coûts, si vous voulez vraiment mettre à jour progressivement comme ceci, est de ne pas utiliser trig en premier lieu; si d est petit et que vous n'en avez pas besoin pour être exact mais juste très proche, alors vous pouvez faire une `` astuce '' en ajoutant un vecteur de longueur d à oX / oY, orthogonal au vecteur vers votre centre (notez qu'un le vecteur orthogonal à (dX, dY) est donné par (-dY, dX)), puis le réduire à la bonne longueur. Je ne vais pas expliquer ce code pas à pas, mais j'espère que cela aura du sens compte tenu de ce que vous avez vu jusqu'à présent. Notez que nous «rétrécissons» le nouveau vecteur delta implicitement à la dernière étape,
la source
Formez un triangle en utilisant les deux côtés que vous avez déjà (un côté est de «c» à «o», l'autre de «o» à «a»), et le troisième côté va de «a» à «c». Vous ne savez pas encore où est «a», imaginez simplement qu'il y a un point pour l'instant. Vous aurez besoin de trigonométrie pour calculer l'angle de l'angle opposé au côté «d». Vous avez la longueur des côtés c <-> o et c <-> a, car ils sont tous les deux le rayon du cercle.
Maintenant que vous avez la longueur des trois côtés de ce triangle que vous ne pouvez pas encore voir, vous pouvez déterminer l'angle opposé au côté «d» du triangle. Voici la formule SSS (side-side-side) si vous en avez besoin: http://www.teacherschoice.com.au/maths_library/trigonometry/solve_trig_sss.htm
En utilisant la formule SSS, vous avez l'angle (que nous appellerons «j») qui est opposé au côté «d». Donc, maintenant, nous pouvons calculer (aX, aY).
Assurez-vous que les angles que vous calculez sont toujours en radians.
Si vous devez calculer le rayon du cercle, vous pouvez utiliser la soustraction vectorielle, soustraire le point «c» du point «o», puis obtenir la longueur du vecteur résultant.
Quelque chose comme ça devrait faire, je crois. Je ne connais pas Java, j'ai donc deviné la syntaxe exacte.
Voici l'image donnée par l'utilisateur
Byte56
pour illustrer à quoi pourrait ressembler ce triangle:la source
Pour faire tourner obj2 autour de obj1, essayez peut-être:
la source