Pseudoangles: Difference between revisions

From vegard.wiki
Jump to navigation Jump to search
Content added Content deleted
(typo)
(typo)
Line 12: Line 12:
</source>
</source>


This function returns a value between 1 and 5. When using as a sort key, this yields the same behaviour as the key <tt>mod(atan2(y, x) + 1.5 * pi, 2. * pi)</tt>. It is therefore not a direct replacement for <tt>atan2()</tt> if you care about which angles are considered the smallest/larges, however it does sort in the correct "direction".
This function returns a value between 1 and 5. When used as a sort key, this yields the same behaviour as the key <tt>mod(atan2(y, x) + 1.5 * pi, 2. * pi)</tt>. It is therefore not a direct replacement for <tt>atan2()</tt> 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 <tt>atan2()</tt> (with the return value in range 0-4), you can use:
If you want to preserve the exact sorting order as if you had used <tt>atan2()</tt> (with the return value in range 0-4), you can use:

Revision as of 19:35, 17 December 2019

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