如何在Manim中绘制直线?现有方案存在动画过快问题
Manim绘制无限直线的最优方案
一、专用类:直接使用InfiniteLine
Manim自带专门绘制无限延伸直线的InfiniteLine类,完全不用自己扩展线段,它默认会自动延伸到屏幕边界,用法和普通Line基本一致:
from manim import InfiniteLine, Scene, DEGREES class TestLineScene(Scene): def construct(self): # 过原点、45度方向的无限直线 infinite_line = InfiniteLine(angle=45 * DEGREES, color=BLUE) self.play(Create(infinite_line)) self.wait()
你可以通过point参数指定直线经过的点,direction参数控制直线方向,也能设置stroke_width、dashed等样式属性,完全满足无限直线的绘制需求。
二、解决自定义扩展线段的动画速度问题
如果因为特定场景必须用你自己的expand_line方法,想要减慢Create动画的速度,直接给Create添加run_time参数即可:
from manim import Line, Scene, LEFT, RIGHT def expand_line(line: Line, ratio=100) -> None: ends = line.get_start_and_end() delta = ends[1] - ends[0] line.put_start_and_end_on(ends[0] - ratio * delta, ends[1] + ratio * delta) class TestExpandLineScene(Scene): def construct(self): line = Line(start=LEFT, end=RIGHT) expand_line(line) # 设置动画时长为3秒(默认是1秒),减慢绘制速度 self.play(Create(line, run_time=3)) self.wait()
三、精准贴合屏幕的线段绘制技巧
如果不想用InfiniteLine,又不想过度扩展线段,可以利用Manim内置的FRAME_X_RADIUS和FRAME_Y_RADIUS常量,计算直线与屏幕边界的交点,让线段刚好贴合屏幕:
from manim import Line, Scene, FRAME_X_RADIUS, FRAME_Y_RADIUS, ORIGIN def get_screen_fit_line(point, direction): dx, dy = direction[:2] intersections = [] # 计算与左右边界的交点 if dx != 0: t_left = (-FRAME_X_RADIUS - point[0]) / dx y_left = point[1] + dy * t_left if -FRAME_Y_RADIUS <= y_left <= FRAME_Y_RADIUS: intersections.append([-FRAME_X_RADIUS, y_left, 0]) t_right = (FRAME_X_RADIUS - point[0]) / dx y_right = point[1] + dy * t_right if -FRAME_Y_RADIUS <= y_right <= FRAME_Y_RADIUS: intersections.append([FRAME_X_RADIUS, y_right, 0]) # 计算与上下边界的交点 if dy != 0: t_up = (FRAME_Y_RADIUS - point[1]) / dy x_up = point[0] + dx * t_up if -FRAME_X_RADIUS <= x_up <= FRAME_X_RADIUS: intersections.append([x_up, FRAME_Y_RADIUS, 0]) t_down = (-FRAME_Y_RADIUS - point[1]) / dy x_down = point[0] + dx * t_down if -FRAME_X_RADIUS <= x_down <= FRAME_X_RADIUS: intersections.append([x_down, -FRAME_Y_RADIUS, 0]) return Line(start=intersections[0], end=intersections[1]) class TestFitLineScene(Scene): def construct(self): # 过原点、右上方向的贴合屏幕线段 fit_line = get_screen_fit_line(point=ORIGIN, direction=[1,1]) self.play(Create(fit_line)) self.wait()
内容的提问来源于stack exchange,提问作者Dinshey
相关产品推荐
相关产品推荐

