get_ procs

by Bravo1
A helpful set of procs for angular and positional data! [More]
To download this library for your Linux/Mac installation, enter this on your command line:

DreamDownload byond://Bravo1.get_procs##version=4

Emulator users, in the BYOND pager go to File | Open Location and enter this URL:

byond://Bravo1.get_procs##version=4

163 downloads
Version 4
Date added: Jan 7 2013
Last updated: Feb 1 2013
5 fans
Greetings everyone, this is a short functional library to give some helpful get_ procs based on positional and angular inputs.

It also includes a helpful replacement for get_dir called get_dir_angle()
As it stands, get_dir will return NORTH, SOUTH, EAST, and WEST only when the target atom is at exactly that direction from the source.
Otherwise it returns a combination, such as NORTHEAST. Let's have an example...

A=source, B=target

_____________________________________
| |
| A |
| B |
|_____________________________________|


In the example above, B is 26 spaces tot he right of A, while it's only 1 space lower. BYOND's get_dir returns SOUTHEAST in this situation.
The issue is that if you want A's dir to look intuitively toward B, it would return EAST, as the offset in the Y position is far outweighed by that in the X position.

That is what get_dir_angle() does. First it uses get_angle() to calculate the proper angle between A and B, and uses that angle to return a more appropriate direction.

This is helpful in projects that use 8 directional icons, or just want to have more approprite returned angle. I've also included a version for 4 directional calls in case you'd like
to only return NORTH, EAST, SOUTH, or WEST, and never anything inbetween. There is also a slightly more accurate version for mobs, in case you want step offsets to be applied as well.


Procs:
get_dir_angle(atom/a,atom/b) - This uses the angle between atoms (a) and (b) to give a more appropriate result than get_dir.

get_dir_angle4(aton/a,atom/b) - much like get_dir_angle, but only resolves the four cardinal directions.

get_angle(atom/a,atom/b) - a basic angle proc for two atoms based on loc, this proc is used for get_dir_angle, as sometimes you want the angle for atoms. This uses get_angle_nums to process its return.

get_angle_nums(ax,ay,bx,by) - a basic angle proc for numerical values. This is used if you already have four numbers to pass as arguments instead of atoms. This is used by get_angle().

get_pix_pos(atom/a) - This proc is used by get_angle() in the event that any of the arguments are atoms. It returns a list of the atoms position (in pixels) in two variables. Ex: list(320,336)

get_angle_dir(atom/a) - this proc gives you the angle based on a given atom (or dir). This is helpful if you're using accurate angles already and you wish to find the angle of a dir.

get_turn(a,b) - when working with angles, find which direction, clockwise or counterclockwise, the angle (a) should be adjusted in order to reach the angle provided (b).

between(a,b,c,strict) - find whether or not value (a) is between (b) and (c). Strict denotes that (a) cannot be equal to (b) or (c).

get_dist_sq(atom/a,atom/b) - a helper proc I added for the hell of it. Returns a true distance in pixels based on pythagorean theorem a^2+b^2=c^2


Updates:
2/1/2013 - Updates to make it get_angle_nums a bit faster. Thanks to FIREking and Mangun2k for their input!
Removed the need for get_angle_step and any other code that was argument specific. get_angle now accepts atoms, mobs, or numeric values.
Added two helper procs one that are used in the library. get_pix_pos() and get_dist_sq()
Included demo files so that some simple profiling can be done.

1/10/2013 - Updated to change how get_turn works. Much more efficient at grabbing the proper direction to turn now. Cut the proc down to 1/3 it's original size.

1/10/2013 - Updated to include between() proc, fixed get_angle_step to work for any world.icon_size.

Comments

Turboskill: (Dec 16 2013, 5:43 am)
so atan3 would be f_atan2?
Magnum2k: (Feb 1 2013, 6:24 am)
It is. I forgot to change the name in the snippet. Haha.
Bravo1: (Feb 1 2013, 6:19 am)
It doesn't look like atan3 is getting called in that profile. o_o
Magnum2k: (Feb 1 2013, 5:57 am)
You can also optimize Lummox's algorithm a bit further. I did some testing and the snippet below is a bit faster, though the speed increase is negligible.

proc

// Original atan2() by Lummox R
atan2(x, y)
if(!x && !y)
return 0
. = arccos(x / sqrt(x * x + y * y))
return y >= 0 ? . : -.

// Modified atan2() by Magnum2k
atan3(x, y)
if(isnull(x || y))
return 0
return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : \
-arccos(x / sqrt(x * x + y * y))


Result:


EDIT: Lummox JR's atan2() seems to get more exhausted as more calls are made to it.
FIREking: (Feb 1 2013, 1:44 am)
Bravo1 wrote:
Ok, I got some more implementations, and all of them are returning the same values (I prefer North to be 0, South to be 180, East to be 90, and West to be 270).

Unfortunately BYOND and trigonometry doesn't like that. You'll be making a -270 adjustment to every input.

*shrugs* If that's how you prefer it though...

Yeah, which isn't a big deal.