简体   繁体   中英

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.

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM