当前位置: 首页 > 工具软件 > Manim > 使用案例 >

manim的一些进阶方法

咸疏珂
2023-12-01

manim的一些进阶方法

1.DashedVMobject

将对象的线段变成虚线

DashedVMobject(Circle(radius=3,color=GRAY))
DashedVMobject(Line(LEFT*5,RIGHT*5,color=GRAY))

2.FadeToColor

改变物体的颜色

mob = Circle()
FadeToColor(mob,TEAL)

3.Group

封装之前的VMobjects对象,然后进行整体移动

picture = Group(*self.mobjects).scale(0.6)
self.play(
    ApplyMethod(
    picture.to_edge,LEFT,buff=SMALL_BUFF
    ),run_time=3
)

4.save_state and restore()

在这个时刻将对象保存起来 (声明)

square2.save_state()
def update_rotate_move(mob,alpha):
    square2.restore()
    square2.shift(RIGHT*10*alpha)
    square2.rotate(3*PI*alpha)

5.surround

圆围绕着方形

circle.surround(square)

6.Arc

画弧 标注角度使用最多

paramaters:

radius:弧长

arc_center:弧的圆心(继承circle)

start_angle:起始角度

angle:要旋转的角度

arc = Arc(radius=0.3,arc_center=np.array([-1, 0, 0]),start_angle=0, angle=31.5 * DEGREES)
        

7.rotate

第一个参数:旋转的角度

abount_point:围绕哪个点去旋转 默认时圆点

 line = DashedLine(np.array([2,0,0]),np.array([5.5,0,0])).rotate(67.5*DEGREES, about_point=np.array([2, 0, 0]))  

8.Rotating

也是旋转,这个旋转在使用起来比较流畅

radians:要旋转的角度

self.play(Rotating(rect,axis=IN,radians=PI))

9.Rotating和rotate的区别

Rotating:每一帧都会创建一个target

rotate:只生成一个target,中间直接补间动画

self.play(
    Rotating(sq1,about_point=ORIGIN,radians=TAU/3),
    sq2.rotate,{'about_point':ORIGIN,'angle':TAU/3},
    run_time=3
)

10.get_boundary_point

获取对象在某个方向的坐标,返回[]

rotateDot = line01.get_boundary_point(DOWN) #返回最下面的点

11.MoveToTarget

移动目标

a = TextMobject('text')
#先复制自己成为A的target属性
a.generate_target()
#操作a的target将a变成矩形
a.target.become(Square(side_length=2,color=BLUE).shift(RIGHT*2))
self.add(a)
self.wait()
self.play(MoveToTarget(a))

12.add_updater 、remove_updater、clear_updaters

目的:让一个对象跟随另一个对象的运动而运动,就是将一个对象的值绑定到另一个对象身上

dot = Dot()
text = TextMobject('this is some text').next_to(dot,RIGHT)
self.add(dot,text)
#group01 = VGroup(text,dot)
text.add_updater(lambda a:a.next_to(dot,RIGHT))
self.play(dot.shift,UP*3)
self.play(dot.shift,DOWN*3)
#移除原先的绑定,下面这句无效,remove_updater不适合匿名函数,因此只能使用clear_updater
text.remove_updater(lambda a:a.next_to(dot,RIGHT))

#清空绑定的所有关系
text.clear_updaters()

#来来去去
self.play(dot.shift,UP*4,rate_func=there_and_back,run_time=2)

13.ValueTracker

只记录数值,不在屏幕上显示

#设置存值器t
t = ValueTracker(-2)
numline = NumberLine()
triangle = Triangle(fill_opacity=1,color=YELLOW)
.scale(0.1).move_to(np.array([-2,0.5,0]))

dec = DecimalNumber(0)

#将三角形进行绑定,随着存值器的变化而变化
triangle.add_updater(lambdaa:a.move_to(np.array([t.get_value(),0.5,0])))

#将古典数也与三级形进行绑定
dec.add_updater(lambda a:a.set_value(t.get_value()))
dec.add_updater(lambda a:a.next_to(triangle,UP))
self.add(numline,triangle,dec)

#设置值进行渲染
self.play(t.set_value,2,rate_func=there_and_back,run_time=3)

14.rate_func

