Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate point about another point in degrees python

If you had a point (in 2d), how could you rotate that point by degrees around the other point (the origin) in python?

You might, for example, tilt the first point around the origin by 10 degrees.

Basically you have one point PointA and origin that it rotates around. The code could look something like this:

PointA=(200,300)
origin=(100,100)

NewPointA=rotate(origin,PointA,10) #The rotate function rotates it by 10 degrees
like image 732
user2592835 Avatar asked Dec 19 '15 15:12

user2592835


4 Answers

The following rotate function performs a rotation of the point point by the angle angle (counterclockwise, in radians) around origin, in the Cartesian plane, with the usual axis conventions: x increasing from left to right, y increasing vertically upwards. All points are represented as length-2 tuples of the form (x_coord, y_coord).

import math

def rotate(origin, point, angle):
    """
    Rotate a point counterclockwise by a given angle around a given origin.

    The angle should be given in radians.
    """
    ox, oy = origin
    px, py = point

    qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
    qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
    return qx, qy

If your angle is specified in degrees, you can convert it to radians first using math.radians. For a clockwise rotation, negate the angle.

Example: rotating the point (3, 4) around an origin of (2, 2) counterclockwise by an angle of 10 degrees:

>>> point = (3, 4)
>>> origin = (2, 2)
>>> rotate(origin, point, math.radians(10))
(2.6375113976783475, 4.143263683691346)

Note that there's some obvious repeated calculation in the rotate function: math.cos(angle) and math.sin(angle) are each computed twice, as are px - ox and py - oy. I leave it to you to factor that out if necessary.

like image 168
Mark Dickinson Avatar answered Oct 09 '22 09:10

Mark Dickinson


An option to rotate a point by some degrees about another point is to use numpy instead of math. This allows to easily generalize the function to take any number of points as input, which might e.g. be useful when rotating a polygon.

import numpy as np

def rotate(p, origin=(0, 0), degrees=0):
    angle = np.deg2rad(degrees)
    R = np.array([[np.cos(angle), -np.sin(angle)],
                  [np.sin(angle),  np.cos(angle)]])
    o = np.atleast_2d(origin)
    p = np.atleast_2d(p)
    return np.squeeze((R @ (p.T-o.T) + o.T).T)


points=[(200, 300), (100, 300)]
origin=(100,100)

new_points = rotate(points, origin=origin, degrees=10)
print(new_points)
like image 45
ImportanceOfBeingErnest Avatar answered Oct 09 '22 10:10

ImportanceOfBeingErnest


import math

def rotate(x,y,xo,yo,theta): #rotate x,y around xo,yo by theta (rad)
    xr=math.cos(theta)*(x-xo)-math.sin(theta)*(y-yo)   + xo
    yr=math.sin(theta)*(x-xo)+math.cos(theta)*(y-yo)  + yo
    return [xr,yr]
like image 8
Gabriel Eng Avatar answered Oct 09 '22 11:10

Gabriel Eng


After going through a lot of code and repositories. This function worked best for me. Also it is efficient as it calculates sine and cosine values only once.

import numpy as np
def rotate(point, origin, degrees):
    radians = np.deg2rad(degrees)
    x,y = point
    offset_x, offset_y = origin
    adjusted_x = (x - offset_x)
    adjusted_y = (y - offset_y)
    cos_rad = np.cos(radians)
    sin_rad = np.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
like image 5
an0nym0use Avatar answered Oct 09 '22 09:10

an0nym0use