Pseudoangles

From vegard.wiki
Revision as of 19:34, 17 December 2019 by Vegard (talk | contribs) (typo)
Jump to navigation Jump to search

Pseudoangles allow you to compare the angles of two vectors without actually computing the angle itself (which could be costly). By extension, it also allows you to sort a list of vectors by angle without calling atan() or atan2().

The version you'll typically find on Google [1][2] is basically:

def pseudoangle(y, x):
    r = y / (abs(x) + abs(y))
    if x < 0:
        return 2. - r
    else:
        return 4. + r

This function returns a value between 1 and 5. When using as a sort key, this yields the same behaviour as the key mod(atan2(y, x) + 1.5 * pi, 2. * pi). It is therefore not a direct replacement for atan2() if you care about which angles are considered the smallest/larges, however it does sort in the correct "direction".

If you want to preserve the exact sorting order as if you had used atan2() (with the return value in range 0-4), you can use:

def psuedoangle(y, x):
    r = x / (abs(x) + abs(y))
    if y < 0:
        return 1. + r
    return 3. - r

If you also want the sign of the return value to be the same as for atan2(), i.e. return value in range (-2 to 2), you can use:

def psuedoangle(y, x):
    r = x / (abs(x) + abs(y))
    if y < 0:
        return r - 1.
    return 1. - r

I personally prefer this last version as there are no performance disadvantages to using it anyway.