为何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
相关产品推荐
相关产品推荐

