Jump to content
  • Advertisement
Sign in to follow this  
pdub

2D Rotation - Face point A towards point B

This topic is 3172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Needless to say, it's been a while since I've done any math and I could really use some help with this. I have googled around but I haven't had much luck, as I'm not entirely sure which realm of math would be used to solve my problem. I am trying to write a function that determines the amount of rotation required to make a Ship face a specified target. I need to determine both 1)The correct direction to turn, and 2)The amount of degrees necessary to face the point. In other words, from my Ship.FacingDirection, Ship.Position, and Target.Position, I need to determine what direction my ship should turn, and how much of a turn it should make. Heres an example picture: Free Image Hosting at www.ImageShack.us Given both the Position and Facing direction of point A, how would I determine that I should turn (clockwise) to the Right, and the amount of degrees to turn that direction? Any tips or pointers in the right direction would be greatly appreciated. Thank you very much.

Share this post


Link to post
Share on other sites
Advertisement
Clicky

EDIT: If that's not an option,

gradient = m = (y2 - y1)/(x2 - x1)

angle = θ = atan(m)

Then determine the quadrant the target is in to decide whether or not to add pi radians (or 180 degrees - math functions like atan() will spit out radians, though) to the resultant angle.

In either instance, you can get your number by subtracting θ from current angle, or something.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fenrisulvur
Clicky

EDIT: If that's not an option,

gradient = m = (y2 - y1)/(x2 - x1)

angle = θ = atan(m)

Then determine the quadrant the target is in to decide whether or not to add pi radians (or 180 degrees - math functions like atan() will spit out radians, though) to the resultant angle.

In either instance, you can get your number by subtracting θ from current angle, or something.


Thank you for the quick reply. I am coding in C# so I have access to Atan2, but I still have no idea what I'm doing with it. I got through geometry and failed trig twice in high school, so...

Anyone mind elaborating on how I would use either of these methods to solve this?

edit: btw as shown in the diagram I linked above, both my x and y values are always positive, if that makes this any easier?

[Edited by - pdub on October 10, 2009 11:12:15 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by pdub
I got through geometry and failed trig twice in high school

This doesn't bode well for your prospects as a game programmer.

Quote:
Original post by pdub
Anyone mind elaborating on how I would use Atan2 to solve this?

Sure. First question is, where are you measuring angles from? Counter-clockwise from the X axis? Clockwise from the Y axis? Other?

atan2() accepts two arguments, an X value and a Y value - for your case, that'll be the displacement along the X axis of the target relative to the ship, and the displacement along the Y axis of the target relative to the ship. The output, normally measured in radians, is the angle counter-clockwise from the positive X axis of the direction of the target from the ship's perspective. We'll call that angle θ (theta).

That is, this:



Now, your ship will already be facing some direction relative to the X axis, call it ς (sigma). Since θ is in radians, we also need ς to be in radians - if you're currently measuring ς in degrees, either multiply ς by pi/180 (to convert to radians), or multiply θ by 180/pi (to convert to degrees).

You want to know the difference between these two angles, which we'll call ω (omega). ω is given by the formula:



If the target is counterclockwise from the direction the ship is facing, then ω will be positive; if not, ω will be negative. Either way, adding ω to ς should point your ship in the direction of the target.

Any questions?

EDIT: slight error, corrected:
Quote:
adding ω to ς should point your ship in the direction of the target.

Share this post


Link to post
Share on other sites
Thank you for the very helpful reply! I am calculating the rotation counter clockwise from the X axis. It may take me a minute to get this all sunk into my head.

My first question is this, the function Atan2 is defined as Atan2(y, x). Shall I pass the values in that order? ie,:

Atan2( yTarget - yShip, xTarget - xShip )


Is there a reason you swapped them around, or doesn't it matter? I realize most of the time the x axis is horizontal, and y axis is vertical, however I'm working with them like this:

0 YYYY
X
X
X

I'm sure i will have more questions as soon as I give this a whirl. THanks again for the very helpful reply!

Share this post


Link to post
Share on other sites
Quote:
Original post by pdub
My first question is this, the function Atan2 is defined as Atan2(y, x). Shall I pass the values in that order? ie,:

Atan2( yTarget - yShip, xTarget - xShip )


Is there a reason you swapped them around, or doesn't it matter?

Oh, yes, you are correct. I don't make regular use of atan2() at all, so that tidbit slipped my mind.



And the order definitely matters - the function doesn't know where the numbers came from.

Quote:
Original post by pdub
I realize most of the time the x axis is horizontal, and y axis is vertical, however I'm working with them like this:

0 YYYY
X
X
X

It should be equivalent, since you claimed you're measuring angles counter-clockwise from the X axis.

Share this post


Link to post
Share on other sites
so far, I haven't had much luck ;P

My axis look like this:

(0,0) -- positive Y -->
x
x
x
(positive X down)

All my x and y coordinates are positive. I've implemented the code as you suggested (with the exception of the finding the quadrant part), and it's definitely not working properly. My guess is that I still need to determine what quadrant the target is in? Any chance you could explain how I might go about doing that please :) ?

Sorry to be such a bother ~

[Edited by - pdub on October 11, 2009 3:57:21 AM]

Share this post


Link to post
Share on other sites
There should be no need to determine quadrants with atan2(). Since I can't really hope to debug an implementation that I can't see, your best bet is probably to post the relevant code.

Share this post


Link to post
Share on other sites
Here's what I came up with from what I understand of your explanation:
http://pastebin.com/m8010d1a


public static Rotation Rotation(Position Target)
{
// our Rotation struct
Rotation r = new Rotation();

// player Position
Position Player = GameData.Player.Position;

// get the angle counter-clockwise from positive x axis of the direction
// of the target from the players perspective
double radians = Math.Atan2((Target.y - Player.y), (Target.x - Player.x));
double degrees = radians * (180/Math.PI);

// current rotation 0 - 360
float currentFacing = GameData.Player.Rotation;

// the difference of the two angles
double diff = currentFacing - degrees;

// if difference is positive the target is CCW
if (diff > 0)
r.Direction = Direction.Left;
else
r.Direction = Direction.Right;

// get amount of degrees in the direction we need to turn
r.Degrees = Convert.ToSingle(diff);

// get the direction we want to face
r.DesiredFacing = Convert.ToSingle(degrees + currentFacing);

return r;
}


I can't really make out what is going wrong... Here is some example output data, where I am facing directly at my target, from the following coordinates:

player position x:1517.675, y:1797.688
target position x:1517.428, y:1768.279

my Rotation return structure is output as follows:
Direction: Left
Degrees: 91.06335
atan2 radians: -1.57919314254992
currentFacing: 0.5822506 (degrees - facing almost directly west, a tad south)

I believe it's off (by 90 deg?) because of how I've defined my angles, this is how I have been working with them:

0 degrees west
90 degrees south
180 degrees east
270 degrees north

How might I correct the calculation in order to generate correct values using my 0 degrees @ west angle representation?

Or maybe it has nothing to do with that, in which case ... can you see anything else I'm doing wrong?

Share this post


Link to post
Share on other sites
I only skimmed the code, but I can tell you that working with absolute angles in this way can be problematic due to periodicity.

What I would recommend instead is to compute the relative angle between the object's forward direction vector and the vector to the target. Pseudocode:
vector2 diff = target.position - object.position;
float relative_angle = atan2(perp_dot(object.forward, diff), dot(object.forward, diff));
The relative angle will then tell you both how far the object has to turn, and in which direction.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!