( 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:
deltaX = oX-cX;
deltaY = oY-cY;
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:
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
De plus, à partir de notre vecteur relatif, nous pouvons trouver l'angle précis de la ligne de cX à oX:
curTheta = atan2(deltaX, deltaY);
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:
deltaTheta = d/radius; // treats d as a distance along the arc
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:
deltaTheta = 2*asin(d/(2*radius)); // treats d as a linear distance
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:
newTheta = curTheta+deltaTheta; // This will take you to aX, aY. For bX/bY, use curTheta-deltaTheta
Une fois que nous avons le nouvel angle, nous pouvons utiliser un trig de base pour trouver notre vecteur relatif mis à jour:
newDeltaX = radius*cos(newTheta);
newDeltaY = radius*sin(newTheta);
et à partir de notre position centrale et de notre vecteur relatif, nous pouvons (enfin) trouver le point cible:
aX = cX+newDeltaX;
aY = cY+newDeltaY;
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,
deltaX = oX-cX; deltaY = oY-cY;
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
orthoX = -deltaY*d/radius;
orthoY = deltaX*d/radius;
newDeltaX = deltaX+orthoX; newDeltaY = deltaY+orthoY;
newLength = sqrt(newDeltaX*newDeltaX+newDeltaY*newDeltaY);
aX = cX+newDeltaX*radius/newLength; aY = cY+newDeltaY*radius/newLength;
d
une distance linéaire ou est-ce un arc?