Ease rotation towards the mouse

2.1k Views Asked by At

The following code rotates the line towards the mouse position using a simple ease function, but the problem is that the atan2() methods works form -PI to PI, making the line to rotate backwards when the angle reach either of the limits, I can make it to rotate from 0 to TWO_PI but there is no different as the line will rotate backwards until it reach the targetAngle, if I dont use the easing calculation works fine because there jump from -PI to PI is unnoticeable, so how can I ease my rotation and avoid this problem?

float angle = 0;
float targetAngle = 0;
float easing = 0.1;

void setup() {
  size(320, 240);
}

void draw() {
  background(200);
  noFill();
  stroke( 0 );

  // get the angle from the center to the mouse position
  angle = atan2( mouseY - height/2, mouseX - width/2 );
  // check and adjust angle to go from 0 to TWO_PI
  if ( angle < 0 ) angle = TWO_PI + angle;

  // ease rotation
  targetAngle += (angle - targetAngle) * easing;

  pushMatrix();
  translate( width/2, height/2 );
  rotate( targetAngle );
  line( 0, 0, 60, 0 );
  popMatrix();
}

Thanks

1

There are 1 best solutions below

0
On BEST ANSWER

Not sure if I understood the problem correctly... Do you mean that if the mouse position is slightly less than +PI, and targetAngle is slightly greater than -PI, then the line rotates away from the mouse? The thing is that even if both values are in the same range (-PI, PI), they still can be quite far away from each other. You must adjust angle to fit the PI-neighbourhood of the current targetAngle value.

// get the angle from the center to the mouse position
angle = atan2( mouseY - height/2, mouseX - width/2 );
// check and adjust angle to be closer to targetAngle
if ( angle < targetAngle - PI ) angle = angle + TWO_PI;
if ( angle > targetAngle + PI ) angle = angle - TWO_PI;

This will work if targetAngle is in the range (-TWO_PI, TWO_PI). It seems that it will work for you. If targetAngle can have any value very far away from the working range, then you can use something like this:

// get the angle from the center to the mouse position
angle = atan2( mouseY - height/2, mouseX - width/2 );
// calculate the shortest rotation direction
float dir = (angle - targetAngle) / TWO_PI;
dir = dir - Math.round(dir);
dir = dir * TWO_PI;

// ease rotation
targetAngle += dir * easing;