如何在Manim中实现类似Desmos的函数可视化效果(以自定义心形函数为例)
如何在Manim中实现类似Desmos的函数可视化效果(以自定义心形函数为例)
你好呀!我看了你用Manim绘制自定义心形函数的尝试,对比Desmos的效果,你的Manim结果出现了y轴拉伸、曲线形状偏离的问题,这主要是两个原因导致的:函数计算的小错误和坐标轴比例没有匹配Desmos的视觉设定,咱们来一步步修正~
先说说问题出在哪儿
- 函数公式写错了:你在代码里的
heart_curve函数中,直接用了value = 3.5-x**2然后乘0.9,但原函数里是0.9*sqrt(3.5-x²)*sin(...)——你漏了对3.5-x²开平方!这直接导致曲线的波动幅度被放大了N倍,形状完全偏离。 - 坐标轴比例不匹配:Manim的
Axes默认会根据窗口自适应缩放,你的x_range设得太大([-10,10]),而函数实际的x范围只有[-√3.5, √3.5]≈[-1.87,1.87],这就导致x轴被过度压缩,y轴相对拉伸,视觉上比例失调。
修正后的完整代码
我把这两个问题都修复了,还调整了一些参数让效果更贴近Desmos:
from manim import * import numpy as np class HeartAnimation(Scene): def construct(self): # 调整坐标轴参数,保证x/y轴视觉比例一致,范围贴合函数 axes = Axes( x_range=[-2, 2, 0.5], # 覆盖函数的x范围(≈[-1.87,1.87]),步长0.5更清晰 y_range=[-1, 4, 0.5], # 函数y值范围大概在0-3之间,预留一点空间 axis_config={"color": BLUE, "tip_length": 0.02}, # 缩小轴箭头更贴合Desmos风格 x_length=8, # 设置x轴显示长度 y_length=8, # y轴和x轴长度相同,保证单位长度视觉一致 scaling=LinearBaseFunction(stretch_factor=1), # 强制线性缩放,避免自适应变形 ) def heart_curve(x): sqrt_term = np.sqrt(3.5 - x**2) # 补上漏掉的平方根! # x^(2/3)用np.cbrt(x**2)是正确的,和pow(x, 2/3)效果一致 return np.cbrt(x**2) + 0.9 * sqrt_term * np.sin(np.pi * x * 15) graph = axes.plot( heart_curve, color=RED, x_range=[-np.sqrt(3.5), np.sqrt(3.5)], use_smoothing=False, sample_points=2000 # 增加采样点,让曲线细节更细腻 ) self.play(Create(axes)) self.play(Create(graph, run_time=3)) # 延长绘制动画时间,更流畅 self.wait(3)
调整的关键细节
- 函数修正:补上
np.sqrt(3.5 - x**2)这一步,让曲线的波动幅度回到原函数的设定,这是形状匹配的核心。 - 坐标轴比例:把
x_length和y_length设为相同值,保证x和y轴的单位长度在视觉上一致,解决y轴拉伸的问题;同时缩小x/y的范围,让心形曲线占据画布的主要区域,和Desmos的显示逻辑一致。 - 细节优化:增加
sample_points让曲线的波动细节更清晰,缩小轴箭头的长度更贴近Desmos的简洁风格,延长动画绘制时间让过程更流畅。
这样调整后,你得到的Manim动画就会和Desmos里的效果非常接近啦~
备注:内容来源于stack exchange,提问作者just_a_kid_coder_123




