-
-
Save rabbl/1fea7928a957e69ef369eeb1607ed5e1 to your computer and use it in GitHub Desktop.
Rotate X,Y (2D) coordinates around a point or origin in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Lyle Scott, III // [email protected] | |
Multiple ways to rotate a 2D point around the origin / a point. | |
Timer benchmark results @ https://gist.github.com/LyleScott/d17e9d314fbe6fc29767d8c5c029c362 | |
""" | |
from __future__ import print_function | |
import math | |
import numpy as np | |
def rotate_via_numpy(xy, radians): | |
"""Use numpy to build a rotation matrix and take the dot product.""" | |
x, y = xy | |
c, s = np.cos(radians), np.sin(radians) | |
j = np.matrix([[c, s], [-s, c]]) | |
m = np.dot(j, [x, y]) | |
return float(m.T[0]), float(m.T[1]) | |
def rotate_origin_only(xy, radians): | |
"""Only rotate a point around the origin (0, 0).""" | |
x, y = xy | |
xx = x * math.cos(radians) + y * math.sin(radians) | |
yy = -x * math.sin(radians) + y * math.cos(radians) | |
return xx, yy | |
def rotate_around_point_lowperf(point, radians, origin=(0, 0)): | |
"""Rotate a point around a given point. | |
I call this the "low performance" version since it's recalculating | |
the same values more than once [cos(radians), sin(radians), x-ox, y-oy). | |
It's more readable than the next function, though. | |
""" | |
x, y = point | |
ox, oy = origin | |
qx = ox + math.cos(radians) * (x - ox) + math.sin(radians) * (y - oy) | |
qy = oy + -math.sin(radians) * (x - ox) + math.cos(radians) * (y - oy) | |
return qx, qy | |
def rotate_around_point_highperf(xy, radians, origin=(0, 0)): | |
"""Rotate a point around a given point. | |
I call this the "high performance" version since we're caching some | |
values that are needed >1 time. It's less readable than the previous | |
function but it's faster. | |
""" | |
x, y = xy | |
offset_x, offset_y = origin | |
adjusted_x = (x - offset_x) | |
adjusted_y = (y - offset_y) | |
cos_rad = math.cos(radians) | |
sin_rad = math.sin(radians) | |
qx = offset_x + cos_rad * adjusted_x + sin_rad * adjusted_y | |
qy = offset_y + -sin_rad * adjusted_x + cos_rad * adjusted_y | |
return qx, qy | |
def _main(): | |
theta = math.radians(90) | |
point = (5, -11) | |
print(rotate_via_numpy(point, theta)) | |
print(rotate_origin_only(point, theta)) | |
print(rotate_around_point_lowperf(point, theta)) | |
print(rotate_around_point_highperf(point, theta)) | |
if __name__ == '__main__': | |
_main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment