线以意外缩放旋转
The line rotate with unexpected scaling
场景很简单,一行并旋转PI/2,代码如下:
ln = Line(ORIGIN, RIGHT*2)
self.add(ln)
self.wait()
self.play(ApplyMethod(ln.rotate, PI/2, OUT))
但是,在旋转的过程中,貌似在缩放的同时,我检查了轴是[0 0 1]也就是z轴,我想线的长度应该保持不变。
如何防止线路结垢?谢谢!
使用Rotate
或Rotating
,参见this。
class RotateVector(Scene):
def construct(self):
coord_start=[1,1,0]
coord_end=[2,3,0]
dot_start=Dot().move_to(coord_start)
dot_end=Dot().move_to(coord_end)
vector=Arrow(coord_start,coord_end,buff=0)
vector.set_color(RED)
self.add(dot_start,dot_end)
self.play(GrowArrow(vector))
self.play(
Rotating(
vector,
radians=PI*2,
about_point=coord_start,
rate_func=smooth,
run_time=1
)
)
self.wait()
self.play(
Rotating(
vector,
radians=PI*2,
about_point=coord_end,
rate_func=linear,
run_time=1
)
)
self.wait()
编辑
您可以创建自定义动画:
class RotatingAndMove(Animation):
CONFIG = {
"axis": OUT,
"radians": TAU,
"run_time": 5,
"rate_func": linear,
"about_point": None,
"about_edge": None,
}
def __init__(self, mobject, direction,**kwargs):
assert(isinstance(mobject, Mobject))
digest_config(self, kwargs)
self.mobject = mobject
self.direction = direction
def interpolate_mobject(self, alpha):
self.mobject.become(self.starting_mobject)
self.mobject.rotate(
alpha * self.radians,
axis=self.axis,
about_point=self.about_point,
about_edge=self.about_edge,
)
self.mobject.shift(alpha*self.direction)
class NewSceneRotate(Scene):
def construct(self):
arrow=Vector(UP)
arrow.to_corner(UL)
self.play(GrowArrow(arrow))
self.play(
RotatingAndMove(arrow,RIGHT*12+DOWN*4)
)
self.wait()
或者您可以使用 UpdateFromAlphaFunc
:
class NewSceneRotateUpdate(Scene):
def construct(self):
arrow=Vector(UP)
arrow.to_corner(UL)
direction=RIGHT*12+DOWN*4
radians=TAU
arrow.starting_mobject=arrow.copy()
def update_arrow(mob,alpha):
mob.become(mob.starting_mobject)
mob.rotate(alpha*radians)
mob.shift(alpha*direction)
self.play(GrowArrow(arrow))
self.play(
UpdateFromAlphaFunc(arrow,update_arrow,rate_func=linear,run_time=5)
)
self.wait()
应该很清楚的一点是,当你定义一个更新函数时,使用 dt 和 alpha 是不一样的.即定义
不一样
def update_function(mob,dt)
作为
def update_function(mob,alpha)
dt随视频的fps而变化,计算公式如下:
dt = 1/self.camera.frame_rate
# You don't have to calculate it, manim already does it by default,
# I just write it so you know where it comes from.
其中self
指的是Scene
class。
而alpha是从0到1变化的,其实你可以把之前的场景写成这个update方法,得到的结果是一样的:
def update_arrow(mob,dt):
alpha=interpolate(0,1,dt)
mob.become(mob.starting_mobject)
mob.rotate(alpha*radians)
mob.shift(alpha*direction)
如果您希望 alpha 在不同的时间间隔内变化,这会很有用,请使用
alpha=interpolate(alpha_start,alpha_end,dt)
场景很简单,一行并旋转PI/2,代码如下:
ln = Line(ORIGIN, RIGHT*2)
self.add(ln)
self.wait()
self.play(ApplyMethod(ln.rotate, PI/2, OUT))
但是,在旋转的过程中,貌似在缩放的同时,我检查了轴是[0 0 1]也就是z轴,我想线的长度应该保持不变。
如何防止线路结垢?谢谢!
使用Rotate
或Rotating
,参见this。
class RotateVector(Scene):
def construct(self):
coord_start=[1,1,0]
coord_end=[2,3,0]
dot_start=Dot().move_to(coord_start)
dot_end=Dot().move_to(coord_end)
vector=Arrow(coord_start,coord_end,buff=0)
vector.set_color(RED)
self.add(dot_start,dot_end)
self.play(GrowArrow(vector))
self.play(
Rotating(
vector,
radians=PI*2,
about_point=coord_start,
rate_func=smooth,
run_time=1
)
)
self.wait()
self.play(
Rotating(
vector,
radians=PI*2,
about_point=coord_end,
rate_func=linear,
run_time=1
)
)
self.wait()
编辑
您可以创建自定义动画:
class RotatingAndMove(Animation):
CONFIG = {
"axis": OUT,
"radians": TAU,
"run_time": 5,
"rate_func": linear,
"about_point": None,
"about_edge": None,
}
def __init__(self, mobject, direction,**kwargs):
assert(isinstance(mobject, Mobject))
digest_config(self, kwargs)
self.mobject = mobject
self.direction = direction
def interpolate_mobject(self, alpha):
self.mobject.become(self.starting_mobject)
self.mobject.rotate(
alpha * self.radians,
axis=self.axis,
about_point=self.about_point,
about_edge=self.about_edge,
)
self.mobject.shift(alpha*self.direction)
class NewSceneRotate(Scene):
def construct(self):
arrow=Vector(UP)
arrow.to_corner(UL)
self.play(GrowArrow(arrow))
self.play(
RotatingAndMove(arrow,RIGHT*12+DOWN*4)
)
self.wait()
或者您可以使用 UpdateFromAlphaFunc
:
class NewSceneRotateUpdate(Scene):
def construct(self):
arrow=Vector(UP)
arrow.to_corner(UL)
direction=RIGHT*12+DOWN*4
radians=TAU
arrow.starting_mobject=arrow.copy()
def update_arrow(mob,alpha):
mob.become(mob.starting_mobject)
mob.rotate(alpha*radians)
mob.shift(alpha*direction)
self.play(GrowArrow(arrow))
self.play(
UpdateFromAlphaFunc(arrow,update_arrow,rate_func=linear,run_time=5)
)
self.wait()
应该很清楚的一点是,当你定义一个更新函数时,使用 dt 和 alpha 是不一样的.即定义
不一样 def update_function(mob,dt)
作为
def update_function(mob,alpha)
dt随视频的fps而变化,计算公式如下:
dt = 1/self.camera.frame_rate
# You don't have to calculate it, manim already does it by default,
# I just write it so you know where it comes from.
其中self
指的是Scene
class。
而alpha是从0到1变化的,其实你可以把之前的场景写成这个update方法,得到的结果是一样的:
def update_arrow(mob,dt):
alpha=interpolate(0,1,dt)
mob.become(mob.starting_mobject)
mob.rotate(alpha*radians)
mob.shift(alpha*direction)
如果您希望 alpha 在不同的时间间隔内变化,这会很有用,请使用
alpha=interpolate(alpha_start,alpha_end,dt)