Using two given points in 2D space to determine one of the following directions: north, south, east, or west

Started by
6 comments, last by Paradigm Shifter 10 years, 6 months ago

I have a hard time trying to calculate a value to determine what direction an entity is moving towards at.

Currently, I have 2 points known at any point in time, the starting point and the ending point. The unit moves at a constant speed in a linear interpolating fashion. I'm trying to find what direction the entity is moving from the starting point to the ending point, not the other way around.

Example: If the starting point is at the point of origin in the Cartesian plane, and the ending point is at (10.1235, 0.81235), the direction the entity is moving towards at is east, since the angle is less than 45 degrees of northeast direction. In this case, after calculating the value (that I have a hard time trying), using conditional ifs, we can conclude that the direction east is determined.

Any tips I can use? I'm looking at Math.atan2(dy,dx), but maybe I may have been looking at it incorrectly. Thanks in advance.

Advertisement

dist = target - start;

if(abs(dist.x) > abs(dist.y)) // the axis with the most movement determines the direction
{
    if(dist.x > 0)
        return EAST;
    else
        return WEST;
}
else
{
    if(dist.y > 0)
        return SOUTH;
    else
        return NORTH;
}

It shouldn't be more complicated than this. Depending on your direction layout, you can even "optimize" the nested if-statements away:


moveX = dist.x > 0; // true = east, false = west

And, if you want to determine the "real" direction (North-West, South-East etc...) you can easily adapt it too.

What Juliean said, but I have to object to the variable name `dist'. A distance is a number, not a vector. `direction' would have been a much better name.

Alternatively, you could accomplish this using atan2, as you started:


static int const direction_table[5] = {WEST, SOUTH, EAST, NORTH, WEST};
static double const Tau = std::atan(1.0)*8.0; // a.k.a. `2*Pi'
 
Vector2D direction = target - start;
double angle = std::atan2(direction.y, direction.x);
int rounded_angle = static_cast<int>(std::floor(0.5 + angle * 4.0 / Tau)) + 2;
 
return direction_table[rounded_angle];

The latter solution is easier to generalize to using 8 or 16 directions.

EDIT: Sorry the code is in C++, since I don't know Java. It should be easy to understand anyway.


What Juliean said, but I have to object to the variable name `dist'. A distance is a number, not a vector. `direction' would have been a much better name.

Hm, I honestly didn't think about it before writing, its probably some bad translation I made from german, but doesn't distance make sense here too, viewing the vector as an aggregate of both an x and an y distance? Thats all a vector is after all, whether its two position or two distancen components, isn't it? In my own code, I'd put a prefix befor it, like vDist, which should make it a little more clear.

The distance between two points is the length of the difference vector, so of course these things are related. Still, I like my variables to have names as clear as possible, and calling a vector `dist' is just not clear enough. Someone reading the code might assume the wrong type for it, given its name.

A vector is not "two distancen components" at all. If something can have a value of -5, it's not a distance.


A vector is not "two distancen components" at all. If something can have a value of -5, it's not a distance.

Apologies for my poor wording. I was refering to the fact that you said "A distance is a number, not a vector", and a vector is (AFAIK) a tuple of two numbers. In this case, the distancen on the x - axis and on the y-axis. I didn't know about that a distance cannot be negative though, so thanks for clearing me up.


I was refering to the fact that you said "A distance is a number, not a vector", and a vector is (AFAIK) a tuple of two numbers.

A [two-dimensional] vector is a pair of numbers once you have decided on a basis. But "a number" and "a pair of numbers" are not the same thing: In programming terms, they have different types.

I've seen the term "signed distance" used before especially with regards to distance to plane checks (+ve means it is in front, -ve behind a plane with respect to the plane normal).

But what is normally meant by distance is something which satisfies the properties of a metric http://en.wikipedia.org/wiki/Metric_%28mathematics%29

i.e. given a function d(x, y) where x, y are members of a set and d(x, y) is a real number

d(x, y) >= 0 with d(x, y) = 0 if and only if x = y

d(x, y) = d(y, x)

d(x, z) <= d(x, y) + d(y, z) [triangle inequality; it's never quicker to get from x to z by going via y]

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

This topic is closed to new replies.

Advertisement