• 14
• 12
• 9
• 10
• 13

# Translating coordinates from absolute to relative question

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

## 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 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-------oF = frontB = backL = leftR = 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.xy = prey.y - hunter.yangle = 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 radiansif(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 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.xy = prey.y - hunter.yangle = 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 guessingrelativePreyY = ??; //needs relativePredY I'm guessingif(relativePreyX > 0)     hunter.direction--;if(relativePreyX < 0)     hunter.direction++;if(relativePreyX == 0 && relativePreyY < 0)     hunter.direction += rand()%3 -1;

##### 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 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 on other sites
The information in this recent thread on the AI board might be helpful.

##### 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 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.