Kyle Fahringer
Kyle Fahringer

Reputation: 23

Finding angle using three points

I want a square (represented by head) to always face toward the mouse (represented by Mouse - yeah, it's LWJGL). I'm having a bit of trouble actually getting it to face torward the mouse because i'm using glRotatef(angle), which

  1. Requires degrees, while most java Math functions involve radians
  2. Is difficult to do since I have no way of knowing how far i have to rotate in order to point toward the mouse

I whipped up the following java code, which assumes that 0 degrees is straight up:

double mx = Mouse.getX();
double my = Mouse.getY();
double rx = head.x;
double ry = head.y + 1;
double vx = head.x;
double vy = head.y;
double mtor = Math.sqrt(Math.pow(mx + rx, 2) + Math.pow(my + ry, 2));
double mtov = Math.sqrt(Math.pow(mx + vx, 2) + Math.pow(my + vy, 2));
double rtov = Math.sqrt(Math.pow(rx + vx, 2) + Math.pow(ry + vy, 2));
double rotate = Math.toDegrees(Math.acos((Math.pow(mtov, 2) + Math.pow(rtov, 2) - Math.pow(mtor, 2))/(2*mtov*rtov))));

However, this creates some strange results:

What

(The side with the white squares is the front. For a full album go to https://i.sstatic.net/uT0Rq.jpg)

Here's some console output:

Mouse X: 555.0
Mouse Y: 439.0
Reference X: 400.0
Reference Y: 301.0
Vertex X: 400.0
Vertex Y: 300.0
Rotation: 65.56236879269605

Mouse X: 552.0
Mouse Y: 440.0
Reference X: 400.0
Reference Y: 301.0
Vertex X: 400.0
Vertex Y: 300.0
Rotation: 65.5244609346555

So, what am I doing wrong? (Extra Credit: is there some better way to do this in openGL?)

Upvotes: 0

Views: 165

Answers (1)

maybeWeCouldStealAVan
maybeWeCouldStealAVan

Reputation: 15610

This assumes that 0 degrees is straight up, counterclockwise is positive, that x increases to the right, and that y increases upward. (I don't know if that's true for LWJGL.) I'm using a range of -180 to 180, rather than 0 to 360, since that seems more natural (eg, if the head were to slowly rotate)

double dx = (mx-vx); // change in x from head to mouse
double dy = (my-vy); // change in y from head to mouse
double dist = Math.sqrt(dx*dx + dy*dy); // distance, pythagorean theorem
double degrees = Math.toDegrees((Math.acos(dy/dist)) * -Math.signum(dx));
        // dy/dist is the cosine
        // the sign of dx determines positive (CCW) or negative (CW) angle

If you're worried about performance, you could avoid a sqrt operation by using atan, but you'd need to do extra tests to determine the quadrant and to avoid dividing by zero. It'd still probably be a hair faster, but might not be worthwhile.

Upvotes: 1

Related Questions