定义了物体变换/运动的速率

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruosC4vR-1598661718748)(https://manim.ml/_images/rate_functions2.png)]

15.函数的写法

import numpy as np

np.sqrt(x) #x的平方根
np.power(x,2) #x的2次方
np.cbrt(10)  #10的立方根
no.exp(x) #x的幂次方

16.Text

Text:可以支持中文

color_gradient:颜色的梯度

length_of_output = 4:输出四个提出的颜色

font:这个参数必须要有,不然执行会报错

CONFIG = {
        'default_font': '你自己选择的字体'
    }
text_01 = Text('感 谢 观 看', font=self.default_font).set_height(1.)

17.更改画布的背景颜色

通过改变相机的配置,改变背景色

CONFIG = {
        'camera_config': {
            'background_color': BLUE,
        },
    }

18.TexMobject书写数学公式的写法

text01 = TexMobject('\\mathbf{RM')
text02 = TexMobject('\\sqrt{\\frac{a^2+b^2}{2} }}')
text03 = TexMobject(r'\sqrt{\frac{a^2+b^2}{2} }}')

19.字体颜色的用法

set_color_by_t2c:进行对字体上色

text01 = Text('几何法证明n个数的',font='思源黑体 Bold')
map = color_gradient([RED, PINK, BLUE,YELLOW], 5)
text01.set_color_by_t2c({'几何法':map[4],'证明':map[1],'n':map[2],'个数的':map[3]})

20.大括号的写法(Brance)

在矩形的左边画出一个大括号,标记为9

square = Square(side_length=2)
braces01 = Brace(square, LEFT)
brText01 = braces01.get_text('9').scale(0.6)

21.如何获取两个直线的交点的准确坐标

获取两条相交线段所有的点,会出现7个坐标 ,可以一个一个尝试,我这个是第三个坐标,还不是很清楚是否有规律可循

pl = np.array([-1.5,-1,0])
pr = np.array([1.5,-1,0])
line01 = Line(np.array([-3,2,0]),pr).set_color(RED)
line02 = Line(pl,np.array([3,2,0])).set_color(RED)
self.play(
    ShowCreation(line01),
    ShowCreation(line02)
)
group01 = VGroup(line01,line02)
print(group01.get_all_points())
dot = Dot( np.array([0.00000000e+00 , 1.11022302e-16 , 0.00000000e+00]))
self.play(Write(dot))

22.become

使用become进行转换对象的时候,不会改变前一个对象

circle = Circle()
square = Square(side_length=2)
self.play(circle.become, square)

23.Uncreate

将创建好的文字,删除,效果从后往前

self.play(Uncreate(text))

24.UpdateFromAlphaFunc

传入的函数含有参数alpha,

25.UpdateFromFunc

动画的效果:使矩形边移动边翻转

square = Square(side_length=2)
def anim(obj):
	obj.shift(RIGHT*dt*2)
	obj.rotate(0.4*TAU*dt)
self.play(
	UpdateFromFunc(square,anim)
)

26.ParametricFunction 及其 point_from_proportion

参数方程

传入的function自变量为参数t,t_min,t_max则是参数t的范围,这个会返回一个点的函数

#解析:
#t:则是0-1
#sin(t)从-pi/2到pi/2这段的高度
sinfunc = ParametricFunction(
	lambda t:np.array([t,np.sin(t),0]),t_min=PI/2,t_max=PI/2
).shift(RIGHT*2+DOWN).set_color(YELLOW)

#返回的是sinfunc上的一个坐标,也就是alpha会在0-1中不断增加,然后改变这个值
sinfunc.point_from_proportion(alpha) 


manim的一些实例代码片段

1.动画:两个矩形围绕圆旋转60°

class Arrange04(Scene):
    def construct(self):
        square1,square2 = VGroup(
            Square(),
            Square(color=TEAL)
        ).scale(0.3).set_y(-3)
        reference = DashedVMobject(Circle(radius=3,color=GRAY))
        self.add(square1,square2,reference)
        
        #core
        self.play(
            square1.rotate,2*PI/3,{'about_point':ORIGIN},
            Rotate(square2,2*PI/3,about_point=ORIGIN),
            run_time = 4
        )
        self.wait()

2.动画:两个矩形边旋转边往右边运动

class Arrange01(Scene):
    def construct(self):
        square1,square2 = VGroup(
            Square(color=RED),
            Square(color=BLUE)
        ).scale(0.5).set_x(-5)

        reference = DashedVMobject(Line(LEFT*5,RIGHT*5,color=GRAY))
        self.add(square1,square2,reference)

        square2.save_state()
        def update_rotate_move(mob,alpha):
            square2.restore()
            square2.shift(RIGHT*10*alpha)
            square2.rotate(3*PI*alpha)

        self.play(
            square1.rotate,3 * PI,
            square1.move_to,[5,0,0],
            UpdateFromAlphaFunc(square2,update_rotate_move),
            run_time=4
        )

        self.wait()

3.动画:动态的画弧

class Shapes(Scene):
    def construct(self):
        t = ValueTracker(0)
        cir = Circle(radius=2).shift(LEFT*5)
        dot_o = Dot(LEFT*5)
        dot_a = Dot(LEFT*3)
        l_oa = Line(LEFT*5,LEFT*3)
        dot_p = Dot().add_updater(lambda a:a.move_to(
            np.array([-5+2*np.cos(t.get_value()),2*np.sin(t.get_value()),0])
        ))
        l_op = Line(LEFT*5,LEFT*3).add_updater(lambda a:a.put_start_and_end_on(
            dot_o.get_center(),dot_p.get_center()
        ))
        arc = Arc(angle=0).add_updater(lambda a:a.become(
            Arc(start_angle=0,angle=t.get_value()%TAU,color=ORANGE).shift(LEFT*5)
        ))

        self.add(cir,dot_o,dot_a,dot_p,l_oa,l_op,arc)
        self.play(t.set_value,2*TAU,run_time=8,rate_func=linear)

科普:关于视屏动画的其他软知识

1.什么是帧(Frame)?

​ 帧就是视频或者动画中的每一张画面

2.什么是帧数(Frames) ?

​ 帧数就是为帧生成数量的简称,可以解释为静止画面的数量,如一个动画的帧率恒为60帧每秒,那么就是说它在一秒中的帧数为60帧

3.帧率(Frame rate) ?

​ 帧率(Frame rate) = 帧数(Frames) / 时间(Time),单位为帧每秒(FPS)

​ 在manim中 low : self.camera_frame_rate = 15 也就是15fps

持续更新…

 类似资料: