沿椭圆的长轴旋转椭圆

问题描述 投票:0回答:1

我的目标是绘制 3D 旋转椭球体。 我有一个代码用于在 2D 中创建相应椭圆的模拟:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse

# Define ground station and airplane positions
ground_station = np.array([2, 2])
airplane = np.array([4, 5])

# Actual distance between ground station and airplane
true_distance = np.linalg.norm(ground_station - airplane)

# Distance measured by DME
dme_distance = 1.25 * true_distance

# Calculate the center of the ellipse (midpoint between ground station and airplane)
center = (ground_station + airplane) / 2

# Calculate the semi-major and semi-minor axes of the ellipse
a = dme_distance / 2
b = np.sqrt(a**2 - (true_distance / 2)**2)

# Calculate the angle of rotation for the ellipse
angle = np.arctan2(airplane[1] - ground_station[1], airplane[0] - ground_station[0])

# Visualize the ellipse
ellipse = Ellipse(xy=center, width=2 * a, height=2 * b, angle=np.degrees(angle), edgecolor='r', linestyle='dotted', fill=False)

# Visualize simulation
plt.figure(figsize=(8, 6))
plt.plot(*ground_station, 'ro', label='Ground Station')
plt.plot(*airplane, 'bo', label='Airplane')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('2D Simulation')
plt.legend()
plt.grid(True)

plt.gca().add_patch(ellipse)
plt.axis('equal')
plt.show()

这会创建这样一个椭圆:

我现在需要将这个 2D 表示扩展到 3D。两个焦点保持在 x-y 平面上,椭圆的属性保持不变。 目标是沿着椭圆的长轴旋转椭圆以获得旋转椭球。

我的方法是生成 360 个椭圆,其中每个椭圆旋转 1 度。不知怎的,我无法让它在不改变其属性的情况下旋转。

另一种方法是将其直接绘制为椭球体。这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import Ellipse

ground_station_3d = np.array([2, 2, 0])  
airplane_3d = np.array([4, 5, 0])        

true_distance = np.linalg.norm(ground_station_3d[:2] - airplane_3d[:2])

dme_distance = 1.25 * true_distance

center = (ground_station_3d + airplane_3d) / 2

a = dme_distance / 2
b = np.sqrt(a**2 - (true_distance / 2)**2)

angle = np.arctan2(airplane_3d[1] - ground_station_3d[1], airplane_3d[0] - ground_station_3d[0])

ellipse_height = 5

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = center[0] + a * np.outer(np.cos(u), np.sin(v))
y = center[1] + b * np.outer(np.sin(u), np.sin(v))
z = center[2] + ellipse_height * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, color='r', alpha=0.5)

ax.scatter(*ground_station_3d, color='b', label='Bodenstation')
ax.scatter(*airplane_3d, color='g', label='Flugzeug')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D-Simulation')
ax.legend()

plt.show()

由于我对轴的计算完全相同,因此我预计结果在某种程度上是正确的。但生成的椭球体不包含 2 个焦点中的任何一个,因此不具有与 2D 椭球体相同的属性。

我需要帮助找到沿椭圆长轴旋转椭圆的正确方法。 如果在 python 中没有正确的方法,我将不胜感激在其他编程语言中寻找方法的帮助。

问候

python matplotlib plot ellipse
1个回答
0
投票

我建议您首先以标准意义定向椭球体(以原点为中心,半轴 a、b、c 沿 x、y、z 方向),然后绕 z 轴旋转适当的角度,同时平移为正确的中心。

对于规范对齐:

xp = a cos(u)
yp = b sin(u)cos(u)
zp = c sin(u)sin(v)

然后将平移添加到中心(正如您当前所做的那样)并同时绕 z 轴旋转:

x = xc + cos(angle) * xp - sin(angle) * yp
y = yc + sin(angle) * xp + cos(angle) * zp
z = zc + zp

代码看起来像

import math
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

ground_station_3d = np.array([2, 2, 0])  
airplane_3d = np.array([4, 5, 0])        

true_distance = np.linalg.norm( ground_station_3d - airplane_3d )
center = ( ground_station_3d + airplane_3d ) / 2

dme_distance = 1.25 * true_distance
a = dme_distance / 2
b = np.sqrt( a ** 2 - ( true_distance / 2 ) ** 2 )
c = 5
angle = math.atan2( airplane_3d[1] - ground_station_3d[1], airplane_3d[0] - ground_station_3d[0] )
cosangle = math.cos( angle )
sinangle = math.sin( angle )

N = 100
u = np.linspace( 0, 2 * np.pi, N )
v = np.linspace( 0, np.pi, N )

# Conventionally aligned with the axes first
xp = a * np.outer( np.cos(u), np.ones(N) )
yp = b * np.outer( np.sin(u), np.cos(v) )
zp = c * np.outer( np.sin(u), np.sin(v))

# Now translate and also rotate about the z axis
x = center[0] + cosangle * xp - sinangle * yp
y = center[1] + sinangle * xp + cosangle * yp
z = center[2] + zp

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z, color='r', alpha=0.5)
ax.scatter(*ground_station_3d, color='b', label='Bodenstation')
ax.scatter(*airplane_3d, color='g', label='Flugzeug')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D-Simulation')
ax.legend()
plt.show()

输出:

© www.soinside.com 2019 - 2024. All rights reserved.