Sign in to follow this  
KnTenshi

Translating coordinates from absolute to relative question

Recommended Posts

I am try to program a little Hunter program in C++ in a continuous environment (i.e. things have a speed and direction and can't turn on a dime). I understand that I need to translate the hunter's coordinates to a relative one so I can easily check if the prey is to the left, right, in front, or behind. I know that to make these relative coordinates is this: relativeX = (hunter.x * cos(hunter.direction)) + (hunter.y * sin(hunter.direction)); relativeY = -1 * (hunter.x * sin(hunter.direction)) + (hunter.y * cos(hunter.direction)); But how do I convert the prey's x and y to these relative coordinates?

Share this post


Link to post
Share on other sites
If you want to find out whether or not something is "left", "right", "in front", or "behind", you need to mathematically define it. These terms are ambiguous right now. I also do not really understand your formulae for relativeX relativeY.
It would not be sufficient to simply define "in front" as "is further ahead in the direction the hunter is facing." That defines 1/2 of the screen as in front, and 1/2 the screen behind. Similar arguments for definition of left/right. It seems you want to find whether or not it is within a certain swept range (imagine a windshield wiper mounted at the hunter's position sweeping an area and declaring that the front. What you set the windshield wiper's maximum angle to increases or decreases the area).

Here is what I think of:

o-------o
| \ F / |
|L X R|
| / B \ |
o-------o
F = front
B = back
L = left
R = right

In this diagram, anything +/- 45 degrees of the way the hunter is facing is considered "in front". Anything -45 to -135 is considered right, anything +45 to +135 is considered left, and finally, anything from +135 to -135 is considered back.

If this is the case you are envisioning, you need find the angle between the hunter and the prey. This can be done by:

x = prey.x - hunter.x
y = prey.y - hunter.y
angle = atan2(y, x);

This will give you the angle between the hunter and the prey in the range of [-PI,PI]. From there, you determine which of the four groups fits the angle.
For example, to determine if it is "in front" of the hunter, you might use:

t = angle * 180.0 / PI; //Convert angle from degrees to radians

if(t <= 45.0 && t >= -45.0)
side = FRONT;



If you are doing graphics, it really helps to draw a line in that direction too to help debug visually the angles.

Share this post


Link to post
Share on other sites
Thanks for the input Figgles, but I'm trying to not use atan2, unless there is a simple way to make the angle relative to my hunter's direction. The best way I can think of for that is like this.


x = prey.x - hunter.x
y = prey.y - hunter.y
angle = atan2(y, x);
rads = fromDegreesToRadians(hunter.direction);
dif = angle - rads;
if(dif > PI)
{
if(angle > rads)
hunter.direction--;
if(angle < rads)
hunter.direction++
}
else
{
if(angle > rads)
hunter.direction++;
if(angle < rads)
hunter.direction--;
}


The way I'd like to do it is:


relativePredX = (hunter.x * cos(hunter.direction)) + (hunter.y * sin(hunter.direction));
relativePredY = -1 * (hunter.x * sin(hunter.direction)) + (hunter.y * cos(hunter.direction));

relativePreyX = ??; //needs relativePredX I'm guessing
relativePreyY = ??; //needs relativePredY I'm guessing

if(relativePreyX > 0)
hunter.direction--;
if(relativePreyX < 0)
hunter.direction++;

if(relativePreyX == 0 && relativePreyY < 0)
hunter.direction += rand()%3 -1;

Share this post


Link to post
Share on other sites
w.r.t. hunter/prey I think what you're after is called "steering" behaviour, seek/flee.

To figure out where the prey is, relative to the hunter's orientation, you would build a matrix for the hunter, and then use it's inverse to transform the prey's position (into "local space").

For steering purposes, usually you would just dot-product the right vector of the hunter, with the direction to the prey, and use the result as an adjustment to your delta angle. A dot product of 0 would mean the hunter is facing the prey.

Share this post


Link to post
Share on other sites
Is this a particular reason that atan2() is off-limits but using sin()/cos() isn't? It wouldn't be for performance reasons because you do a total of 2 pairs of sin()/cos(). On x86 hardware, FPATAN is a single instruction that is particularly fast at computing arctangents.

The only caveat of the dot product is that it can't tell you which direction to turn, only how much.



C A B
\ | /
\|/

A = <0.0f, 1.0f>
B = <.5f, 0.5f>
C = <-.5f, 0.5f>

dot(A,B) = 0.0f*0.5f + 1.0f*0.5f = 0.5f;
dot(A,C) = 0.0f*-0.5f + 1.0f*0.5f = 0.5f;

Flip the direction of vector A and you'll find you still can't tell the direction. I honestly think that atan2() is the easiest solution. I'm sure you've got other parts of the program to work on other than that.

Share this post


Link to post
Share on other sites
Ok, I've tried it with atan2() in the way I posted in my last post. Problem is, my hunter will randomly circle some point for eternity (the prey will come at from any direction, but nothing changes).

This is why I didn't want to use atan2(), since I had tried it in an earlier project in Flash and had similar results. How do I fix this?

And I tried to understand the other thread, but got heavily lost on it. I knew I should have sat closer to the teacher in the Vector/matrix math class.

Share this post


Link to post
Share on other sites
atan2() produces values in the range of [-PI, PI]. It looks like your code assumes it is in the range of [0, 2*PI]. Basically, you want to map -'K' to (2*PI - K). To verify that these results are correct:


-90 degrees = 360 - 90 = 270
-PI/2 = 2PI - PI/2 = 3PI/2


So you just need to add:

if(angle < 0.0f)
angle += 2*PI;


Now you can directly compare the two and should be able to turn correctly.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this