%%manim -v WARNING -ql s1
if type("xxp's manim") == str:
# 不写在下方 construct 函数中,因为这可能使用到其内部的函数,我想与其分离,因为如果 construct 内部的函数改写了,我此处的类也需要改写
if type('function') == str:
def harmonic_func(u, v, l, m):
# 请不要使用 if l == x & m == y 这种形式,会报错
if l == 0 & m == 0:
r = np.sqrt(1/(4*PI))
elif l == 1:
if m == 0:
r = np.sqrt(3/(4*PI))*np.cos(u)
elif m == 1:
r = np.sqrt(3/(4*PI))*np.sin(u)*np.cos(v)
elif m == -1:
r = np.sqrt(3/(4*PI))*np.sin(u)*np.sin(v)
elif l == 2:
if m == 0:
r = np.sqrt(5/(16*PI))*(3*np.cos(u)**2 - 1)
if m == 1:
r = np.sqrt(15/(4*PI))*np.sin(u)*np.cos(u)*np.cos(v)
if m == -1:
r = np.sqrt(15/(4*PI))*np.sin(u)*np.cos(u)*np.sin(v)
if m == 2:
r = np.sqrt(15/(16*PI))*np.sin(u)**2*np.sin(2*v)
if m == -2:
r = np.sqrt(15/(16*PI))*np.sin(u)**2*np.cos(2*v)
elif l == 3:
if m == 0:
r = 1/4*np.sqrt(7/PI)*(5*np.cos(u)**3 - 3*np.cos(u))
if m == 1:
r = 1/8*np.sqrt(42/PI)*np.sin(u)*(5*np.cos(u)**2 - 1)*np.cos(v)
if m == -1:
r = 1/8*np.sqrt(42/PI)*np.sin(u)*(5*np.cos(u)**2 - 1)*np.sin(v)
if m == 2:
r = 1/4*np.sqrt(105/PI)*np.sin(u)**2*np.cos(u)*np.sin(2*v)
if m == -2:
r = 1/4*np.sqrt(105/PI)*np.sin(u)**2*np.cos(u)*np.cos(2*v)
if m == 3:
r = 1/8*np.sqrt(70/PI)*np.sin(u)**3*np.cos(3*v)
if m == -3:
r = 1/8*np.sqrt(70/PI)*np.sin(u)**3*np.sin(3*v)
else:
raise Exception('l or m is too large')
return r
if type('mobject') == str:
class Atom(VGroup):
def __init__(
self,
quantum_num_li: list, # each item in this list is a list
position_correction: bool = False, # 这个是专门为 sp2 杂化设计的,因为我发现 sp2 杂化时原子核不在中心,这是因为正三角形放置在画布中时不会以自身的中心为中心点,而是会产生一些偏移,于是我们使用 p 轨道定位
**kwargs
):
super().__init__(**kwargs) # 如果不使用这句话,那么 self.add 会失效
nucleus = Sphere(fill_opacity=0.7, stroke_width=0).set_color(
"#9AFF9A").scale(0.5)
axes = ThreeDAxes(x_range=(-5, 5, 1), y_range=(-5, 5, 1), z_range=(-5, 5, 1),
x_length=5, y_length=5, z_length=5) # 注意默认的 x, y, z 轴长度不相等,图像会拉伸
orbits = VGroup()
for num in quantum_num_li:
orbit = Surface(
# 在不杂化的原子中,num 是含有两个元素的列表,分布代表 l 和 m;在杂化的原子中,num 是含有大于等于六个元素的列表,一部分包括杂化轨道的系数
lambda u, v: axes.c2p(*self.specific_harmonic_func(u, v, num)),
resolution=(20, 20),
v_range=[0, 2*PI],
u_range=[0, 2*PI],
checkerboard_colors=[BLUE],
fill_opacity=0.3,
stroke_width=0,
)
orbits.add(orbit)
nucleus_radius = nucleus.width
if orbits.depth > orbits.width: # 事实上,三维物体要考虑 width, height, depth
orbits.set(depth=6*nucleus_radius)
else:
orbits.set(width=6*nucleus_radius)
if position_correction:
distance_deviation = nucleus.get_center() - orbits[-1].get_center()
orbits.shift(distance_deviation)
self.orbits = orbits
self.add(nucleus, orbits)
def specific_harmonic_func(self, u, v, num) -> list: # 这个函数根据是否杂化而变化
pass
class AutographIntroduction(Group):
def __init__(
self,
image: str,
name: str,
date_of_birth_and_death: str,
**kwargs
):
super().__init__(**kwargs)
image = ImageMobject(image)
if image.width > image.height:
image.set(width = 5.5)
else:
image.set(height = 5.5)
image.shift(3.5*LEFT+0.8*UP)
name = Narrator(name).next_to(image,DOWN)
date_of_birth_and_death = Narrator(date_of_birth_and_death).scale(0.8).next_to(name,DOWN)
self.add(image, name, date_of_birth_and_death)
class DotGroup(VGroup):
def __init__(
self,
num: int = 10,
internal_radius: float = 0,
external_radius: float = 2.5,
scale_min: float = 0.6,
scale_max: float = 1.4,
**kwargs
):
super().__init__(**kwargs)
for i in range(num):
radius = internal_radius + (external_radius - internal_radius)*np.random.rand()
scale = scale_min + (scale_max - scale_min)*np.random.rand()
theta = np.random.rand()*2*PI
self.add(Dot().copy().shift(radius*np.cos(theta)*RIGHT+radius*np.sin(theta)*UP).scale(scale))
class HybridAtom(Atom):
def __init__(
self,
hybrid_type: int,
**kwargs
):
quantum_num_li = self.hybrid_coefficient(hybrid_type)
if hybrid_type == 2:
position_correction = True
else:
position_correction = False
super().__init__(quantum_num_li, position_correction=position_correction, **kwargs)
def hybrid_coefficient(self, hybrid_type):
if hybrid_type == 1:
coe = [[[1/np.sqrt(2), 0, 0], [1/np.sqrt(2), 1, 1]], [[1/np.sqrt(2), 0, 0], [-1/np.sqrt(2), 1, 1]], [
[1, 1, -1]], [[1, 1, 0]]] # this represents f1 = s + px, f2 = x - px, f3 = p, f4 = p
elif hybrid_type == 2:
# coe = [[[np.sqrt(1/3),0,0], [-np.sqrt(1/6),1,1], [np.sqrt(1/2),1,-1]]]
coe = [[[np.sqrt(1/3), 0, 0], [np.sqrt(2/3), 1, 1]], [[np.sqrt(1/3), 0, 0], [-np.sqrt(1/6), 1, 1], [
np.sqrt(1/2), 1, -1]], [[np.sqrt(1/3), 0, 0], [-np.sqrt(1/6), 1, 1], [-np.sqrt(1/2), 1, -1]], [[1, 1, 0]]]
elif hybrid_type == 3:
coe = [[[1, 0, 0], [1, 1, 1], [1, 1, -1], [1, 1, 0]], [[1, 0, 0], [1, 1, 1], [-1, 1, -1], [-1, 1, 0]],
[[1, 0, 0], [-1, 1, 1], [1, 1, -1], [-1, 1, 0]], [[1, 0, 0], [-1, 1, 1], [-1, 1, -1], [1, 1, 0]]]
return coe
def specific_harmonic_func(self, u, v, num) -> list:
r = 0
for i in num:
r += i[0]*harmonic_func(u, v, i[1], i[2])
r = r ** 2
return [r*np.sin(u)*np.cos(v), r*np.sin(u)*np.sin(v), r*np.cos(u)]
class MusicRecommender(Group):
def __init__(
self,
recommender: str,
music: str,
**kwargs
):
super().__init__(**kwargs)
image = ImageMobject(f"D:\\manimIMG\\{recommender}.png").set(width=1)
music = Text(music, font='STFangSong').scale(0.7).next_to(img,10*LEFT)
name = ImageMobject(f"D:\\manimIMG\\{recommender}name.png").match_height(music).next_to(img,2*RIGHT)
self.add(image, music, name)
class Narrator(Text):
def __init__(
self,
text: str,
font_type: int = 1,
**kwargs
):
if font_type == 1:
font = "STZhongsong"
elif font_type == 2:
font = "STFangsong"
super().__init__(text, font=font, **kwargs)
self.to_edge(DOWN).scale(0.6)
class TextFlower(VGroup):
def __init__(
self,
text: str,
color_type: int = 1,
**kwargs
):
super().__init__(**kwargs)
if color_type == 1:
color = ['#f3e9e0', '#fea8a9']
elif color_type == 2:
color = ['#f3e9e0', '#b1d85c']
elif color_type == 3:
color = ['#f3e9e0', '#6A5ACD']
text = Text(text, font = 'STZhongsong', stroke_width=2).set_color(color = color)
flower = SVGMobject(r"D:\manimSource\svg\icon.svg")[8].rotate(PI/2).set_color(color = color[::-1]).scale(1.5)
text.next_to(flower, RIGHT)
self.add(flower, text)
self.set(height = 0.6)
self.move_to(ORIGIN)
class UnhybridAtom(Atom):
def __init__(
self,
*args, # this list contains l, m
**kwargs
):
super().__init__([[*args]], **kwargs)
def specific_harmonic_func(self, u, v, num) -> list:
r = harmonic_func(u, v, *num)
r = r ** 2
return [r*np.sin(u)*np.cos(v), r*np.sin(u)*np.sin(v), r*np.cos(u)]
class xa(Atom): # Atom
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xai(AutographIntroduction): # AutographIntroduction
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xdg(DotGroup): # DotGroup
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xha(HybridAtom): # HybridAtom
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xmr(MusicRecommender): # MusicRecommender
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xn(Narrator): # Narrator
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xtf(TextFlower): # TextFlower
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class xua(UnhybridAtom): # UnhybridAtom
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if type('animation') == str:
class CorrespondingPartsTransform(AnimationGroup):
def __init__(
self,
names,
*args,
**kwargs
):
# names is a list of mobjects
# args represent lists, such as [0,1,[0,0,1,1,2,2]], the 1st and 2nd numbers represent the index of mobject in the names list
def pretrans0(name, i): # get the transforming part
if type(i) == int:
back = name[i]
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])
back = name[n1:n2]
return back
def pretrans(name, i):
if type(i) == int:
back = name[i]
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])
back = name[n1:n2]
elif type(i) == list:
back = VGroup()
for j in i:
item = pretrans0(name, j)
back.add(item)
return back
ag = []
itemli = []
for l in names:
itemli.append(list(range(len(l))))
# delete the tranformed part
def countli0(name, i):
if type(i) == int:
name.remove(i)
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])-1
p1 = name.index(n1)
p2 = name.index(n2)
del name[p1:p2+1]
def countli(name, i):
if type(i) == int:
name.remove(i)
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])-1
p1 = name.index(n1)
p2 = name.index(n2)
del name[p1:p2+1]
elif type(i) == list:
for j in i:
item = countli0(name, j)
set1 = set()
set2 = set()
# two groups of transforming
for m in range(len(args)):
n = 0
for i in args[m][2]:
n += 1
if n % 2 != 0:
u = pretrans(names[args[m][0]], i)
countli(itemli[args[m][0]], i)
set1.add(args[m][0])
else:
v = pretrans(names[args[m][1]], i)
item = Transform(u,v) # 如果使用改进的 at(),会显示未定义
ag.append(item)
countli(itemli[args[m][1]], i)
set2.add(args[m][1])
for i in set1:
for ii in itemli[i]:
names[i][ii].save_state()
ag.append(ShrinkToCenter(names[i][ii]))
for j in set2:
for jj in itemli[j]:
ag.append(GrowFromCenter(names[j][jj]))
super().__init__(*ag, **kwargs)
class CorrespondingPartsTransformOrigin(AnimationGroup):
def __init__(
self,
original_mobject: mobject,
target_mobject: mobject,
corresponding_parts_list: list,
**kwargs
):
# a and b represent mobjects, c represents the corresponding transform parts
def pretrans0(name, i):
if type(i) == int:
back = name[i]
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])
back = name[n1:n2]
return back
def pretrans(name, i):
if type(i) == int:
back = name[i]
elif type(i) == str:
m = i.find('.')
n1 = int(i[0:m])
n2 = int(i[m+1:])
back = name[n1:n2]
elif type(i) == list:
back = VGroup()
for j in i:
item = pretrans0(name, j)
back.add(item)
return back
n = 0
ag = []
for i in corresponding_parts_list:
n += 1
if n % 2 != 0:
u = pretrans(original_mobject, i)
else:
v = pretrans(target_mobject, i)
item = Transform(u,v)
ag.append(item)
super().__init__(*ag, **kwargs)
class DotFadeIn(AnimationGroup):
def __init__(
self,
*mobjects,
**kwargs
):
ag = []
for i in mobjects:
dots = DotGroup(len(i)).set_color(WHITE).set_opacity(0)
ag.append(Transform(dots,i))
super().__init__(*ag, **kwargs)
class DotFadeOut(AnimationGroup):
def __init__(
self,
*mobjects,
**kwargs
):
ag = []
for i in mobjects:
dots = DotGroup(len(i)).set_color(WHITE).set_opacity(0)
ag.append(Transform(i,dots))
super().__init__(*ag, **kwargs)
class FisheyeGrow(AnimationGroup):
def __init__(
self,
*mobjects,
**kwargs
):
# 注意如果对 Text 使用此动画,要使用索引才能生效:Text()[0]
ag = []
for a in mobjects:
a0 = a.copy()
myl = 5 # myl represents the fish eye's border, default: 5
li = a.points
def getlen(k):
return np.sqrt(k[0]**2 + k[1]**2 + k[2]**2)
for i in li:
times = 0.04*(myl - getlen(i))**3
i *= times # the further, times is smaller
ag.append(Transform(a0,a))
super().__init__(*ag, **kwargs)
class FisheyeShrink(AnimationGroup):
def __init__(
self,
*mobjects,
**kwargs
):
# 注意如果对 Text 使用此动画,要使用索引才能生效:Text()[0]
ag = []
for a in mobjects:
a0 = a.copy()
li = a.points
def getlen(k):
return np.sqrt(k[0]**2 + k[1]**2 + k[2]**2)
for i in li:
times = 0.02*getlen(i)**3 + 0.5 # 0.5 represent the minimum, because when the point is near center, genlen() return a number near 0
i *= times # the further, times is larger
ag.append(Transform(a0,a))
super().__init__(*ag, **kwargs)
class UnfoldFlowers(Succession):
def __init__(
self,
texts, # a VGroup of Texts
**kwargs
):
animations = self.main_animation(texts)
super().__init__(*animations, **kwargs)
def main_animation(self, texts):
animation_group = []
flower_num = len(texts)
flower = TextFlower("").shift(0.7*LEFT)
flowers = VGroup(*[flower.copy() for i in range(flower_num)]) # 注意不能直接写成 VGroup(... for i in ...),必须使用 *
animation1 = DrawBorderThenFill(flowers)
animation2 = AnimationGroup(*[Rotate(flowers[i + 1], angle=2*PI/flower_num*(i+1), about_point=ORIGIN) for i in range(flower_num-1)], lag_ratio=0.3)
animation3 = Transform(flowers, texts)
animation_group.append(animation1)
animation_group.append(animation2)
animation_group.append(animation3)
return animation_group
class Vibration(AnimationGroup):
def __init__(
self,
*mobjects,
t: int = 2,
**kwargs
):
ag = []
for mobject in mobjects:
li = []
center = mobject.get_center()
vibration_times = int(t*5) # 否则为 float 类型
for i in range(vibration_times):
x = np.random.rand()*0.3
y = np.random.rand()*2*PI
li.append(ApplyMethod(mobject.move_to, center+x*np.cos(y)*RIGHT+x*np.sin(y)*UP, run_time=0.2))
ag.append(Succession(*li))
super().__init__(*ag, **kwargs)
class ycpt(CorrespondingPartsTransform): # CorrespondingPartsTransform
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class ycpto(CorrespondingPartsTransformOrigin): # CorrespondingPartsTransformOrigin
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class ydfi(DotFadeIn): # DotFadeIn
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class ydfo(DotFadeOut): # DotFadeOut
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class yfg(FisheyeGrow): # FisheyeGrow
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class yfs(FisheyeShrink): # FisheyeShrink
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class yuf(UnfoldFlowers): # UnfoldFlowers
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class yv(Vibration): # Vibration
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class s1(Scene):
def construct(self):
if type('abbreviation') == str:
# 必须写在 construct 函数里面
if type('constant') == str:
r = RIGHT;l = LEFT;d = DOWN;u = UP;du = DEGREES
rr = RED;bb = BLUE;gg = GREEN;gg2 = GOLD;pp = PINK;tt = TEAL;ww = WHITE;o = ORIGIN
if type('manim CE') == str:
def sa(*args, **kwargs): # self.add()
return self.add(*args, **kwargs)
def saw(*args, **kwargs): # self.add() and self.wait()
self.add(*args, **kwargs);self.wait()
def sc(*args, **kwargs): # self.clear()
return self.clear(*args, **kwargs)
def sp(*args, **kwargs): # self.play()
return self.play(*args, **kwargs)
def sr(*args, **kwargs): # self.remove()
return self.remove(*args, **kwargs)
def sw(*args, **kwargs): # self.wait()
return self.wait(*args, **kwargs)
def ac(*args, **kwargs): # Animation coloring
li = []
for i in range(len(args)):
if i % 2 == 0:
li.append(ApplyMethod(args[i].set_color, args[i+1], **kwargs))
return AnimationGroup(*li)
def aci(a, *args, **kwargs): # Animation Circumscribe()
return Circumscribe(a, *args, **kwargs)
def acct(a, b, *args, **kwargs): # Animation CounterclockwiseTransform()
return CounterclockwiseTransform(a, b, *args, **kwargs)
def act(a, b, *args, **kwargs): # Animation ClockwiseTransform()
return ClockwiseTransform(a, b, *args, **kwargs)
def adb(*args, **kwargs): # Animation DrawBorderThenFill()
li = []
for i in args:
li.append(DrawBorderThenFill(i, **kwargs))
return AnimationGroup(*li)
def adbo(a, *args, **kwargs): # Animation DrawBorderThenFill() origin
return DrawBorderThenFill(a, *args, **kwargs)
def adbr(a, *args, **kwargs): # Animation DrawBorderThenFill() reverse
return DrawBorderThenFill(a, *args, **kwargs, reverse_rate_function = True)
def afi(a, *args, **kwargs): # Animation FadeIn()
return FadeIn(a, *args, **kwargs)
def afii(a, *args, **kwargs): # Animation FadeIn()
return FadeIn(a, *args, shift=DOWN, **kwargs)
def afo(a, *args, **kwargs): # Animation FadeOut()
return FadeOut(a, *args, **kwargs)
def afoo(a, *args, **kwargs): # Animation FadeOut()
return FadeOut(a, *args, shift=DOWN, **kwargs)
def agf(*args, **kwargs): # Animation GrowFromCenter()
li = []
for i in args:
li.append(GrowFromCenter(i, **kwargs))
return AnimationGroup(*li)
def agfe(a, b, *args, **kwargs): # Animation GrowFromEdge()
return GrowFromEdge(a, b, *args, **kwargs)
def agfo(a, *args, **kwargs): # Animation GrowFromCenter() origin
return GrowFromCenter(a, *args, **kwargs)
def agfp(a, b, *args, **kwargs): # Animation GrowFromPoint()
return GrowFromPoint(a, b, *args, **kwargs)
def ai(a, *args, **kwargs): # Animation Indicate
return Indicate(a, *args, **kwargs)
def als(a, *args, **kwargs): # Animation LaggedStart()
return LaggedStart(a, *args, **kwargs)
def ama(a, b, *args, **kwargs): # Animation MoveAlongPath()
return MoveAlongPath(a, b, *args, **kwargs)
def amt(*args, **kwargs): # Animation move to
li = []
i = 1
for a in args:
if i % 2 != 0:
li.append(ApplyMethod(a.move_to, args[i], **kwargs))
i += 1
return AnimationGroup(*li)
def are(a, *args, **kwargs): # Animation Restore()
return Restore(a, *args, **kwargs)
def aro(a, b, *args, **kwargs): # Animation Rotate()
# b 可以为坐标或物体
if type(b) == list:
return Rotate(a, about_point = b, *args, **kwargs)
else:
return Rotate(a, about_point = b.get_center(), *args, **kwargs)
def art(a, b, *args, **kwargs): # Animation ReplacementTransform()
return ReplacementTransform(a, b, *args, **kwargs)
def asc(*args, **kwargs): # Animation scale
li = []
i = 1
for a in args:
if i % 2 != 0:
li.append(ApplyMethod(a.scale, args[i], **kwargs))
i += 1
return AnimationGroup(*li)
def ash(*args, **kwargs): # Animation Shift
li = []
i = 1
for a in args:
if i % 2 != 0:
li.append(ApplyMethod(a.shift, args[i], **kwargs))
i += 1
return AnimationGroup(*li)
def asi(a, *args, **kwargs): # Animation SpinInFromNothing
return SpinInFromNothing(a, angle=2 * PI, *args, **kwargs)
def asir(a, *args, **kwargs): # Animation SpinInFromNothing reverse
return SpinInFromNothing(a, angle=2 * PI, *args, **kwargs, reverse_rate_function = True)
def aso(*args, **kwargs): # Animation set opacity
li = []
for i in range(len(args)):
if i % 2 == 0:
li.append(ApplyMethod(args[i].set_opacity, args[i+1], **kwargs))
return AnimationGroup(*li)
def ast(*args, **kwargs): # Animation ShrinkToCenter
def ast_single(a, *args, **kwargs):
dot = Dot(radius=0.01).set_opacity(0).move_to(a)
return at(a,dot)
li = []
for i in args:
li.append(ast_single(i))
return AnimationGroup(*li)
def asto(a, *args, **kwargs): # Animation ShrinkToCenter origin
# a will restore after shrink
a.save_state()
li = []
li.append(ShrinkToCenter(a, *args, **kwargs))
li.append(Restore(a, run_time=0))
return Succession(*li)
def asu(*args): # Animation Succession
return Succession(*args)
def at(a, b, *args, **kwargs): # Animation Transform() (improved)
# improve: a will not change after transform
a.save_state()
return Succession(ReplacementTransform(a, b, *args, **kwargs),Restore(a,run_time=0))
def atm(a, b, *args, **kwargs): # Animation TransformMatchingShapes()
return TransformMatchingShapes(a, b, *args, **kwargs)
def ato(a, b, *args, **kwargs): # Animation Transform() origin
return Transform(a, b, *args, **kwargs)
def auw(a, *args, **kwargs): # Animation Unwrite()
return Unwrite(a, *args, **kwargs)
def aw(a, *args, **kwargs): # Animation Write()
return Write(a, *args, **kwargs)
def awi(a, *args, **kwargs): # Animation Wiggle()
return Wiggle(a, *args, **kwargs)
def mab(a, b, *args, **kwargs): # mobject ArcBetweenPoints
return ArcBetweenPoints(a.get_center(), b.get_center(), angle = 120*DEGREES, *args, **kwargs)
def mbbm(a,b,buff,rise=0,single=0,dire=DOWN): # mobject BraceBetweenMobject
x = a.get_center() - b.get_center()
y = x/np.sqrt(x[0]**2+x[1]**2+x[2]**2)
if single == 0:
return BraceBetweenPoints(a.get_center() + buff + rise/2*y, b.get_center() + buff - rise/2*y)
else:
return BraceBetweenPoints(a.get_center() + buff - rise/2*dire, b.get_center() + buff + rise/2*(dire))
def mdl(a, b, *args, **kwargs): # mobject DashedLine
return DashedLine(a, b, *args, **kwargs)
def mmt(text, *args, **kwargs): # mobject MathTex
return MathTex(text, *args, **kwargs)
def msm(name, *args, **kwargs): # mobject SVGMobject
sm = SVGMobject(f'D:\\manimSVG\\{name}.svg')
return sm
def msmc(name, *args, **kwargs): # mobject SVGMobject constant
sm = SVGMobject(f'D:\\manimSVG\\constants\\{name}.svg').scale(0.4).shift(5*r)
return sm
def mt(text, *args, **kwargs): # mobject Text
return Text(text, *args, **kwargs)
def mvg(*args, **kwargs): # mobject VGroup
return VGroup(*args, **kwargs)
if type('organization') == str:
def obc(*args): # organization beforehand coloring
i = 1
for a in args:
if i % 2 != 0:
a.set_color(args[i])
i += 1
def obmt(*args): # organization beforehand move to
i = 1
for a in args:
if i % 2 != 0:
a.move_to(args[i])
i += 1
def obnt(*args): # organization beforehand next to
i = 0
for a in args:
if i % 3 == 0:
a.next_to(args[i+1], args[i+2])
i += 1
def obo(*args): # organization beforehand (set) opacity
i = 1
for a in args:
if i % 2 != 0:
a.set_opacity(args[i])
i += 1
def obsc(*args): # organization beforehand scale
i = 1
for a in args:
if i % 2 != 0:
if type(a) == list:
for j in a:
j.scale(args[i])
else:
a.scale(args[i])
i += 1
def obsh(*args): # organization beforehand shift
i = 1
for a in args:
if i % 2 != 0:
a.shift(args[i])
i += 1
def oc(*args): # organization check
self.camera.background_color = WHITE
full = FullScreenRectangle()
for svg in args:
if type(svg) == list:
self.clear()
def checkedge(a):
for i in a:
if i.width/i.height > 1920/1080:
i.set(width = full.width/2.5)
else:
i.set(height = full.height/2.5)
checkedge(svg)
if len(svg) == 2:
svg[0].to_corner(UL)
svg[1].to_corner(DR)
elif len(svg) == 3:
svg[0].to_corner(UL)
svg[1].to_corner(UR)
svg[2].to_corner(DL)
elif len(svg) == 4:
svg[0].to_corner(UL)
svg[1].to_corner(UR)
svg[2].to_corner(DL)
svg[3].to_corner(DR)
for sss in svg:
self.add(sss.set(color = RED))
for sss in svg:
n = 0
for i in sss:
num = Integer(number=n, stroke_width=2).set_color(BLACK).move_to(i)
n += 1
self.add(num)
self.wait()
else:
self.clear()
self.add(svg.set(color = RED))
n = 0
for i in svg:
num = Integer(number=n, stroke_width=2).set_color(BLACK).move_to(i)
n += 1
self.add(num)
self.wait()
self.clear()
def ocoi(*args): # organization color and opacity init
def xc2h(c):
return rgb_to_hex(color_to_rgb(c))
for a in args:
# 先缩放再设置透明度(否则会消失不见)
a.set_opacity(1)
for i in a:
if xc2h(i.color) == '#ff0000':
i.set_color([RED_C, RED_E]).set_sheen(0.3).set_opacity(0.8)
elif xc2h(i.color) == '#ffff00':
i.set_color([GOLD_C, GOLD_E]).set_sheen(0.3).set_opacity(0.8)
elif xc2h(i.color) == '#00ff00':
i.set_color([GREEN_C, GREEN_E]).set_sheen(0.3).set_opacity(0.8)
elif xc2h(i.color) == '#00ffff':
i.set_color([TEAL_C, TEAL_E]).set_sheen(0.3).set_opacity(0.8)
elif xc2h(i.color) == '#0000ff':
i.set_color([BLUE_C, BLUE_E]).set_sheen(0.3).set_opacity(0.8)
elif xc2h(i.color) == '#ff00ff':
i.set_color([PINK_C, PINK_E]).set_sheen(0.3).set_opacity(0.8)
def oen(a, font_type=1): # organization execute narrator
if font_type == 1:
for i in a:
globals()[f't{str(i)}']=on(a[i])
elif font_type == 2:
for i in a:
globals()[f'n{str(i)}']=on2(a[i])
def oem(name, num): # organization execute mobject
for i in range(num):
globals()[name + str(i+1)]=msm(name + str(i+1))
def oeo(name,a): # organization execute object
# attention: when you try to use object defined before in oeo(), you should run this function before you defined
for i in a:
if type(a[i]) == str:
globals()[name + str(i)]=on2(a[i])
else:
globals()[name + str(i)]=a[i]
def oip(*args): # organization interval play
for a in args:
if type(a) == list:
self.wait(0.5)
self.play(*a)
self.wait(0.5)
elif type(a) == tuple:
self.clear()
self.add(*a)
else:
self.wait(0.5)
self.play(a)
self.wait(0.5)
def olal(t,*argss): # organization lagged animations list
args = []
for i in argss:
args.append(i)
args.reverse() # 不是args = args.reverse()
n = 0
for a in args:
if n == 1:
ag = AnimationGroup(args[1],args[0],lag_ratio=t)
elif n > 1:
ag = AnimationGroup(a,ag,lag_ratio=t)
n += 1
return ag
def oms(a, n1, b, n2): # organization move and scale (according to components)
scale = b[n2].width/a[n1].width
a.scale(scale)
vect = b[n2].get_center() - a[n1].get_center()
a.shift(vect)
def ont(a,n,b,m,buff): # organization next to (according to components)
a1 = a[n].copy()
a[n].next_to(b[m],buff)
vect = a[n].get_center() - a1.get_center()
aleft = mvg(a[0:n],a[n+1:])
aleft.shift(vect)
def oos(num, *args): # organization opacity scale (according to components)
# num represents the magnification of the 1st mobject, args represent the mobjects
def premovescale(a, b):
for i in a:
# 设置 get_fill_opacity() == 0.5 会失效
if i.get_fill_opacity() < 1:
x = i
for j in b:
if j.get_fill_opacity() < 1:
y = j
scale = y.height/x.height
a.scale(scale)
# 先缩放再移动
vector = y.get_center() - x.get_center()
a.shift(vector)
args[0].scale(num)
for n in range(len(args) - 1):
premovescale(args[n+1], args[n])
ocoi(*args)
def opic(r, *args): # organization place in circle
n = 0
vg = VGroup()
for i in args:
i.move_to(ORIGIN)
i.shift(r*np.cos(n*2*PI/len(args) + PI/2)*RIGHT + r*np.sin(n*2*PI/len(args) + PI/2)*UP)
vg.add(i)
n += 1
return vg