云计算百科
云计算领域专业知识百科平台

莫比乌斯带的数学原理和视觉特性

import numpy as np
from manim import *
import manim.utils.rate_functions as rate_funcs

# 定义黑板的黑绿色
BLACKBOARD_GREEN = "#1E352F"

class MobiusRaceScene04(ThreeDScene):

def construct(self):
# 1. 设置黑板背景色和初始相机视角
self.camera.background_color = BLACKBOARD_GREEN
self.set_camera_orientation(
phi=70 * DEGREES, theta=-35 * DEGREES, zoom=0.85
)

# —————- 2D 文本与公式 (固定在屏幕上) —————-

# 标题 (顶部中央) – 使用 Text 以完美支持中文
title = Text(
"莫比乌斯带的数学方程与坐标变换",
font="Sans",
color=YELLOW,
).scale(0.7)
title.to_edge(UP, buff=0.4)

# 角落 (1): 莫比乌斯带的参数方程 (左上角)
label1 = Text("(1)莫比乌斯带参数方程:", font="Sans", color=WHITE).scale(0.35)
eq1 = MathTex(
r"x = \\left( R + v \\cos\\frac{u}{2} \\right) \\cos u\\\\",
r"y = \\left( R + v \\cos\\frac{u}{2} \\right) \\sin u\\\\",
r"z = v \\sin\\frac{u}{2}",
color=WHITE,
).scale(0.55)
group1 = VGroup(label1, eq1).arrange(DOWN, aligned_edge=LEFT, buff=0.1)
group1.to_corner(UL).shift(DOWN * 0.8)

# 角落 (2): 极坐标与直角坐标的转换 (右上角)
label2 = Text("(2)极坐标与直角坐标转换:", font="Sans", color=LIGHT_GRAY).scale(0.35)
eq2 = MathTex(
r"r = R + v \\cos\\frac{u}{2}\\\\",
r"x = r \\cos u\\\\",
r"y = r \\sin u",
color=LIGHT_GRAY,
).scale(0.55)
group2 = VGroup(label2, eq2).arrange(DOWN, aligned_edge=LEFT, buff=0.1)
group2.to_corner(UR).shift(DOWN * 0.8)

# 角落 (3): 给定数字的具体计算 (左下角)
label3 = Text("(3)实例数值计算:", font="Sans", color=ORANGE).scale(0.35)
eq3 = MathTex(
r"\\text{if} R = 2.5, u = \\pi, v = 0.5\\\\",
r"r = 2.5 + 0.5 \\cos(\\frac{\\pi}{2}) = 2.5\\\\",
r"x = 2.5 \\cos(\\pi) = -2.5\\\\",
r"y = 2.5 \\sin(\\pi) = 0\\\\",
r"z = 0.5 \\sin(\\frac{\\pi}{2}) = 0.5",
color=ORANGE,
).scale(0.55)
group3 = VGroup(label3, eq3).arrange(DOWN, aligned_edge=LEFT, buff=0.1)
group3.to_corner(DL).shift(UP * 0.3)

# 使用 add_fixed_in_frame_mobjects 确保 2D 元素不随 3D 相机旋转
self.add_fixed_in_frame_mobjects(title, group1, group2, group3)

# —————- 3D 几何体与动画 —————-

# 创建渐变色三维坐标轴
axes = ThreeDAxes(
x_range=[-4, 4, 1],
y_range=[-4, 4, 1],
z_range=[-3, 3, 1],
x_length=7,
y_length=7,
z_length=5,
).shift(
DOWN * 0.3
) # 稍微向下移动以避免重叠公式
for axis in [axes.x_axis, axes.y_axis, axes.z_axis]:
axis.set_color(color=[RED, WHITE, RED])

# 参数化莫比乌斯带函数
R = 2.5

def mobius_func(u, v):
x = (R + v * np.cos(u / 2)) * np.cos(u)
y = (R + v * np.cos(u / 2)) * np.sin(u)
z = v * np.sin(u / 2)
# 同样应用平移以和坐标轴对齐
return np.array([x, y, z]) + DOWN * 0.3

# 创建七条不透明的平行色带
colors = [RED, ORANGE, YELLOW, GREEN, TEAL, BLUE, PURPLE]
num_strips = 7
total_width = 1.0
strip_width = total_width / num_strips

strips = VGroup()
for i, color in enumerate(colors):
v_min = -total_width / 2 + i * strip_width
v_max = v_min + strip_width

strip = Surface(
lambda u, v, v_min=v_min, v_max=v_max: mobius_func(u, v),
u_range=[0, 2 * np.pi],
v_range=[v_min, v_max],
resolution=(60, 2),
)
strip.set_fill(color=color, opacity=1.0)
strip.set_stroke(width=0)
strips.add(strip)

# 定义 3 个“蚂蚁” (适配 v0.19.0)
ant_sphere = Sphere(radius=0.15).set_color(RED)
ant_cube = Cube(side_length=0.25).set_color(GREEN)
ant_tetra = Tetrahedron(
edge_length=0.3,
faces_config={"fill_color": BLUE, "fill_opacity": 1.0},
)
ant_tetra.graph.set_color(BLUE)

ants = [ant_sphere, ant_cube, ant_tetra]

def get_ant_position(alpha, index):
base_u = alpha * 4 * np.pi
offset = index * (4 * np.pi / 3)
u = (base_u + offset) % (4 * np.pi)
return mobius_func(u, 0)

