小惑星/彗星/隕石軌道を視覚化するためのPythonスクリプト(GitHub LINK)を書いています。スクリプトはまた、惑星とその軌道の位置をプロットします。Matplotlib 3Dプロット - パラメトリックカーブを特定の視点からラップアラウンドする
小さな半長軸(すなわち、「より小さい」軌道)の軌道に対してはうまく動作します。しかし、私が(例えば、ハレー型の彗星の)海王星を越える軌道を持ち、特定の視点から見ると、(より良い言葉の欠如のために)奇妙な「回り込み」があります。
私が何を意味するかをお見せしましょう:
画像編集:http://i.imgur.com/onSZG8s.png
この画像は、それが破壊されない視点からのプロットを示しています。
同じプロットを少し右に回転させると、あたかも軌道が半分に折り畳まれ、その方向が逆転しているようです!
大きな距離からプロットを見ると、そのようにプロットされていることがわかります。
ここでは、問題を再現できるコードの最小限のバージョンを示します。 「ラップアラウンド」は、カメラの視点が大回りの軌道とほぼ平行である場合にのみ発生します。
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
def orbitalElements2Cartesian(a, e, I, peri, node, E):
""" Convert orbital elements to Cartesian coordinates in the Solar System.
Args:
a (float): semi-major axis (AU)
e (float): eccentricity
I (float): inclination (degrees)
peri (float): longitude of perihelion (degrees)
node (float): longitude of ascending node (degrees)
E (float): eccentric anomaly (radians)
"""
# The source of equations used:
# http://farside.ph.utexas.edu/teaching/celestial/Celestialhtml/node34.html
# Check if the orbit is parabolic or hyperbolic
if e >=1:
e = 0.99999999
# Convert degrees to radians
I, peri, node = map(np.radians, [I, peri, node])
# True anomaly
theta = 2*np.arctan(np.sqrt((1.0 + e)/(1.0 - e))*np.tan(E/2.0))
# Distance from the Sun to the poin on orbit
r = a*(1.0 - e*np.cos(E))
# Cartesian coordinates
x = r*(np.cos(node)*np.cos(peri + theta) - np.sin(node)*np.sin(peri + theta)*np.cos(I))
y = r*(np.sin(node)*np.cos(peri + theta) + np.cos(node)*np.sin(peri + theta)*np.cos(I))
z = r*np.sin(peri + theta)*np.sin(I)
return x, y, z
if __name__ == '__main__':
# Example orbital elements
# a, e, incl, peri, node
orb_elements = np.array([
[2.363, 0.515, 4.0, 205.0, 346.1],
[0.989, 0.089, 3.1, 55.6, 21.2],
[0.898, 0.460, 1.3, 77.1, 331.2],
[104.585332285, 0.994914, 89.3950, 130.8767, 282.4633]
])
# Setup the plot
fig = plt.figure()
ax = fig.gca(projection='3d')
# Eccentric anomaly (full range)
E = np.linspace(-np.pi, np.pi, 100)
# Plot the given orbits
for i, orbit in enumerate(orb_elements):
a, e, I, peri, node = orbit
# Take extra steps in E if the orbit is very large
if a > 50:
E = np.linspace(-np.pi, np.pi, (a/20.0)*100)
# Get the orbit in the cartesian space
x, y, z = orbitalElements2Cartesian(a, e, I, peri, node, E)
# Plot orbits
ax.plot(x, y, z, c='#32CD32')
# Add limits (in AU)
ax.set_xlim3d(-5,5)
ax.set_ylim3d(-5,5)
ax.set_zlim3d(-5,5)
plt.tight_layout()
plt.show()
私は少し馬鹿馬鹿しくて、適切な解決策を見つけることができません。私はいくつかの助けに非常に感謝します!
これを再現するための最小限の例(インライン)を入力してください。 – tacaswell
@tcaswell提案していただきありがとうございます!私は投稿を編集しました。 –
は、レンダリング前に間違ってカリングカーブのように見えます。画面全体を横切る2つの大きな線は、投影面を横切る曲線の2つのセグメントである可能性が最も高い。 1つの点が可視領域または可視領域のすぐ近くにあり、2つ目は可視領域にはありません。セグメントが切り取られていないので、カメラの背後にある可能性が最も高い(つまり、なぜミラーリングされている)場合でも、レンダリングされ、スクリーンを通して補間されます。少なくともそれは私の賭けです。完全に見えるセグメントだけをレンダリングしてみてください。 – Spektre