Manim文档及源码笔记-CE文档-示例库4特殊摄像机设置

Manim文档及源码笔记-CE文档-示例库4特殊摄像机设置

参考原文:
Manim Community Edition
Example Gallery

前言

笔记随想:
暂未发现官方中文版,自己实践代码的同时,顺便做翻译加深理解~
除了给出原文档中的展现效果及源码,我把实践代码过程的笔记也分享出来,另外最后设计出一些技能训练的内容,强化学校效果。行文格式:

示例-标号及名称
展现效果
操作拆解
源码直击
代码实践
技能训练

本示例库包含一系列最佳实践代码片段及其相应的视频/图像输出,展示了整个库的不同功能。这些都是在麻省理工学院的许可下,所以请随意复制并粘贴到您的项目中。享受这Manim的味道!

更新【new】:

  • 8月23日
    • “笔记随想”前后标注了“前言”与“正文”;
    • 本系列暂告段落,把“上一节”、“下一节”升级为系列目录,放到了文尾;
  • 后续更新备忘:文中“【建设中】”的内容;欢迎朋友们催更~

正文

特殊摄像机设置,Special Camera Settings

示例1:FollowingGraphCamera

展现效果1

FollowingGraphCamera

示例1:FollowingGraphCamera

操作拆解1

上一节我们对建立坐标系越来越熟练了,本案例开始做一些比较酷的事情;
焦点/视角/镜头/参照物落在动点上;

  • 做轴和曲线,create the axes and the curve
  • 做曲线上的动点,create dots based on the graph
  • 留意调用play时参数camera的技巧
源码直击1
%%manim -v WARNING -qm FollowingGraphCamera
from manim import *

class FollowingGraphCamera(MovingCameraScene):
    def construct(self):
        self.camera.frame.save_state()

        # create the axes and the curve
        ax = Axes(x_range=[-1, 10], y_range=[-1, 10])
        graph = ax.plot(lambda x: np.sin(x), color=BLUE, x_range=[0, 3 * PI])

        # create dots based on the graph
        moving_dot = Dot(ax.i2gp(graph.t_min, graph), color=ORANGE)
        dot_1 = Dot(ax.i2gp(graph.t_min, graph))
        dot_2 = Dot(ax.i2gp(graph.t_max, graph))

        self.add(ax, graph, dot_1, dot_2, moving_dot)
        self.play(self.camera.frame.animate.scale(0.5).move_to(moving_dot))

        def update_curve(mob):
            mob.move_to(moving_dot.get_center())

        self.camera.frame.add_updater(update_curve)
        self.play(MoveAlongPath(moving_dot, graph, rate_func=linear))
        self.camera.frame.remove_updater(update_curve)

        self.play(Restore(self.camera.frame))

参考:moving_camera_sceneMovingCameraSceneMoveAlongPathRestore,plot(),add_updater()

代码实践1

代码实践1

技能训练1

单独整理到此【建设中】

示例2:MovingZoomedSceneAround

展现效果2

MovingZoomedSceneAround

示例2:MovingZoomedSceneAround

操作拆解2

放大局部但又想一揽全局?好办,做一个分镜放大框就可以了,类似放大镜效果。

  • 初始化放大框;
  • 演示图的背景是较为炫酷的黑白灰,上面有一个圆点;
源码直击2
%%manim -v WARNING -qm MovingZoomedSceneAround
from manim import *

class MovingZoomedSceneAround(ZoomedScene):
# contributed by TheoremofBeethoven, www.youtube.com/c/TheoremofBeethoven
    def __init__(self, **kwargs):
        ZoomedScene.__init__(
            self,
            zoom_factor=0.3,
            zoomed_display_height=1,
            zoomed_display_width=6,
            image_frame_stroke_width=20,
            zoomed_camera_config={
                "default_frame_stroke_width": 3,
                },
            **kwargs
        )

    def construct(self):
        dot = Dot().shift(UL * 2)
        image = ImageMobject(np.uint8([[0, 100, 30, 200],
                                       [255, 0, 5, 33]]))
        image.height = 7
        frame_text = Text("Frame", color=PURPLE, font_size=67)
        zoomed_camera_text = Text("Zoomed camera", color=RED, font_size=67)

        self.add(image, dot)
        zoomed_camera = self.zoomed_camera
        zoomed_display = self.zoomed_display
        frame = zoomed_camera.frame
        zoomed_display_frame = zoomed_display.display_frame

        frame.move_to(dot)
        frame.set_color(PURPLE)
        zoomed_display_frame.set_color(RED)
        zoomed_display.shift(DOWN)

        zd_rect = BackgroundRectangle(zoomed_display, fill_opacity=0, buff=MED_SMALL_BUFF)
        self.add_foreground_mobject(zd_rect)

        unfold_camera = UpdateFromFunc(zd_rect, lambda rect: rect.replace(zoomed_display))

        frame_text.next_to(frame, DOWN)

        self.play(Create(frame), FadeIn(frame_text, shift=UP))
        self.activate_zooming()

        self.play(self.get_zoomed_display_pop_out_animation(), unfold_camera)
        zoomed_camera_text.next_to(zoomed_display_frame, DOWN)
        self.play(FadeIn(zoomed_camera_text, shift=UP))
        # Scale in        x   y  z
        scale_factor = [0.5, 1.5, 0]
        self.play(
            frame.animate.scale(scale_factor),
            zoomed_display.animate.scale(scale_factor),
            FadeOut(zoomed_camera_text),
            FadeOut(frame_text)
        )
        self.wait()
        self.play(ScaleInPlace(zoomed_display, 2))
        self.wait()
        self.play(frame.animate.shift(2.5 * DOWN))
        self.wait()
        self.play(self.get_zoomed_display_pop_out_animation(), unfold_camera, rate_func=lambda t: smooth(1 - t))
        self.play(Uncreate(zoomed_display_frame), FadeOut(frame))
        self.wait()

