2

I'm having a little trouble calculating this angle and I'm hoping one of you geniuses can help me.

I have a game with a cannon that can be at any spot in the game world. Using OpenGL's matrix transformations, I want the cannon's texture to rotate to face in whatever direction the player puts his finger. To do this, I need to calculate an angle to send to the rotation matrix.

Currently I'm having a little trouble calculating the angle correctly.

See the figure:

enter image description here

Legend: A) A constant unit vector that always points toward the top of the screen. B) A point that is set based on where the user clicks the screen. theta) the angle I need to measure

As you can see, I'm using a constant unit vector that always points up as a baseline (A). What my algorithm needs to do is correctly measure the angle (theta) between A and B.

Here's the code that sets the target's position:

    public void setTarget(Vector2 targetPos) {

    //calculate target's position relative to cannon
    targetPos = sub(targetPos, this.position);

    //replace target
    this.target = targetPos;

    //calculate new angle
    //This is broken
    this.cannonAngle = findAngleBetweenTwoVectors(POINT_UP, target);

The "findAngleBetweenTwoVectors" method is what doesn't seem to be working. It's code is here:

 public static float findAngleBetweenTwoVectors(Vector2 baseVec, Vector2 newVec) {

    //first, make copies of the vectors
    Vector2 baseCopy = new Vector2(baseVec);
    Vector2 newCopy = new Vector2(newVec);

    //next, ensure they're normalized
    baseCopy.nor();
    newCopy.nor();

    //the arc-cosine is the angle between the two vectors
    //this is used as the "cannonAngle" value (does not work)

    return (float) Math.acos(newCopy.dot(baseCopy));
}

I know this is likely a vector math problem, I just can't seem to get the angle calculation right.

Thanks in advance for the help.

hhanesand
  • 990
  • 11
  • 28
RGrun
  • 350
  • 3
  • 16
  • 1
    Your vector math looks correct, but the `Math.acos` method returns values in radians. If this is what you want then I'm not sure what's wrong. – hhanesand Feb 18 '15 at 04:28
  • very similar question is here http://stackoverflow.com/a/28427322/2521214 – Spektre Feb 18 '15 at 08:07

1 Answers1

0

Get the coordinates of B and subtract the coordinates of the cannon from them, giving a vector pointing in the desired direction. The Java atan2 function can be used to get the angle of the vector in radians. To get the angle relative to the up vector, going clockwise, pass the arguments to atan2 in the order x,y rather than y,x (which gives a result going anticlockwise from a right-pointing vector).

So you need something like this:

double dx = b_x - cannon_x;
double dy = b_y - cannon_y;
double angle_in_degrees = Math.toDegrees(Math.atan2(dx,dy));

This answer assumes that the A vector points up, as you said, and is thus (0,1). If the A vector is arbitrary, then your original answer looks almost correct, but you need to convert to degrees as a commenter said, and possibly also check that your answer is clockwise or anticlockwise.

Graham Asher
  • 1,648
  • 1
  • 24
  • 34