Reputation: 1564
Let's say I have a circle with a line sticking out of it.
I want that line to point at the center of the window, no matter where the circle moves to.
But, I want that line to slowly move to that angle. I don't want the rotation to be calculated and set every single frame, but rather calculated and tweened to that direction.
The issue I'm having with this is that if you move to make the line rotate around where the radians meet 0, it will do a full 360 (or 3.14 in rads ;) to get to that point.
I have spent a while trying to think of how to explain this best, here is a codepen that can hopefully help clarify what I'm asking
// CenterX/Y is the center of the screen.
// dotX/Y is the center of the circle.
var angleToCenter=Math.atan2(centerY-dotY,centerX-dotX);
if (angleToCenter<currentAngle) {
currentAngle-=0.05;
} else {
currentAngle+=0.05;
}
if you move to the right of the screen, then go above or below the center, you will see the line move in a full circle to try to get to the calculated direction. How do I avoid this? I want the line to seamlessly rotate to point at the center, via the shortest possible way, not by doing a full circle.
Upvotes: 2
Views: 515
Reputation: 5138
The problem lies in the point where angleToCenter
switches from Math.PI
to -Math.PI
(and vice versa).
Therefore I'd suggest you create an "epsilon angle distance", in which the angles will be hard-coded:
var angleToCenter = Math.atan2(centerY - dotY, centerX - dotX);
var epsilon = 0.05;
if (Math.abs(angleToCenter - Math.PI) <= epsilon / 2 || Math.abs(angleToCenter + Math.PI) <= epsilon / 2) {
if (dotY > centerY) {
currentAngle = -Math.PI;
} else if (dotY < centerY) {
currentAngle = Math.PI;
}
} else if (angleToCenter < currentAngle - epsilon) {
currentAngle -= epsilon;
} else {
currentAngle += epsilon;
}
For the full edit, you can check my fork to your CodePan
Upvotes: 0
Reputation: 2357
Great question. Very different.
I would have an inverse (-1) relationship defined for any location below the black circle. Such that, if the red circle crosses a horizontal axis - whose boundry is defined by the black circle - the mathematical result to your equation is inversed.
This would make 0 degrees as we typically think of it, now positioned at 180 degrees.
Reasoning: Looking at your CodePen it's obvious that the stem is going "the long way around", but you want it to go the "short way around". The most intuitive way to make that happen would seem to be to inverse the red-circles calculated rotation. The simplest method I can think of would be to inverse the polarity of the circle.
Upvotes: 1