You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Manim将椭圆点集渲染为圆形?行星轨道动画问题

行星轨道在Manim中显示为圆形而非椭圆的原因及解决方法

调用compute_orbit()生成的行星轨道点集,在Matplotlib中能正常显示为椭圆,但导入Manim的ThreeDScene后却呈现为圆形,核心原因及解决方法如下:

核心原因

  • 3D相机视角问题:Manim的ThreeDScene默认相机视角为正上方,此时XY平面内的椭圆会因垂直投影而看起来像圆形。
  • 未主动调整相机参数:默认视角下,轨道的扁率无法通过投影体现,需要手动设置相机的俯仰角(phi)和方位角(theta)来获取合适的观察角度。

原代码片段

from manim import *
from astroquery.jplhorizons import Horizons
import numpy as np
import scipy.integrate

def get_initial_conditions(planet_id):
        obj = Horizons(id=planet_id, location='@sun', epochs=2000.0)
        eph = obj.vectors()
        position = np.array([eph['x'][0], eph['y'][0], eph['z'][0]]) * 1.496e11
        velocity = np.array([eph['vx'][0], eph['vy'][0], eph['vz'][0]])  * (1.496e11/86400)    
        scale_factor_position = 1  
        scale_factor_velocity = 1  
        return {
            "position": np.array(position) / scale_factor_position,
            "velocity": np.array(velocity) / scale_factor_velocity
        }

def compute_orbit(central_mass=1.989e30,rotating_mass=5.972e24, dt=10000, total_time=31536000):
        initial_conditions_data = get_initial_conditions(399)
        initial_conditions = [
            initial_conditions_data['position'][0], initial_conditions_data['velocity'][0],
            initial_conditions_data['position'][1], initial_conditions_data['velocity'][1],
            initial_conditions_data['position'][2], initial_conditions_data['velocity'][2]
                            ]

        def f(t, state):
            x, vx, y, vy, z, vz = state
            r = np.sqrt(x**2 + y**2 + z**2) + 1e-5  
            G = 6.67430e-11
            Fx = -G * central_mass * rotating_mass * x / r**3
            Fy = -G * central_mass * rotating_mass * y / r**3
            Fz = -G * central_mass * rotating_mass * z / r**3
            return [vx, Fx / rotating_mass, vy, Fy / rotating_mass, vz, Fz / rotating_mass]


        t_span = (0, total_time)
        t_eval = np.arange(0, total_time, dt)  
        sol = scipy.integrate.solve_ivp(
        f, 
        t_span, 
        initial_conditions, 
        t_eval=t_eval, 
        rtol=1e-3, 
        atol=1e-6)
        x = sol.y[0] / 1e11 
        y = sol.y[2]  / 1e11
        z = sol.y[4]  / 1e11
        positions = np.column_stack((x, y, z))
        return positions


class Space(ThreeDScene):
    def construct(self):
        orbit = ThreeDVMobject()
        data = compute_orbit()
        orbit.set_points_as_corners(data)
        self.add(orbit)
        self.wait(3)

解决方法

修改Space类的construct方法,添加相机视角调整代码,从斜上方观察轨道,椭圆形状即可显现:

class Space(ThreeDScene):
    def construct(self):
        orbit = ThreeDVMobject()
        data = compute_orbit()
        orbit.set_points_as_corners(data)
        self.add(orbit)
        # 设置相机视角:俯仰角75度,方位角30度,确保椭圆扁率可见
        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
        self.wait(3)
        # 可选:添加旋转动画让视角动态变化,更直观展示轨道形状
        self.begin_ambient_camera_rotation(rate=0.1)
        self.wait(5)

额外建议:可以在场景中添加太阳作为参考点,进一步突出轨道的椭圆特性:

class Space(ThreeDScene):
    def construct(self):
        # 添加太阳参考点
        sun = Sphere(radius=0.1, color=YELLOW).shift(ORIGIN)
        orbit = ThreeDVMobject()
        data = compute_orbit()
        orbit.set_points_as_corners(data)
        self.add(sun, orbit)
        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
        self.begin_ambient_camera_rotation(rate=0.1)
        self.wait(5)

内容的提问来源于stack exchange,提问作者hassam rajpoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:36:13