参考:zoomed_sceneZoomedSceneBackgroundRectangleUpdateFromFuncadd_updater()get_zoomed_display_pop_out_animation()

代码实践2

代码实践2a
代码实践2b

技能训练2

单独整理到此【建设中】

示例3:FixedInFrameMObjectTest

展现效果3

示例3:FixedInFrameMObjectTest

操作拆解3

之前都是2D范畴,下面进入3D模式~

  • 也很简单,直接调用3D轴的方法;
  • 不过前面刚提到镜头,在3D中要考虑观察者视角;
源码直击3
%%manim -v WARNING -qm FixedInFrameMObjectTest
from manim import *

class FixedInFrameMObjectTest(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
        text3d = Text("This is a 3D text")
        self.add_fixed_in_frame_mobjects(text3d)
        text3d.to_corner(UL)
        self.add(axes)
        self.wait()

参考:ThreeDSceneset_camera_orientation()add_fixed_in_frame_mobjects()

代码实践3

代码实践3

技能训练3

单独整理到此【建设中】

示例4:ThreeDLightSourcePosition

展现效果4

示例4:ThreeDLightSourcePosition

操作拆解4

在让3D动起来之间,先做一个3D球;
3D调动同样简单,只是维度增加、参数也多了一些;

源码直击4
%%manim -v WARNING -qm ThreeDLightSourcePosition
from manim import *

class ThreeDLightSourcePosition(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        sphere = Surface(
            lambda u, v: np.array([
                1.5 * np.cos(u) * np.cos(v),
                1.5 * np.cos(u) * np.sin(v),
                1.5 * np.sin(u)
            ]), v_range=[0, TAU], u_range=[-PI / 2, PI / 2],
            checkerboard_colors=[RED_D, RED_E], resolution=(15, 32)
        )
        self.renderer.camera.light_source.move_to(3*IN) # changes the source of the light
        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
        self.add(axes, sphere)

参考:ThreeDSceneThreeDAxesSurfaceset_camera_orientation()

代码实践4

代码实践4

技能训练4

单独整理到此【建设中】

示例5:ThreeDCameraRotation

展现效果5

ThreeDCameraRotation

示例5:ThreeDCameraRotation

操作拆解5

这次让水平面沿水平面旋转(“摇摆”)。

源码直击5
%%manim -v WARNING -qm ThreeDCameraRotation
from manim import *

class ThreeDCameraRotation(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        circle=Circle()
        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
        self.add(circle,axes)
        self.begin_ambient_camera_rotation(rate=0.1)
        self.wait()
        self.stop_ambient_camera_rotation()
        self.move_camera(phi=75 * DEGREES, theta=30 * DEGREES)
        self.wait()

参考:ThreeDSceneThreeDAxesbegin_ambient_camera_rotation()stop_ambient_camera_rotation()

代码实践5

代码实践5

技能训练5

单独整理到此【建设中】

示例6:ThreeDCameraIllusionRotation

展现效果6

ThreeDCameraIllusionRotation

示例6:ThreeDCameraIllusionRotation

操作拆解6

这次更进一步,让水平面在3D空间更为自由地“摇摆”。

源码直击6
%%manim -v WARNING -qm ThreeDCameraIllusionRotation
from manim import *

class ThreeDCameraIllusionRotation(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        circle=Circle()
        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
        self.add(circle,axes)
        self.begin_3dillusion_camera_rotation(rate=2)
        self.wait(PI/2)
        self.stop_3dillusion_camera_rotation()

参考:ThreeDSceneThreeDAxesbegin_3dillusion_camera_rotation()stop_3dillusion_camera_rotation()

代码实践6

代码实践6

技能训练6

单独整理到此【建设中】

示例7:ThreeDSurfacePlot

展现效果7

示例7:ThreeDSurfacePlot

操作拆解7

构建3D基本曲面;

源码直击7
%%manim -v WARNING -qm ThreeDSurfacePlot
from manim import *

class ThreeDSurfacePlot(ThreeDScene):
    def construct(self):
        resolution_fa = 24
        self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)

        def param_gauss(u, v):
            x = u
            y = v
            sigma, mu = 0.4, [0.0, 0.0]
            d = np.linalg.norm(np.array([x - mu[0], y - mu[1]]))
            z = np.exp(-(d ** 2 / (2.0 * sigma ** 2)))
            return np.array([x, y, z])

        gauss_plane = Surface(
            param_gauss,
            resolution=(resolution_fa, resolution_fa),
            v_range=[-2, +2],
            u_range=[-2, +2]
        )

        gauss_plane.scale(2, about_point=ORIGIN)
        gauss_plane.set_style(fill_opacity=1,stroke_color=GREEN)
        gauss_plane.set_fill_by_checkerboard(ORANGE, BLUE, opacity=0.5)
        axes = ThreeDAxes()
        self.add(axes,gauss_plane)

参考:ThreeDSceneSurface

代码实践7

代码实践7

技能训练7

单独整理到此【建设中】

本系列目录【new】

Manim文档及源码笔记-CE文档-示例库1基本概念
Manim文档及源码笔记-CE文档-示例库2动画
Manim文档及源码笔记-CE文档-示例库3使用Manim绘图
Manim文档及源码笔记-CE文档-示例库4特殊摄像机设置【本文】
Manim文档及源码笔记-CE文档-示例库5进阶项目

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值