如何用Manim基于Numpy数组绘制点及实现平滑插值曲线?
解决Manim中批量绘点与平滑曲线插值问题
一、批量绘制Numpy数组坐标点的正确方法
你代码的核心问题是用np.zeros数组存储Dot对象——Manim无法识别numpy数组中的Mobject元素,必须用VGroup统一管理所有图形元素:
from manim import * import numpy as np class OrbitalTrajectoryAnimation(Scene): def construct(self): # 替换为你的x、y numpy数组 x = np.linspace(0, 4*np.pi, 163) y = np.sin(x) plane = NumberPlane() axes = Axes().add_coordinates() # 用VGroup批量存储所有点 dots_group = VGroup() for x_val, y_val in zip(x, y): canvas_point = axes.coords_to_point(x_val, y_val) dot = Dot(canvas_point, color=GREEN, radius=0.05) dots_group.add(dot) self.add(plane, axes, dots_group)
更简洁的写法可以用列表推导式直接生成VGroup:
dots_group = VGroup(*[ Dot(axes.coords_to_point(x_val, y_val), color=GREEN, radius=0.05) for x_val, y_val in zip(x, y) ])
二、实现平滑曲线插值
plot_line_graph仅支持线性插值,要生成平滑曲线可以借助scipy的插值工具生成密集采样点,再绘制曲线:
步骤1:导入插值模块
from scipy.interpolate import interp1d
步骤2:生成平滑曲线
class OrbitalTrajectoryAnimation(Scene): def construct(self): x = np.linspace(0, 4*np.pi, 163) y = np.sin(x) plane = NumberPlane() axes = Axes().add_coordinates() # 绘制原始点 dots_group = VGroup(*[ Dot(axes.coords_to_point(x_val, y_val), color=GREEN, radius=0.05) for x_val, y_val in zip(x, y) ]) # 生成三次样条插值函数(可选quadratic、linear等) smooth_interp = interp1d(x, y, kind='cubic') # 生成1000个密集采样点,保证曲线平滑 x_smooth = np.linspace(x.min(), x.max(), 1000) y_smooth = smooth_interp(x_smooth) # 绘制平滑曲线 smooth_curve = axes.plot_line_graph( x_smooth, y_smooth, line_color=BLUE, add_vertex_dots=False # 不显示插值后的点 ) self.add(plane, axes, dots_group, smooth_curve)
如果不想依赖scipy,也可以用Manim的ParametricFunction实现:
# 基于插值函数创建参数化曲线 def smooth_param_func(t): t_scaled = t * (x_smooth.max() - x_smooth.min()) + x_smooth.min() return axes.coords_to_point(t_scaled, smooth_interp(t_scaled)) smooth_curve = ParametricFunction(smooth_param_func, t_range=[0, 1], color=BLUE)
内容的提问来源于stack exchange,提问作者asckvas
相关产品推荐
相关产品推荐