# —————- 动画播放 —————-

# 1. 渐显标题和公式组
self.play(
Write(title),
FadeIn(group1, shift=RIGHT),
FadeIn(group2, shift=LEFT),
FadeIn(group3, shift=UP),
run_time=2,
)
self.wait(0.5)

# 2. 绘制坐标轴
self.play(Create(axes), run_time=2)
self.wait(0.5)

# 3. 色带赛跑
rate_functions = [
rate_funcs.smooth,
rate_funcs.ease_in_quad,
rate_funcs.ease_out_quad,
rate_funcs.linear,
rate_funcs.ease_in_out_cubic,
rate_funcs.ease_in_sine,
rate_funcs.ease_out_sine,
]

strip_animations = []
for i, strip in enumerate(strips):
strip_animations.append(
Create(
strip,
rate_func=rate_functions[i],
run_time=6,
)
)

self.play(*strip_animations)
self.wait(0.5)

# 4. 相机与场景旋转 (此时屏幕角落的公式保持不动)
self.begin_ambient_camera_rotation(rate=0.4)
self.play(
Rotate(axes, angle=2 * np.pi, axis=OUT),
Rotate(strips, angle=2 * np.pi, axis=OUT),
run_time=4,
rate_func=rate_funcs.linear,
)
self.stop_ambient_camera_rotation()
self.wait(0.5)

# 5. 蚂蚁爬行
for i, ant in enumerate(ants):
ant.move_to(get_ant_position(0, i))
self.play(*[FadeIn(ant) for ant in ants])

def update_ant(ant, alpha, index):
ant.move_to(get_ant_position(alpha, index))
ant.rotate(
0.15, axis=np.array([1, 1, 1]), about_point=ant.get_center()
)

self.play(
UpdateFromAlphaFunc(
ant_sphere,
lambda m, a: update_ant(m, a, 0),
),
UpdateFromAlphaFunc(
ant_cube,
lambda m, a: update_ant(m, a, 1),
),
UpdateFromAlphaFunc(
ant_tetra,
lambda m, a: update_ant(m, a, 2),
),
run_time=10,
rate_func=rate_funcs.linear,
)

self.wait(2)

这段代码使用Manim库创建了一个3D动画,展示了莫比乌斯带的数学原理和视觉特性。让我详细解释代码的各个部分:

主要功能概述

这是一个关于莫比乌斯带(Mobius strip)的3D数学演示动画,包含:

  • 数学公式展示
  • 3D几何体构建
  • 多元素动画同步
  • 相机运动控制
  • 代码结构详解

    1. 场景设置

    self.camera.background_color = BLACKBOARD_GREEN
    self.set_camera_orientation(phi=70 * DEGREES, theta=-35 * DEGREES, zoom=0.85)

    • 设置黑绿色背景(黑板风格)
    • 调整3D相机初始角度和缩放

    2. 2D文本与公式(固定在屏幕)

    使用add_fixed_in_frame_mobjects在3D场景中固定2D元素:

    • 左上:莫比乌斯带参数方程
    • 右上:极坐标与直角坐标转换
    • 左下:具体数值计算示例
    • 顶部:标题

    即使3D场景旋转,这些2D元素始终面向摄像机。

    3. 莫比乌斯带的3D构建

    def mobius_func(u, v):
    x = (R + v * np.cos(u / 2)) * np.cos(u)
    y = (R + v * np.cos(u / 2)) * np.sin(u)
    z = v * np.sin(u / 2)

    这是莫比乌斯带的标准参数方程,其中:

    • u:绕环角度(0到2π)
    • v:带宽度方向(-0.5到0.5)
    • 通过v * cos(u/2)和v * sin(u/2)实现半扭转

    4. 七色带构建

    将莫比乌斯带分割成7个不同颜色的平行条带,每个条带使用不同的动画速率函数。

    5. 动画顺序

  • 标题和公式渐显(2秒)
  • 绘制坐标轴(2秒)
  • 条带动画(6秒)- 使用不同速率函数
  • 场景旋转(4秒):相机自动旋转+场景整体旋转
  • 蚂蚁动画(10秒):3只"蚂蚁"在带上行走
  • 6. 蚂蚁动画

    • 红球(Sphere)
    • 绿方块(Cube)
    • 蓝四面体(Tetrahedron)

    通过UpdateFromAlphaFunc更新位置,使用固定偏移实现等间距分布。

    关键技术点

    不同速率函数

    rate_functions = [
    rate_funcs.smooth, # 平滑
    rate_funcs.ease_in_quad, # 二次缓入
    rate_funcs.ease_out_quad, # 二次缓出
    rate_funcs.linear, # 线性
    rate_funcs.ease_in_out_cubic, # 三次缓入缓出
    rate_funcs.ease_in_sine, # 正弦缓入
    rate_funcs.ease_out_sine, # 正弦缓出
    ]

    每个条带使用不同速度曲线,展示相同几何体在不同运动学下的效果。

    3D到2D的转换

    • 使用add_fixed_in_frame_mobjects固定屏幕元素
    • 3D元素正常参与空间变换
    • 相机角度变化不影响固定的2D元素

    参数方程的应用

    • 代码同时展示了数学理论和3D实现
    • 所有3D几何体由参数方程生成
    • 通过改变参数产生动画效果
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 莫比乌斯带的数学原理和视觉特性
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!