流线是一条线,它是 与瞬时速度方向相切(速度是一个矢量,并且 它有一个大小和一个方向)。为了在流程中可视化这一点,我们 可以想象一个小的标记流体元素的运动。例如,我们可以标记一个 用荧光染料滴水,然后用激光照射它,这样 它会发出荧光。如果我们在液滴移动时拍摄一张短曝光照片 根据局部速度场(与 速度发生明显变化所需的时间),我们会看到一个短的条纹,带有 长度 V\Delta t,且方向与瞬时速度方向相切。如果我们 以这种方式标记许多水滴,其中的流线 流量将变得可见。由于流动中任何一点的速度都有一个值 (流动不能同时流向多个方向),流线不能 渡。除了在速度 量级为零,例如在停留带。
还有其他方法可以使流可见。例如,我们可以追踪出路径 然后是我们的荧光滴剂,使用长时间曝光的照片。这条线被称为路径线,它类似于您在拍摄长时间曝光照片时看到的 夜间高速公路上的车灯。路径线有可能交叉,就像你可以的那样 想象一下高速公路的类比:当一辆汽车改变车道时,它的路径线由它划出 灯光可能会穿过相邻车辆在另一处追踪出的另一条路径线 时间。
可视化流动模式的另一种方法是通过条纹线。条纹线是 由在某个较早的某个点通过特定点的所有粒子所追踪的线 时间。例如,如果我们从一个固定点连续发射荧光染料,则染料 当它顺流而下时构成一条条纹线。为了继续高速公路的类比,它是 线路由经过同一收费站的所有车辆上的信号灯组成。 如果它们都遵循相同的路径(稳定的流动),则会产生一条线,但如果它们遵循 不同的路径(不稳定流动),线路可能会自行交叉。
在 非定常流、流线、路径线和条纹线都是不同的,但在稳态流中,流线、流线、路径线 和条纹线是相同的。
一,manim中流线的创建。
1.流线函数
StreamLines(func, color=None, color_scheme=None, min_color_scheme_value=0,
max_color_scheme_value=2, colors=[ManimColor('#236B8E'), ManimColor('#83C167'),
ManimColor('#FFFF00'), ManimColor('#FC6255')], x_range=None, y_range=None,
z_range=None, three_dimensions=False, noise_factor=None, n_repeats=1, dt=0.05,
virtual_time=3, max_anchors_per_line=100, padding=3, stroke_width=1,
opacity=1, **kwargs)
参数解释
-
func:
- 说明: 定义的向量场函数,应该接受并返回坐标。这是流线的核心,控制流线的形状和运动。
- 示例:
def func(x, y): return np.array([-y, x, 0]) # 旋转流线的向量场
-
color:
- 说明: 流线的基本颜色。如果未指定,则可能使用颜色列表中的颜色或默认颜色。
- 示例:
color=WHITE # 设置流线的颜色为白色
-
color_scheme:
- 说明: 定义流线颜色的方案,通常基于向量场的值。常用的方案包括“viridis”,“plasma”等。
- 示例:
color_scheme='viridis' # 使用预定义的颜色方案
-
min_color_scheme_value:
- 说明: 颜色方案的最小值,控制颜色映射的起点。
- 示例:
min_color_scheme_value=0 # 最小的颜色值
-
max_color_scheme_value:
- 说明: 颜色方案的最大值,控制颜色映射的终点。
- 示例:
max_color_scheme_value=2 # 最大的颜色值
-
colors:
- 说明: 用于流线的颜色列表,允许用户定义具体使用的颜色。
- 示例:
colors=[ManimColor('#236B8E'), ManimColor('#83C167'), ManimColor('#FFFF00'), ManimColor('#FC6255')]
-
x_range:
- 说明: 流线绘制的 x 轴范围,用于限制绘制区域。
- 示例:
x_range=[-3, 3] # x 轴范围从 -3 到 3
-
y_range:
- 说明: 流线绘制的 y 轴范围。
- 示例:
y_range=[-3, 3] # y 轴范围从 -3 到 3
-
z_range:
- 说明: 当
three_dimensions=True
时,限制 z 轴的范围。 - 示例:
z_range=[-1, 1] # z 轴范围从 -1 到 1
- 说明: 当
-
three_dimensions:
- 说明: 布尔值,指示流线是否在三维空间中绘制。
- 示例:
three_dimensions=True # 在三维空间中绘制流线
-
noise_factor:
- 说明: 引入随机性以模拟更自然的流动模式。可以帮助增强真实感。
- 示例:
noise_factor=0.1 # 添加少量噪声
-
n_repeats:
- 说明: 指定起始点的重复次数,影响流线的密集程度。
- 示例:
n_repeats=5 # 重复起始点5次
-
dt:
- 说明: 模拟的时间步长,较小的值意味着更多的模拟步骤和较平滑的结果。
- 示例:
dt=0.05 # 设置时间步长为0.05
-
virtual_time:
- 说明: 指定模拟应该运行的虚拟时间单位,控制动画的持续时间。
- 示例:
virtual_time=3 # 设置虚拟时间为3单位
-
max_anchors_per_line:
- 说明: 设置构成单条流线的最大锚点数量,影响流线的复杂程度。
- 示例:
max_anchors_per_line=100 # 每条流线最多100个锚点
-
padding:
- 说明: 向量场周围的间距,有助于可视化以防止流线过于靠近边缘。
- 示例:
padding=3 # 设置3个单位的间距
-
stroke_width:
- 说明: 控制流线的宽度,允许用户自定义外观。
- 示例:
stroke_width=2 # 流线的宽度为2个单位
-
opacity:
- 说明: 控制流线的透明度,通过调节来实现层叠效果。
- 示例:
opacity=0.8 # 设置透明度为80%
-
kwargs:
- 说明: 允许传递附加参数,这些参数可能是特定于某个实现的或提供额外的自定义选项。
- 示例:
additional_param='some_value' # 任意附加参数
示例代码
以下是使用 StreamLines
的代码示例,包含所有参数:
from manim import *
class StreamLinesExample(Scene):
def construct(self):
# 定义向量场函数
# pos 是一个包含 x 和 y 的位置向量
# 这个函数会计算出一个二次元矢量,用于指定在该位置的流线方向和强度
# np.sin(pos[0]) * UR: 基于 x 坐标生成一个朝向右上方的分量
# np.cos(pos[1]) * LEFT: 基于 y 坐标生成一个朝向左的分量
# pos / 5: 将位置归一化,使得位置对流动的影响比较小
func = lambda pos: np.sin(pos[0]) * UR + np.cos(pos[1]) * LEFT + pos / 5
# 创建流线对象
streamlines = StreamLines(
func, # 向量场函数
color=RED, # 流线的颜色
color_scheme='viridis', # 颜色方案用来色彩的过渡
min_color_scheme_value=0, # 颜色方案的最小值
max_color_scheme_value=2, # 颜色方案的最大值
colors="#ece6e2", # 流线的基础颜色
x_range=[-3, 3], # x轴范围
y_range=[-3, 3], # y轴范围
z_range=[-1, 1], # z轴范围(在三维情况下)
three_dimensions=True, # 是否使用三维
noise_factor=0.1, # 噪声因子,影响流线的随机性
n_repeats=5, # 每个点生成的流线数
dt=0.05, # 时间步长,用于模拟流动
virtual_time=3, # 虚拟时间,用来控制流线的显示时长
max_anchors_per_line=100, # 每条流线的最大锚点数量
padding=3, # 流线的填充
stroke_width=2, # 流线的宽度
opacity=0.8 # 流线的不透明度
)
# 将流线添加到场景中
self.add(streamlines)
# 使用 Create 动画来呈现流线效果
self.play(Create(streamlines), run_time=3)
示例2:
class BasicUsage(Scene):
def construct(self):
func = lambda pos: ((pos[0] * UR + pos[1] * LEFT) - pos) / 3
a=(StreamLines(func))
self.play(a.create())
示例3:
from manim import *
class SpawningAndFlowingArea(Scene):
def construct(self):
func = lambda pos: np.sin(pos[0]) * UR + np.cos(pos[1]) * LEFT + pos / 5
stream_lines = StreamLines(
func, x_range=[-3, 3, 0.2], y_range=[-2, 2, 0.2], padding=1
)
spawning_area = Rectangle(width=6, height=4)
flowing_area = Rectangle(width=8, height=6)
labels = [Tex("Spawning Area"), Tex("Flowing Area").shift(DOWN * 2.5)]
for lbl in labels:
lbl.add_background_rectangle(opacity=0.6, buff=0.05)
self.add(stream_lines, spawning_area, flowing_area, *labels)
二, 函数方法:
1.crrate函数
create(lag_ratio=None, run_time=None, **kwargs)
该函数用于创建动画,使得对象在场景中展示出来。
参数说明:
lag_ratio
: 控制动画执行的延迟程度。值在[0, 1]
之间。较大的值会使得效果看起来更有延迟感,例如可以给每个对象增加一个延迟效果。- 示例:
lag_ratio=0.5
设置对象动画的延迟为 50%。
- 示例:
run_time
: 动画运行的时间(以秒为单位)。可以用来控制动画的速度。- 示例:
run_time=2
设置动画运行时间为 2 秒。
- 示例:
**kwargs
: 其他关键字参数,通常用于设置动画的具体行为或效果。例如,可以调用其他动画的额外参数,如stroke_color
来改变线条颜色。
示例:
self.play(Create(circle, lag_ratio=0.1, run_time=2))
这个示例创建一个圆的动画,在 2 秒内完成,并且对象间有 0.1 的延迟效果。
2.end_animation函数
end_animation()
end_animation
是在动画中用于结束或停止动画的方法。具体的使用和效果可能因具体的动画库或框架而异。不过,通常情况下,这个方法会用来清理动画状态、结束当前动画的运行,并可能退回到初始状态或切换到某个结束状态。
以下是一般性说明:
功能:
- 结束当前动画的执行。
- 清理与动画相关的资源或状态。
- 可能用于将场景中对象恢复到原始状态。
使用场景:
- 在执行完一系列动画后,可以调用该方法来确保所有动画都妥善结束。
- 用于在某些条件下强制停止正在运行的动画。
示例:
self.animate_object() # 开始动画 # 一些操作
self.end_animation() # 结束动画
注意事项:
- 确保在合适的时间调用
end_animation()
以避免状态不一致,比如在动画完成后或在出现错误需要强制停止时。 - 不同的动画库可能有不同的实现,确保查看相关文档以了解其确切用途。
3. start_animation函数
start_animation(warm_up=True, flow_speed=1, time_width=0.3, rate_func=<function linear>,
line_animation_class=<class 'manim.animation.indication.ShowPassingFlash'>, **kwargs)
该函数用于启动流动动画。
参数说明:
-
warm_up
: 一个布尔值,控制是否在动画开始前进行预热。预热可以使得动画初期更平滑。- 示例:
warm_up=True
会在开始动画之前预热。
- 示例:
-
flow_speed
: 表示流动动画的速度。值越大,流动越快。通常使用一个比例值。- 示例:
flow_speed=2
表示流动的速度是正常速度的两倍。
- 示例:
-
time_width
: 控制动画在时间维度上的宽度,影响流动的持续时间。值越大,流动的时间宽度越长。- 示例:
time_width=0.5
表示动画在时间维度上更宽。
- 示例:
-
rate_func
: 一个函数,用于控制动画随着时间变化的方式。可以使用内置的函数如linear
,smooth
, 或者自定义的 easing 函数。- 示例:
rate_func=there_and_back
表示动画会先前进然后再退回。
- 示例:
-
line_animation_class
: 指定用来进行线条动画的类。默认是ShowPassingFlash
,可以替换成其他的动画类来改变效果。- 示例:
line_animation_class=ShowIncreasingSubsets
使用不同的动画类来展示。
- 示例:
-
**kwargs
: 其他参数,通常用来传递特定控制动画的额外选项,具体取决于line_animation_class。
示例:
self.start_animation(warm_up=True, flow_speed=1.5,
time_width=0.5, rate_func=smooth)
这个示例准备启动流动动画,使用 1.5 的流动速度,时间宽度为 0.5。动画的变化速率采用平滑效果。
应用实例 1:
class StreamLineCreation(Scene):
def construct(self):
func = lambda pos: (np.sin(pos[0]) * UR + np.cos(pos[1]) * LEFT) - pos
stream_lines = StreamLines(
func,
color=YELLOW,
x_range=[-7, 7, 1],
y_range=[-4, 4, 1],
stroke_width=3,
virtual_time=1, # use shorter lines
max_anchors_per_line=5, # better performance with fewer anchors
)
self.play(stream_lines.create()) # uses virtual_time as run_time
self.wait()
应用实例 2:
from manim import *
class EndAnimation(Scene):
def construct(self):
func = lambda pos: np.sin(pos[0] / 2) * UR + np.cos(pos[1] / 2) * LEFT
stream_lines = StreamLines(
func, stroke_width=3, max_anchors_per_line=5, virtual_time=1, color=BLUE
)
self.add(stream_lines)
stream_lines.start_animation(warm_up=False, flow_speed=1.5, time_width=0.5)
self.wait(1)
self.play(stream_lines.end_animation())
应用实例 3:
from manim import *
class ContinuousMotion(Scene):
def construct(self):
func = lambda pos: np.sin(pos[0] / 2) * UR + np.cos(pos[1] / 2) * LEFT
stream_lines = StreamLines(func, stroke_width=3, max_anchors_per_line=30)
self.add(stream_lines)
stream_lines.start_animation(warm_up=False, flow_speed=1.5)
self.wait(stream_lines.virtual_time / stream_lines.flow_speed)
总结:
这些参数允许有效地控制动画的性质,包括持续时间、流动速度、延迟情况、以及整体动画表现的风格和流动特性。通过调整这些参数,您能够创建出更丰富、更动感的动画效果。如果您还有其他疑问或需要进一步的说明,请告诉我!