Jump to content
  • Advertisement
Sign in to follow this  
SelethD

determine angle from point a to b

This topic is 4570 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

Im trying to make a 2d iso type game, sort of Diablo-ish in character movement. So if my character is in the center of screen always, and i want him to walk towards the mouse, which can be anywhere, I need to have the character face the mouse position. So how do I get some sort of 'angle' from the center of screen, point A, to my mouse point B, so i know which sprite to use, so the character can face the mouse? Thanks

Share this post


Link to post
Share on other sites
Advertisement
A standard 2D 'absolute angle to target' formula is:
float angle = atan2(b.y-a.y, b.x-a.x);
The isometric aspect may complicate this a little. I don't have any experience with isometric so I can't tell you for sure how it should be done, but my guess is that you would want to somehow raytrace the 'ground plane' using the mouse position, and then use the above equation to find the appropriate angle for the character in world space.

Share this post


Link to post
Share on other sites
Hi SelethD.

I'm not sure what co-ordinate system you're using, but if you're using sprites, then lets assume standard screen co-ordinates, in which your problem could be illustrated as follows:

Image Hosted by ImageShack.us

Granted this is non-isometric (i.e. it's a 'flat' 2D system), but hopefully you could adapt upon it.

Assuming the above flat-model then, the following code hack would provide a measure of the bearing angle between point A (centre of screen) to point B (mouse pointer):


#include <math.h>

#define DEGREE(x) static_cast<int> (180.0 * (x) / PI) // Crude macro used to convert radians into degrees.

const double PI = 3.141593; // pi to 6 decimal places
const double TWO_PI = 2 * PI;

double AngleBearingRadian (const POINT &A, const POINT &B)
{
double xDelta = B.x - A.x; // signed difference between points A and B in x-direction
double yDelta = B.y - A.y; // signed difference between points A and B in y-direction

if ((xDelta > 0.0) && (yDelta >= 0.0)) return PI - atan2 (xDelta, yDelta);
if ((xDelta <= 0.0) && (yDelta > 0.0)) return PI + atan2 (-xDelta, yDelta);
if ((xDelta < 0.0) && (yDelta <= 0.0)) return TWO_PI - atan2 (-xDelta, -yDelta);
return atan2 (xDelta, -yDelta);
}



I've checked the code (which is pretty crude!), by changing point B while keeping point A fixed, to make sure the 'AngleBearingRadian' function returns the correct bearing of point B from point A. However, it could use some more optimization, since your compiler would probably call internal routines (e.g. _ftol which turns floats into integers), which may slow things down in the main render loop.

Anyway, I'm not sure you even wanted a bearing system like this for your game, but at least using a range (like 0 to 2 * pi radians, or 0 - 360 degrees) would allow you to code sprite changes for an entire rotation.

Hope this helps.

Share this post


Link to post
Share on other sites
That's a nice graphic, Terrorflop :-) But given that atan2() already returns the complete range of angles, what's the purpose of all those special cases? (I'm too lazy to try and figure it out myself at the moment.) If it's simply a matter of redefining the default orientation or direction of rotation, it seems you could simply do a single mapping from the range returned by atan2() to the desired range. Anyway, it seems like your solution is unnecessarily complicated (unless I'm missing its purpose).

Share this post


Link to post
Share on other sites
Well I did do some checking beforehand with the atan2 function.

It seems to use the standard Cartesian co-ord system:

Image Hosted by ImageShack.us

And not the usual bearing system:

Image Hosted by ImageShack.us

I'm sure there is an easier way of solving the problem SelethD has (or had) and I did say it was a bit of a hack (I did not address the iso-metric issue). But I thought maybe using a brute force bearing method was one possible way to go.

Nevertheless, I think things would get complicated (slightly) when mapping Cartesian to Screen co-ords, which is the issue I addressed here. (Remember the messy GDI nonsense with logical and physical co-ordinates?)

Share this post


Link to post
Share on other sites
I see. Well, I'm pretty sure you can map the atan2() range to whatever range you want with a single equation, rather than multiple conditionals; it's the same idea, just a bit simpler than your example.

Share this post


Link to post
Share on other sites
Quote:
Original post by TerrorFLOP
Well I did do some checking beforehand with the atan2 function.

It seems to use the standard Cartesian co-ord system...And not the usual bearing system

Subtract the angle from 90 degrees and modulo 360 degrees.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!