如何解决使用多个角度旋转 xy 点 - python 绕原点旋转围绕给定枢轴旋转示例
我目前正在使用参考点和固定点之间的角度旋转 xy 点。我希望包含两个固定点来旋转点。我只是不确定如何实现这一点。
使用下面,旋转的点显示在 x
和 y
中。 X_Ref
、Y_Ref
和X_Fixed
、Y_Fixed
之间的角度用于旋转点(在初始分布图中显示为黑色矢量)。
当前的过程是将固定/参考点转换为复数以计算旋转。我最终将旋转的点重新居中,使 X_Ref
,Y_Ref
以 0,0 为中心(如旋转后的图中所示)。
但是,我希望包含 X_Ref
、Y_Ref
和 X2_Fixed
、Y2_Fixed
之间的角度。旋转后的图显示了旋转点时如何只考虑一个角度。我希望能兼顾两者以返回预期的输出。欢迎提出任何建议。
df = pd.DataFrame({
'Period' : ['1','1','1'],'Label' : ['A','B','C','D'],'x' : [0.0,-1.0,3.0,2.0],'y' : [0.0,0.0],'X_Ref' : [1,1,1],'Y_Ref' : [1,'X_Fixed' : [-2,-2,-2],'Y_Fixed' : [-2,'X2_Fixed' : [4,4,4],'Y2_Fixed' : [-2,})
fig,ax = plt.subplots(figsize = (6,6))
ax.set_xlim(-5,5)
ax.set_ylim(-5,5)
ax.grid(False)
初始分发:
# Rotate points using _Ref and _Fixed
# Re-center resulting distribution with _Ref as 0,0
for f in ['Ref','Fixed']:
df[f] = df['X_'+f] + 1j*df['Y_'+f]
df.drop(['X_'+f,'Y_'+f],axis=1,inplace=True)
df['angle'] = - np.angle(df['Ref'] - df['Fixed'])
df['rotated'] = (df['x'] + 1j*df["y"]) * np.exp(1j*df['angle'])
for f in ['Ref','Fixed']:
df[f+'_Rotated'] = df[f] * np.exp(1j*df['angle'])
df['translation'] = - df['Ref_Rotated']
df['NewPoint'] = df['rotated'] + df['translation']
for f in ['Ref','Fixed']:
df[f+'_Transformed'] = df[f+'_Rotated'] + df['translation']
df['x2'] = np.real(df['NewPoint'])
df['y2'] = np.imag(df['NewPoint'])
for f in ['Ref','Fixed']:
df['NewX_'+f] = np.real(df[f+'_Transformed'])
df['NewY_'+f] = np.imag(df[f+'_Transformed'])
output = df[['Label','x2','y2','NewX_Ref','NewY_Ref','NewX_Fixed','NewY_Fixed']]
旋转后:
ax.scatter(output['NewX_Ref'],output['NewY_Ref'],marker = 'x',zorder = 5,color = 'black')
ax.scatter(output['NewX_Fixed'],output['NewY_Fixed'],marker = '+',color = 'red')
ax.scatter(output['x2'],output['y2'],marker = 'o')
预期轮换:
解决方法
要解决的问题不明确。根据我的理解,问题是使一个点围绕一个枢轴点旋转一定的角度θ。 pandas 的数据框不太适合这个问题,让我们改用 numpy。为方便起见,我们首先定义一个类来表示平面中的点和向量。
class Coord:
def __init__(self,x,y):
x,y = np.array(x),np.array(y)
assert x.shape == y.shape
self.x,self.y = x,y
self.shape = x.shape
@property
def radius(self):
return np.sqrt(self.x ** 2 + self.y ** 2)
def __sub__(self,other):
return Coord(self.x - other.x,self.y - other.y)
def __add__(self,other):
return Coord(self.x + other.x,self.y + other.y)
def __repr__(self):
return f"Coord({self.x},{self.y})"
例如 Coord(2,3)
只是表示一个点或坐标为 (2,3) 的向量。可以执行加法和减法:Coord(2,3) + Coord(1,-2)
返回 Coord(3,1)
。注意 x
和 y
属性可以是 numpy 数组。在这种情况下,Coord
实例可以作为一组点。例如 Coord([1,2,0],[2,-1,3])
表示点/向量 (1,2),(2,-1) and (0,3)
。
绕原点旋转
让我们在类 _rotate_from_origin
中添加一个方法 Coord
,用于输出旋转后的点。您可以在 here 中找到有关如何旋转点的说明。
def _rotate_from_origin(self,theta):
return Coord(
self.x * np.cos(theta) - self.y * np.sin(theta),self.x * np.sin(theta) + self.y * np.cos(theta))
围绕给定枢轴旋转
您似乎定义了坐标 x_ref
和 y_ref
,其想法是不是围绕原点而是围绕该参考点执行旋转。我们可以使用以下方法简单地实现这一点:
def rotate(self,theta,pivot=None):
if not pivot:
pivot = Coord(0,0)
return (self - pivot)._rotate_from_origin(theta) + pivot
就是这样!现在您可以对任何点或一组点使用此方法。
示例
让我们试试你的例子(或者至少是我对它的理解)。
startA = Coord([0,-1],[ 0,-1]) # points that will be rotated with an angle of thetaA
startB = Coord([3,2],[-1,0]) # will be rotated with an angle of thetaB
pivot = Coord(1,1)
thetaA = -np.pi / 4
thetaB = np.pi / 4
## Rotate each set of points with the corresponding angle
rotatedA = startA.rotate(thetaA,pivot=pivot)
rotatedB = startB.rotate(thetaB,pivot=pivot)
## Display the result
plt.plot(pivot.x,pivot.y,'ko')
plt.plot(startA.x,startA.y,'o',c='gold')
plt.plot(rotatedA.x,rotatedA.y,c='gold')
plt.plot(startB.x,startB.y,c='lightblue')
plt.plot(rotatedB.x,rotatedB.y,c='royalblue')
注意这里的 theta
参数是一个整数。在这种情况下,每个点都将使用相同的 theta
值旋转。但是可以使用多个 theta 值来使每个点旋转不同。例如,我们可以这样做:
starts = Coord([0,3,[0,0])
pivot = Coord(1,1)
thetas = (np.pi / 4) * np.array([-1,1,1])
rotated = starts.rotate(thetas,pivot=pivot)
这同样适用于 pivot
参数。基本上这是将函数与 numpy 一起使用时的预期行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。