ID:2125841
 
How would I convert a degree of an angle to its closest direction.
IE: 22.5 degree angle to one of these directions NORTH and NORTHEAST. I suck when it comes to math and would appreciate a little help in this area. =]
Here's a section of my standard library that does this.

var
list
__dir_ang = list(90,270,null,0,45,315,0,180,135,225,180,null,90,180,null)
__dir_names = list("north"=NORTH,"south"=SOUTH,null,"east"=EAST,"northeast"=NORTHEAST,"southeast"=SOUTHEAST,null,"west"=WEST,"northwest"=NORTHWEST,"southwest"=SOUTHWEST)
__euler_dirs = list(EAST,NORTHEAST,NORTH,NORTHWEST,WEST,SOUTHWEST,SOUTH,SOUTHEAST)

#define dir2ang(x) __dir_ang[x]
#define dir2text(x) __dir_names[x]
#define text2dir(name) __dir_names[lowertext(name)]

proc
ang2dir(x)
//ensure that the angle is between 0 and 360
if(x<0)
x = x+360*ceil(x/-360)
. = __euler_dirs[floor(ceil(x/22.5)%16 / 2)+1]


The rest of my standard library can be found here:

http://www.byond.com/forum/?post=1898015
I forgot to include this in my Directions library, but here's my version:

FromDegrees(Degrees)
var global/from_degrees[] = list(NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST)
return from_degrees[1 + round(8 + Degrees * 8 / 360, 1) % 8]

For me, 0 degrees is north and 90 degrees is east.

And here's the 4-directional version (with the above being 8-directional):
FromDegreesToCardinal(Degrees)
var global/from_degrees[] = list(NORTH, EAST, SOUTH, WEST)
return from_degrees[1 + round(4 + Degrees * 4 / 360, 1) % 4]


I'll update my library to include these.
Thanks guys ill look into them.
The reason I forgot to include it is because, usually, you don't start with an angle. Usually, you start with an offset, such as the number of pixels from one position to the next (aka "displacement vector").

With that, you'd use my Directions.FromOffset(X, Y).

Avoid atan2() if you can. I only ever use it for transforms (and even then, it's not necessary if you provide the matrix elements).
For me, 0 degrees is north and 90 degrees is east.

Kaio and I STRONGLY disagree on the subject of cardinality. Kaiochao uses bearings, while I use euler vectors.

You'll find that unless you are working in aerospace engineering, you are going to orient 0 to the East with 90 degrees being north.

Almost every single field that uses trig employs euler vectors with positive increases tending counter-clockwise.

IMO you are setting yourself up for failure telling people to use sin() for the X component and cos() for the Y component.

Just plugging that little quirk out there at you again Kaio. Your orientations are backward and No other standard 2D/3D engine or API tool uses bearings like you choose to continue doing so. Offering this method of thinking to people can only hurt them in the long run when they inevitably transition to another engine or toolset.

Just a little reminder.
In response to Ter13
Ter13 wrote:
his opinion

Yeah, but this is DM we're talking about. His way makes more sense as you're limited to top-down and pseudo side-scroller. 0 being north, 90 being east. imo ofc ;)

His way makes more sense as you're limited to top-down and pseudo side-scroller.

No it doesn't. It's arbitrary. The difference is that euler vectors are an industry standard that literally every engine and language of consequence use.



Until you've taken any math class above Geometry, your opinion on the subject is spurious at best. Sorry, but you admit yourself you never got very far in math.

Kaiochao doesn't have that excuse. He's asian. I'm pretty sure they are all born with that as part of their firmware.

Standards aren't matters of opinion anymore.

Countries that don't use the metric system:

In response to Ter13
Ter13 wrote:
triggered opinion

Sure :)
While I agree that 0° pointing east makes the most sense given its ubiquity, you're blowing things well out of proportion, as a 90° rotation and an opposite orientation is extremely insignificant mathematically, and both of Kaiochao's choices are quite reasonably motivated given the userbase common to this website; north being 0° and doing rotations clockwise instead of counter-clockwise are both fairly "natural" in a broader cultural context and the "standard" way of doing things in mathematics is as much about convenience and history as it is anything else.

As an aside, I don't know where you got the term "Euler vectors" from, but that's neither a term or thing. I think you're referring to Euler angles, but (1) they are not vectors and can't be treated as such and (2) they are not concerned with the underlying coordinate system or orientation.
I wrote this in response to my "(and even then, it's not necessary if you provide the matrix elements)".

You can get a direction vector from one atom to another atom with this:
vector2
var x, y

New(X = 0, Y = 0)
x = X
y = Y

atom
proc
/* Returns a vector2 with length 1 pointing from
the center of src's bounding box to the center of Other's bounding box,
or null if no direction can be found (src and Other are at the same position).
*/

GetDirectionToAtom(atom/Other)
var dx = Other.CenterX() - CenterX()
var dy = Other.CenterY() - CenterY()
if(dx || dy)
var d = sqrt(dx * dx + dy * dy)
return new /vector2 (dx / d, dy / d)

If your atom's icon points north by default, use this transform:
matrix(direction.y, direction.x, 0, -direction.x, direction.y, 0)

If your atom's icon points east by default, use this transform:
matrix(direction.x, -direction.y, 0, direction.x, direction.y, 0)

No angles, no fuss.