Philipp
Philipp

Reputation: 323

Rotating a set of 2D points about another point

I want to rotate an array of coordinates about a given point. To realise that I rotate every coordinate by using a for loop and put the rotated coordinates back into my array. When executing the code I get IndexError: index 1 is out of bounds for axis 0 with size 1 so there must be a mistake inside the loop which I cannot identify.

import math
import numpy as np

airfoil = np.array([[3349.67075, 2138.     ],
       [3225.86375, 2137.77425],
       [3060.79325, 2137.757  ],
       [2901.63575, 2136.89675],
       [2803.16825, 2136.89   ],
       [2728.33625, 2136.719  ],
       [2687.33225, 2136.89   ],
       [2611.475  , 2136.377  ],
       [2600.     , 2138.     ],
       [2602.24925, 2146.457  ],
       [2605.66625, 2152.2665 ],
       [2611.475  , 2158.7585 ],
       [2618.65025, 2164.39625],
       [2638.12775, 2176.0145 ],
       [2680.49825, 2193.95375],
       [2725.0895 , 2208.134  ],
       [2786.08325, 2220.2645 ],
       [2853.398  , 2227.61075]])


theta = 1.5708  # 90 degree
ox, oy = 2000, 2000  # point to rotate about

for i in range(airfoil.shape[0]-1):
    qx = ox + math.cos(theta) * (airfoil[i][0] - ox) - math.sin(theta) * 
        (airfoil[i][1] - oy)
    qy = oy + math.sin(theta) * (airfoil[i][0] - ox) + math.cos(theta) * 
        (airfoil[i][1] - oy)
    airfoil = np.column_stack((qx, qy))

The elements (x and y coordinates) are callable with airfoil[0][0] or airfoil[0][1] to airfoil[17][0] and airfoil[17][1] without any problems. So the mistake must be somewhere else.

I already read similiar questions which could not help me.

Upvotes: 0

Views: 3178

Answers (2)

Philipp
Philipp

Reputation: 323

I modified my code and it works now.

theta = 1.5708
ox, oy = 2000, 2000

qx = []
qy = []

for i in range(airfoil.shape[0]):
    qx.append(ox + math.cos(theta) * (airfoil[i][0] - ox) - math.sin(theta) * (airfoil[i][1] - oy))
    qy.append(oy + math.sin(theta) * (airfoil[i][0] - ox) + math.cos(theta) * (airfoil[i][1] - oy))

airfoil = np.column_stack((qx, qy))

Nevertheless I agree that using matrix multiplication is more elegant than my solution. Thanks!

Upvotes: 0

b-fg
b-fg

Reputation: 4137

To have airfoil = np.column_stack((qx, qy)) inside the loop is not a good idea since it modifies the airfoil array at every iteration. Actually, by doing numpy.column_stack you make airfoil have shape (1,2) after the first iteration overriding the original airfoil which has shape (18,2) (hence on the second iteration it gives you the shape error).

You would be better by storing the rotated points on another variable. And even better, perform the rotation all at once with a simple A v = w, where A is your rotation matrix, v your airfoil coordinates and w the rotated coordinates.

Here is what you could do using the rotation matrix A

theta = 1.5708  # 90 degree
ox, oy = 2000, 2000  # point to rotate about
A = np.matrix([[np.cos(theta), -np.sin(theta)],
               [np.sin(theta), np.cos(theta)]])

w = np.zeros(airfoil.shape)
airfoil_shifted = airfoil-np.array([ox,oy])
for i,v in enumerate(airfoil_shifted):
  w[i] = A @ v

where w will contain the rotated coordinates.

Upvotes: 3

Related Questions