From 3b99e1259fea76103adc3c25b3af2da6d98635ed Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Wed, 14 Apr 2021 17:14:20 +0200 Subject: Add some animations --- vorlesungen/punktgruppen/crystals.py | 269 +++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 vorlesungen/punktgruppen/crystals.py (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py new file mode 100644 index 0000000..0f97a0f --- /dev/null +++ b/vorlesungen/punktgruppen/crystals.py @@ -0,0 +1,269 @@ +from manim import * + +import math as m +import numpy as np + +# configure style +config.background_color = '#202020' +config.tex_template.add_to_preamble( + r"\usepackage[p,osf]{scholax}" + r"\usepackage{amsmath}" + r"\usepackage[scaled=1.075,ncf,vvarbb]{newtxmath}" +) + +# scenes +class Geometric2DSymmetries(Scene): + def construct(self): + # title + title = Tex(r"Geometrische \\ Symmetrien") + title.scale(1.5) + self.play(Write(title)) + self.wait() + self.play(FadeOut(title)) + self.wait() + + self.intro() + self.cyclic() + self.dihedral() + + def intro(self): + # create square + square = Square() + square.set_fill(PINK, opacity=.5) + self.play(SpinInFromNothing(square)) + self.wait() + + # the action of doing nothing + action = MathTex(r"1") + self.play(Write(action)) + self.play(ApplyMethod(square.scale, 1.2)) + self.play(ApplyMethod(square.scale, 1/1.2)) + self.play(FadeOut(action)) + + # show some reflections + axis = DashedLine(2 * LEFT, 2 * RIGHT) + sigma = MathTex(r"\sigma") + sigma.next_to(axis, RIGHT) + + self.play(Create(axis)) + self.play(Write(sigma)) + + self.play(ApplyMethod(square.flip, RIGHT)) + self.wait() + + for d in [UP + RIGHT, UP]: + self.play( + Rotate(axis, PI/4), + Rotate(sigma, PI/4, about_point=ORIGIN)) + + self.play(Rotate(sigma, -PI/4), run_time=.5) + self.play(ApplyMethod(square.flip, d)) + + self.play( + FadeOutAndShift(sigma), + Uncreate(axis)) + + # show some rotations + dot = Dot(UP + RIGHT) + figure = VGroup() + figure.add(square) + figure.add(dot) + + rot = MathTex(r"r") + self.play(Write(rot), Create(dot)) + + last = rot + for newrot in map(MathTex, [r"r", r"r^2", r"r^3"]): + self.play( + ReplacementTransform(last, newrot), + Rotate(figure, PI/2, about_point=ORIGIN)) + self.wait() + last = newrot + + self.play(Uncreate(dot), FadeOut(square), FadeOut(last)) + + + def cyclic(self): + # create symmetric figure + figure = VGroup() + prev = [1.5, 0, 0] + for i in range(1,6): + pos = [ + 1.5*m.cos(2 * PI/5 * i), + 1.5*m.sin(2 * PI/5 * i), + 0 + ] + + if prev: + line = Line(prev, pos) + figure.add(line) + + dot = Dot(pos, radius=.1) + if i == 5: + dot.set_fill(RED) + + prev = pos + figure.add(dot) + + group = MathTex(r"G = \langle r \rangle") + self.play(Write(group), run_time = 2) + self.wait() + self.play(ApplyMethod(group.to_corner, UP)) + + actions = map(MathTex, [r"1", r"r", r"r^2", r"r^3", r"r^4", r"1"]) + action = next(actions, MathTex(r"r")) + + self.play(Create(figure)) + self.play(Write(action)) + self.wait() + + for i in range(5): + newaction = next(actions, MathTex(r"r")) + self.play( + ReplacementTransform(action, newaction), + Rotate(figure, 2*PI/5, about_point=ORIGIN)) + action = newaction + + self.play(Uncreate(figure), FadeOut(action)) + + whole_group = MathTex( + r"G = \langle r \rangle" + r"= \left\{1, r, r^2, r^3, r^4 \right\}") + + self.play(ApplyMethod(group.move_to, ORIGIN)) + self.play(ReplacementTransform(group, whole_group)) + self.wait() + + cyclic = MathTex( + r"C_n = \langle r \rangle" + r"= \left\{1, r, r^2, \dots, r^n \right\}") + + cyclic_title = Tex(r"Zyklische Gruppe") + cyclic_title.next_to(cyclic, UP * 2) + + cyclic.scale(1.2) + cyclic_title.scale(1.2) + + self.play(ReplacementTransform(whole_group, cyclic)) + self.play(FadeInFrom(cyclic_title, UP)) + + self.wait(5) + self.play(FadeOut(cyclic), FadeOut(cyclic_title)) + + def dihedral(self): + # create square + square = Square() + square.set_fill(PINK, opacity=.5) + + # generator equation + group = MathTex( + r"G = \langle \sigma, r \,|\,", + r"\sigma^2 = 1,", + r"r^4 = 1,", + r"(\sigma r)^2 = 1 \rangle") + + self.play(Write(group), run_time = 2) + self.wait() + self.play(ApplyMethod(group.to_corner, UP)) + self.play(FadeIn(square)) + + axis = DashedLine(2 * LEFT, 2 * RIGHT) + sigma = MathTex(r"\sigma^2 = 1") + sigma.next_to(axis, RIGHT) + self.play(Create(axis), Write(sigma)) + self.play(ApplyMethod(square.flip, RIGHT)) + self.play(ApplyMethod(square.flip, RIGHT)) + self.play(Uncreate(axis), FadeOut(sigma)) + + # rotations + dot = Dot(UP + RIGHT) + rot = MathTex(r"r^4 = 1") + rot.next_to(square, DOWN * 3) + + figure = VGroup() + figure.add(dot) + figure.add(square) + + self.play(Write(rot), Create(dot)) + for i in range(4): + self.play(Rotate(figure, PI/2)) + self.play(FadeOut(rot), Uncreate(dot)) + + # rotation and flip + action = MathTex(r"(\sigma r)^2 = 1") + action.next_to(square, DOWN * 5) + + dot = Dot(UP + RIGHT) + axis = DashedLine(2 * LEFT, 2 * RIGHT) + self.play(Create(dot), Create(axis), Write(action)) + + figure = VGroup() + figure.add(dot) + figure.add(square) + + for i in range(2): + self.play(Rotate(figure, PI/2)) + self.play(ApplyMethod(figure.flip, RIGHT)) + self.wait() + + self.play(Uncreate(dot), Uncreate(axis), FadeOut(action)) + self.play(FadeOut(square)) + + # equation for the whole + whole_group = MathTex( + r"G &= \langle \sigma, r \,|\," + r"\sigma^2 = r^4 = (\sigma r)^2 = 1 \rangle \\" + r"&= \left\{" + r"1, r, r^2, r^3, \sigma, \sigma r, \sigma r^2, \sigma r^3" + r"\right\}") + + self.play(ApplyMethod(group.move_to, ORIGIN)) + self.play(ReplacementTransform(group, whole_group)) + self.wait(2) + + dihedral = MathTex( + r"D_n &= \langle \sigma, r \,|\," + r"\sigma^2 = r^n = (\sigma r)^2 = 1 \rangle \\" + r"&= \left\{" + r"1, r, r^2, \dots, \sigma, \sigma r, \sigma r^2, \dots" + r"\right\}") + + dihedral_title = Tex(r"Diedergruppe: Symmetrien eines \(n\)-gons") + dihedral_title.next_to(dihedral, UP * 2) + + dihedral.scale(1.2) + dihedral_title.scale(1.2) + + self.play(ReplacementTransform(whole_group, dihedral)) + self.play(FadeInFrom(dihedral_title, UP)) + + self.wait(5) + self.play(FadeOut(dihedral), FadeOut(dihedral_title)) + + +class Geometric3DSymmetries(ThreeDScene): + def construct(self): + self.symmetric() + + def symmetric(self): + self.renderer.camera.light_source.move_to(3*IN) # changes the source of the light + self.set_camera_orientation(phi=60 * DEGREES, theta=-20 * DEGREES) + + cube = Cube() + axes = ThreeDAxes() + + axis = np.array([2,2,2]) + line = DashedLine(-axis, axis) + + self.play(Create(axes), Create(cube)) + self.play(Create(line)) + + self.play(ApplyMethod(cube.rotate, PI, axis / abs(axis))) + + self.begin_ambient_camera_rotation(rate=0.1) + self.wait(7) + + +class AlgebraicSymmetries(Scene): + def construct(self): + pass -- cgit v1.2.1 From 89aec59f070bcbf4ad32d274da73a19131f58a98 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Thu, 15 Apr 2021 09:53:59 +0200 Subject: Start animating algebraic symmetries --- vorlesungen/punktgruppen/crystals.py | 79 ++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 0f97a0f..d0ff205 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -135,8 +135,8 @@ class Geometric2DSymmetries(Scene): self.wait() cyclic = MathTex( - r"C_n = \langle r \rangle" - r"= \left\{1, r, r^2, \dots, r^n \right\}") + r"Z_n = \langle r \rangle" + r"= \left\{1, r, r^2, \dots, r^{n-1} \right\}") cyclic_title = Tex(r"Zyklische Gruppe") cyclic_title.next_to(cyclic, UP * 2) @@ -266,4 +266,77 @@ class Geometric3DSymmetries(ThreeDScene): class AlgebraicSymmetries(Scene): def construct(self): - pass + # title + title = Tex(r"Algebraische \\ Symmetrien") + title.scale(1.5) + self.play(Write(title)) + self.wait() + self.play(FadeOut(title)) + self.wait() + + self.cyclic() + + def cyclic(self): + root_powers = MathTex( + r"\left( e^\frac{\pi i}{2} \right)^0 &= 1 \\", + r"\left( e^\frac{\pi i}{2} \right)^1 &= i \\", + r"\left( e^\frac{\pi i}{2} \right)^2 &= -1 \\", + r"\left( e^\frac{\pi i}{2} \right)^3 &= -i \\") + + root_more_powers = MathTex( + r"\left( e^\frac{\pi i}{2} \right)^4 &= 1 \\", + r"\left( e^\frac{\pi i}{2} \right)^5 &= i \\", + r"\left( e^\frac{\pi i}{2} \right)^6 &= -1 \\", + r"\left( e^\frac{\pi i}{2} \right)^7 &= -i \\") + + root_powers.shift(LEFT * 2) + root_more_powers.shift(RIGHT * 2) + + for line in root_powers: + self.play(Write(line)) + + for line in root_more_powers: + self.play(Write(line)) + + self.wait() + self.play( + ApplyMethod(root_powers.to_edge, LEFT), + FadeOutAndShift(root_more_powers, RIGHT)) + + groups = MathTex( + r"G &= \left\{ 1, i, -1, -i \right\} \\", + r"&= \left\{", + "1,", "i,", "i^2,", "i^3", + r"\right\} \\", + r"Z_4 &= \left\{", + "1,", "r,", "r^2,", "r^3" + r"\right\}") + groups.shift(UP) + + self.play(Write(groups[0])) + self.play(FadeOutAndShift(root_powers, LEFT)) + for part in groups[0:]: + self.play(Write(part)) + self.play(ApplyMethod(groups.to_corner, UP + LEFT)) + self.wait() + + isomorphism = MathTex( + r"\varphi : G &\to Z_4 \\", + r"\mathrm{ker}(\varphi) &= \emptyset \\", + r"G &\cong Z_4") + + iso_it = iter(isomorphism) + self.play(Write(next(iso_it))) + self.wait() + self.play(Write(next(iso_it))) + self.wait() + + # TODO: show in group + + self.play(Write(next(iso_it))) + self.wait() + + self.play(ApplyMethod(isomorphism.to_edge, UP)) + + self.wait(5) + -- cgit v1.2.1 From 8a4d352a656972bf4b48d2b73733f15d9adf89fc Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Fri, 16 Apr 2021 01:02:19 +0200 Subject: Change symbol for identity element --- vorlesungen/punktgruppen/crystals.py | 92 ++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 25 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index d0ff205..894199d 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -2,6 +2,7 @@ from manim import * import math as m import numpy as np +import itertools as it # configure style config.background_color = '#202020' @@ -34,7 +35,7 @@ class Geometric2DSymmetries(Scene): self.wait() # the action of doing nothing - action = MathTex(r"1") + action = MathTex(r"\mathbb{1}") self.play(Write(action)) self.play(ApplyMethod(square.scale, 1.2)) self.play(ApplyMethod(square.scale, 1/1.2)) @@ -110,7 +111,10 @@ class Geometric2DSymmetries(Scene): self.wait() self.play(ApplyMethod(group.to_corner, UP)) - actions = map(MathTex, [r"1", r"r", r"r^2", r"r^3", r"r^4", r"1"]) + actions = map(MathTex, [ + r"\mathbb{1}", r"r", r"r^2", + r"r^3", r"r^4", r"\mathbb{1}"]) + action = next(actions, MathTex(r"r")) self.play(Create(figure)) @@ -128,7 +132,7 @@ class Geometric2DSymmetries(Scene): whole_group = MathTex( r"G = \langle r \rangle" - r"= \left\{1, r, r^2, r^3, r^4 \right\}") + r"= \left\{\mathbb{1}, r, r^2, r^3, r^4 \right\}") self.play(ApplyMethod(group.move_to, ORIGIN)) self.play(ReplacementTransform(group, whole_group)) @@ -136,7 +140,7 @@ class Geometric2DSymmetries(Scene): cyclic = MathTex( r"Z_n = \langle r \rangle" - r"= \left\{1, r, r^2, \dots, r^{n-1} \right\}") + r"= \left\{\mathbb{1}, r, r^2, \dots, r^{n-1} \right\}") cyclic_title = Tex(r"Zyklische Gruppe") cyclic_title.next_to(cyclic, UP * 2) @@ -158,9 +162,9 @@ class Geometric2DSymmetries(Scene): # generator equation group = MathTex( r"G = \langle \sigma, r \,|\,", - r"\sigma^2 = 1,", - r"r^4 = 1,", - r"(\sigma r)^2 = 1 \rangle") + r"\sigma^2 = \mathbb{1},", + r"r^4 = \mathbb{1},", + r"(\sigma r)^2 = \mathbb{1} \rangle") self.play(Write(group), run_time = 2) self.wait() @@ -168,7 +172,7 @@ class Geometric2DSymmetries(Scene): self.play(FadeIn(square)) axis = DashedLine(2 * LEFT, 2 * RIGHT) - sigma = MathTex(r"\sigma^2 = 1") + sigma = MathTex(r"\sigma^2 = \mathbb{1}") sigma.next_to(axis, RIGHT) self.play(Create(axis), Write(sigma)) self.play(ApplyMethod(square.flip, RIGHT)) @@ -177,7 +181,7 @@ class Geometric2DSymmetries(Scene): # rotations dot = Dot(UP + RIGHT) - rot = MathTex(r"r^4 = 1") + rot = MathTex(r"r^4 = \mathbb{1}") rot.next_to(square, DOWN * 3) figure = VGroup() @@ -190,7 +194,7 @@ class Geometric2DSymmetries(Scene): self.play(FadeOut(rot), Uncreate(dot)) # rotation and flip - action = MathTex(r"(\sigma r)^2 = 1") + action = MathTex(r"(\sigma r)^2 = \mathbb{1}") action.next_to(square, DOWN * 5) dot = Dot(UP + RIGHT) @@ -212,9 +216,9 @@ class Geometric2DSymmetries(Scene): # equation for the whole whole_group = MathTex( r"G &= \langle \sigma, r \,|\," - r"\sigma^2 = r^4 = (\sigma r)^2 = 1 \rangle \\" + r"\sigma^2 = r^4 = (\sigma r)^2 = \mathbb{1} \rangle \\" r"&= \left\{" - r"1, r, r^2, r^3, \sigma, \sigma r, \sigma r^2, \sigma r^3" + r"\mathbb{1}, r, r^2, r^3, \sigma, \sigma r, \sigma r^2, \sigma r^3" r"\right\}") self.play(ApplyMethod(group.move_to, ORIGIN)) @@ -223,9 +227,9 @@ class Geometric2DSymmetries(Scene): dihedral = MathTex( r"D_n &= \langle \sigma, r \,|\," - r"\sigma^2 = r^n = (\sigma r)^2 = 1 \rangle \\" + r"\sigma^2 = r^n = (\sigma r)^2 = \mathbb{1} \rangle \\" r"&= \left\{" - r"1, r, r^2, \dots, \sigma, \sigma r, \sigma r^2, \dots" + r"\mathbb{1}, r, r^2, \dots, \sigma, \sigma r, \sigma r^2, \dots" r"\right\}") dihedral_title = Tex(r"Diedergruppe: Symmetrien eines \(n\)-gons") @@ -245,22 +249,60 @@ class Geometric3DSymmetries(ThreeDScene): def construct(self): self.symmetric() + + @staticmethod + def get_cube(): + verts = np.array(list(it.product(*3 * [[-1, 1]]))) + edges = [ + (v1, v2) + for v1, v2 in it.combinations(verts, 2) + if sum(v1 == v2) == 2 + ] + corner_dots = Group(*[ + Sphere().set_height(0.25).move_to(vert) + for vert in verts + ]) + corner_dots.set_color(GREY_B) + edge_rods = Group(*[ + Line3D(v1, v2) + for v1, v2 in edges + ]) + + faces = Cube(square_resolution=(10, 10)) + faces.set_height(2) + faces.set_color(BLUE_E, 0.3) + # faces.add_updater(lambda m: m.sort(lambda p: np.dot(p, [np.sign(self.euler_angles[0]) * 0.2, -1, 0.2]))) + + cube = Group(corner_dots, edge_rods, faces) + cube.corner_dots = corner_dots + cube.edge_rods = edge_rods + cube.faces = faces + return cube + def symmetric(self): self.renderer.camera.light_source.move_to(3*IN) # changes the source of the light - self.set_camera_orientation(phi=60 * DEGREES, theta=-20 * DEGREES) + self.set_camera_orientation(phi=60 * DEGREES, theta=5 * DEGREES) cube = Cube() - axes = ThreeDAxes() - - axis = np.array([2,2,2]) - line = DashedLine(-axis, axis) - - self.play(Create(axes), Create(cube)) - self.play(Create(line)) - - self.play(ApplyMethod(cube.rotate, PI, axis / abs(axis))) + self.play(GrowFromCenter(cube)) + + axes = list( + map(lambda v: v / np.linalg.norm(v), + map(np.array, [ + [0, 0, 1], + [0, 1, 1], + [1, 1, 1], + ]) + )) + angles = [ PI, PI, PI * 2/3 ] + lines = list(map(lambda x: Line(-2 * x, 2 * x), axes)) + + camera_thetas = list(map(lambda x: x * DEGREES, [10, 100, 110])) + for axis, line, angle, camera_angle in zip(axes, lines, angles, camera_thetas): + self.move_camera(theta=camera_angle) + self.play(Create(line)) + self.play(Rotate(cube, angle, axis=axis, run_time=3)) - self.begin_ambient_camera_rotation(rate=0.1) self.wait(7) -- cgit v1.2.1 From 89ff85cc982caac0a32c8f871da362c1b6970f61 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Fri, 16 Apr 2021 03:56:47 +0200 Subject: Rewrite cyclic group algebraic symmetry video --- vorlesungen/punktgruppen/crystals.py | 165 +++++++++++++++++++++++++---------- 1 file changed, 118 insertions(+), 47 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 894199d..dd55bbe 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -109,7 +109,7 @@ class Geometric2DSymmetries(Scene): group = MathTex(r"G = \langle r \rangle") self.play(Write(group), run_time = 2) self.wait() - self.play(ApplyMethod(group.to_corner, UP)) + self.play(ApplyMethod(group.to_edge, UP)) actions = map(MathTex, [ r"\mathbb{1}", r"r", r"r^2", @@ -168,7 +168,7 @@ class Geometric2DSymmetries(Scene): self.play(Write(group), run_time = 2) self.wait() - self.play(ApplyMethod(group.to_corner, UP)) + self.play(ApplyMethod(group.to_edge, UP)) self.play(FadeIn(square)) axis = DashedLine(2 * LEFT, 2 * RIGHT) @@ -319,66 +319,137 @@ class AlgebraicSymmetries(Scene): self.cyclic() def cyclic(self): - root_powers = MathTex( - r"\left( e^\frac{\pi i}{2} \right)^0 &= 1 \\", - r"\left( e^\frac{\pi i}{2} \right)^1 &= i \\", - r"\left( e^\frac{\pi i}{2} \right)^2 &= -1 \\", - r"\left( e^\frac{\pi i}{2} \right)^3 &= -i \\") - - root_more_powers = MathTex( - r"\left( e^\frac{\pi i}{2} \right)^4 &= 1 \\", - r"\left( e^\frac{\pi i}{2} \right)^5 &= i \\", - r"\left( e^\frac{\pi i}{2} \right)^6 &= -1 \\", - r"\left( e^\frac{\pi i}{2} \right)^7 &= -i \\") + # show the i product + product = MathTex( + r"1", r"\cdot i &= i \\", + r"i \cdot i &= -1 \\", + r"-1 \cdot i &= -i \\", + r"-i \cdot i &= 1") + product.scale(1.5) + + for part in product: + self.play(Write(part)) - root_powers.shift(LEFT * 2) - root_more_powers.shift(RIGHT * 2) + self.wait() + self.play(ApplyMethod(product.scale, 1/1.5)) - for line in root_powers: - self.play(Write(line)) + # gather in group + group = MathTex(r"G = \left\{ 1, i, -1, -i \right\}") + self.play(ReplacementTransform(product, group)) + self.wait() - for line in root_more_powers: - self.play(Write(line)) + # show Z4 + grouppow = MathTex( + r"G &= \left\{ 1, i, i^2, i^3 \right\} \\", + r"Z_4 &= \left\{ \mathbb{1}, r, r^2, r^3 \right\}") + self.play(ReplacementTransform(group, grouppow[0])) + self.wait() + self.play(Write(grouppow[1])) + self.wait() + self.play(ApplyMethod(grouppow.to_edge, UP)) + + # define morphisms + morphism = MathTex(r"\phi: Z_4 \to G \\") + morphism.shift(UP) + self.play(Write(morphism)) + + # show an example + mappings = MathTex( + r"\phi(\mathbb{1}) &= 1 \\", + r"\phi(r) &= i \\", + r"\phi(r^2) &= i^2 \\", + r"\phi(r^3) &= i^3 \\") + mappings.next_to(morphism, DOWN) + + self.play(Write(mappings)) self.wait() + self.play(FadeOutAndShift(mappings, DOWN)) + + # more general definition + homomorphism = MathTex( + r"\phi(r\circ \mathbb{1}) &= i\cdot 1 \\", + r"&= \phi(r)\cdot\phi(\mathbb{1})") + homomorphism.next_to(morphism, DOWN).align_to(morphism, LEFT) + for part in homomorphism: + self.play(Write(part)) + + hom_bracegrp = VGroup() + hom_bracegrp.add(morphism) + hom_bracegrp.add(homomorphism) + self.play( - ApplyMethod(root_powers.to_edge, LEFT), - FadeOutAndShift(root_more_powers, RIGHT)) - - groups = MathTex( - r"G &= \left\{ 1, i, -1, -i \right\} \\", - r"&= \left\{", - "1,", "i,", "i^2,", "i^3", - r"\right\} \\", - r"Z_4 &= \left\{", - "1,", "r,", "r^2,", "r^3" - r"\right\}") - groups.shift(UP) + ApplyMethod(grouppow.shift, 2.5 * LEFT), + ApplyMethod(hom_bracegrp.shift, 2.5 * LEFT)) - self.play(Write(groups[0])) - self.play(FadeOutAndShift(root_powers, LEFT)) - for part in groups[0:]: - self.play(Write(part)) - self.play(ApplyMethod(groups.to_corner, UP + LEFT)) + hom_brace = Brace(hom_bracegrp, direction=RIGHT) + hom_text = Tex("Homomorphismus").next_to(hom_brace.get_tip(), RIGHT) + + self.play(Create(hom_brace)) + self.play(Write(hom_text)) self.wait() - isomorphism = MathTex( - r"\varphi : G &\to Z_4 \\", - r"\mathrm{ker}(\varphi) &= \emptyset \\", - r"G &\cong Z_4") + self.play(FadeOut(hom_brace), FadeOut(hom_text)) - iso_it = iter(isomorphism) - self.play(Write(next(iso_it))) + # add the isomorphism part + isomorphism = Tex(r"\(\phi\) ist bijektiv") + isomorphism.next_to(homomorphism, DOWN).align_to(homomorphism, LEFT) + self.play(Write(isomorphism)) + + iso_bracegrp = VGroup() + iso_bracegrp.add(hom_bracegrp) + iso_bracegrp.add(isomorphism) + + iso_brace = Brace(iso_bracegrp, RIGHT) + iso_text = Tex("Isomorphismus").next_to(iso_brace.get_tip(), RIGHT) + iso_text_short = MathTex("Z_4 \cong G").next_to(iso_brace.get_tip(), RIGHT) + + self.play(Create(iso_brace)) + self.play(Write(iso_text)) self.wait() - self.play(Write(next(iso_it))) + + self.play(ReplacementTransform(iso_text, iso_text_short)) self.wait() - # TODO: show in group + # create a group for the whole + morphgrp = VGroup() + morphgrp.add(iso_bracegrp) + morphgrp.add(iso_brace) + morphgrp.add(iso_text_short) + + self.play( + FadeOutAndShift(grouppow, UP), + FadeOutAndShift(morphgrp, DOWN)) + + # draw a complex plane + plane = ComplexPlane() + plane.axis_config["number_scale_val"] = 1 + self.play(Create(plane)) - self.play(Write(next(iso_it))) + roots = list(map(lambda p: Dot(p, fill_color=PINK), ( + [1, 0, 0], [0, 1, 0], [-1, 0, 0], [0, -1, 0] + ))) + + self.play( + *map(Create, roots), + *map(Write, plane.get_coordinate_labels(1, -1, 1j, -1j))) self.wait() - self.play(ApplyMethod(isomorphism.to_edge, UP)) + arrow = CurvedArrow( + 1.5 * np.array([m.cos(10 * DEGREES), m.sin(10 * DEGREES), 0]), + 1.5 * np.array([m.cos(80 * DEGREES), m.sin(80 * DEGREES), 0])) - self.wait(5) + arrowtext = MathTex("\cdot i") + arrowtext.move_to(2 / m.sqrt(2) * (UP + RIGHT)) + + square = Square().rotate(PI/4).scale(1/m.sqrt(2)) + square.set_fill(PINK).set_opacity(.4) + + self.play(FadeIn(square), Create(arrow), Write(arrowtext)) + + for _ in range(4): + self.play(Rotate(square, PI/2)) + self.wait(.5) + self.play(FadeOut(square), FadeOut(arrow), *map(FadeOut, roots)) + self.play(Uncreate(plane)) -- cgit v1.2.1 From 7191f61813d079d543242b5160a011a18b2bcd7b Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Fri, 16 Apr 2021 14:24:37 +0200 Subject: Fix complex plane animation --- vorlesungen/punktgruppen/crystals.py | 81 ++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 32 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index dd55bbe..76dee1f 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -66,9 +66,7 @@ class Geometric2DSymmetries(Scene): # show some rotations dot = Dot(UP + RIGHT) - figure = VGroup() - figure.add(square) - figure.add(dot) + figure = VGroup(square, dot) rot = MathTex(r"r") self.play(Write(rot), Create(dot)) @@ -184,9 +182,7 @@ class Geometric2DSymmetries(Scene): rot = MathTex(r"r^4 = \mathbb{1}") rot.next_to(square, DOWN * 3) - figure = VGroup() - figure.add(dot) - figure.add(square) + figure = VGroup(dot, square) self.play(Write(rot), Create(dot)) for i in range(4): @@ -201,9 +197,7 @@ class Geometric2DSymmetries(Scene): axis = DashedLine(2 * LEFT, 2 * RIGHT) self.play(Create(dot), Create(axis), Write(action)) - figure = VGroup() - figure.add(dot) - figure.add(square) + figure = VGroup(dot, square) for i in range(2): self.play(Rotate(figure, PI/2)) @@ -317,6 +311,7 @@ class AlgebraicSymmetries(Scene): self.wait() self.cyclic() + self.matrices() def cyclic(self): # show the i product @@ -374,9 +369,7 @@ class AlgebraicSymmetries(Scene): for part in homomorphism: self.play(Write(part)) - hom_bracegrp = VGroup() - hom_bracegrp.add(morphism) - hom_bracegrp.add(homomorphism) + hom_bracegrp = VGroup(morphism, homomorphism) self.play( ApplyMethod(grouppow.shift, 2.5 * LEFT), @@ -384,21 +377,21 @@ class AlgebraicSymmetries(Scene): hom_brace = Brace(hom_bracegrp, direction=RIGHT) hom_text = Tex("Homomorphismus").next_to(hom_brace.get_tip(), RIGHT) + hom_text_short = MathTex(r"G \simeq Z_4").next_to(hom_brace.get_tip(), RIGHT) self.play(Create(hom_brace)) self.play(Write(hom_text)) + self.play(ReplacementTransform(hom_text, hom_text_short)) self.wait() - self.play(FadeOut(hom_brace), FadeOut(hom_text)) + self.play(FadeOut(hom_brace), FadeOut(hom_text_short)) # add the isomorphism part isomorphism = Tex(r"\(\phi\) ist bijektiv") isomorphism.next_to(homomorphism, DOWN).align_to(homomorphism, LEFT) self.play(Write(isomorphism)) - iso_bracegrp = VGroup() - iso_bracegrp.add(hom_bracegrp) - iso_bracegrp.add(isomorphism) + iso_bracegrp = VGroup(hom_bracegrp, isomorphism) iso_brace = Brace(iso_bracegrp, RIGHT) iso_text = Tex("Isomorphismus").next_to(iso_brace.get_tip(), RIGHT) @@ -412,44 +405,68 @@ class AlgebraicSymmetries(Scene): self.wait() # create a group for the whole - morphgrp = VGroup() - morphgrp.add(iso_bracegrp) - morphgrp.add(iso_brace) - morphgrp.add(iso_text_short) + morphgrp = VGroup(iso_bracegrp, iso_brace, iso_text_short) self.play( - FadeOutAndShift(grouppow, UP), - FadeOutAndShift(morphgrp, DOWN)) + ApplyMethod(grouppow.to_edge, LEFT), + ApplyMethod(morphgrp.to_edge, LEFT)) + # self.play( + # FadeOutAndShift(grouppow, UP), + # FadeOutAndShift(morphgrp, DOWN)) # draw a complex plane - plane = ComplexPlane() - plane.axis_config["number_scale_val"] = 1 - self.play(Create(plane)) + plane = ComplexPlane(x_min = -2, x_max = 3) + coordinates = plane.get_coordinate_labels(1, -1, 1j, -1j) roots = list(map(lambda p: Dot(p, fill_color=PINK), ( [1, 0, 0], [0, 1, 0], [-1, 0, 0], [0, -1, 0] ))) - self.play( - *map(Create, roots), - *map(Write, plane.get_coordinate_labels(1, -1, 1j, -1j))) - self.wait() - arrow = CurvedArrow( 1.5 * np.array([m.cos(10 * DEGREES), m.sin(10 * DEGREES), 0]), 1.5 * np.array([m.cos(80 * DEGREES), m.sin(80 * DEGREES), 0])) - arrowtext = MathTex("\cdot i") arrowtext.move_to(2 / m.sqrt(2) * (UP + RIGHT)) square = Square().rotate(PI/4).scale(1/m.sqrt(2)) square.set_fill(PINK).set_opacity(.4) + figuregrp = Group(plane, square, arrow, arrowtext, *coordinates, *roots) + figuregrp.to_edge(RIGHT) + + self.play(Create(plane)) + self.play( + *map(Create, roots), + *map(Write, coordinates)) + self.wait() self.play(FadeIn(square), Create(arrow), Write(arrowtext)) for _ in range(4): self.play(Rotate(square, PI/2)) self.wait(.5) - self.play(FadeOut(square), FadeOut(arrow), *map(FadeOut, roots)) + self.play( + *map(FadeOut, (square, arrow, arrowtext)), + *map(FadeOut, coordinates), + *map(FadeOut, roots)) self.play(Uncreate(plane)) + self.play( + FadeOutAndShift(grouppow, RIGHT), + FadeOutAndShift(morphgrp, RIGHT)) + + modulo = MathTex( + r"\phi: Z_4 &\to (\mathbb{Z}/4\mathbb{Z}, +) \\" + r"\phi(\mathbb{1} \circ r^2) &= 0 + 2 \pmod 4").scale(1.5) + self.play(Write(modulo)) + self.wait(2) + + self.play(FadeOut(modulo)) + self.wait(3) + + def matrices(self): + question = MathTex(r"D_n \cong \,? \\ S_n \cong \,? \\ A_n \cong \,?") + question.scale(1.5) + + self.play(Write(question)) + + self.wait(3) -- cgit v1.2.1 From 4c2a0d4d394dbb85222f480d271aa2171f0f201c Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Fri, 23 Apr 2021 20:18:45 +0200 Subject: Change brace animation --- vorlesungen/punktgruppen/crystals.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 76dee1f..136481b 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -377,14 +377,14 @@ class AlgebraicSymmetries(Scene): hom_brace = Brace(hom_bracegrp, direction=RIGHT) hom_text = Tex("Homomorphismus").next_to(hom_brace.get_tip(), RIGHT) - hom_text_short = MathTex(r"G \simeq Z_4").next_to(hom_brace.get_tip(), RIGHT) + hom_text_short = MathTex(r"\mathrm{Hom}(G, Z_4)").next_to(hom_brace.get_tip(), RIGHT) self.play(Create(hom_brace)) self.play(Write(hom_text)) self.play(ReplacementTransform(hom_text, hom_text_short)) self.wait() - self.play(FadeOut(hom_brace), FadeOut(hom_text_short)) + # self.play(FadeOut(hom_brace), FadeOut(hom_text_short)) # add the isomorphism part isomorphism = Tex(r"\(\phi\) ist bijektiv") @@ -397,8 +397,9 @@ class AlgebraicSymmetries(Scene): iso_text = Tex("Isomorphismus").next_to(iso_brace.get_tip(), RIGHT) iso_text_short = MathTex("Z_4 \cong G").next_to(iso_brace.get_tip(), RIGHT) - self.play(Create(iso_brace)) - self.play(Write(iso_text)) + self.play( + ReplacementTransform(hom_brace, iso_brace), + ReplacementTransform(hom_text_short, iso_text)) self.wait() self.play(ReplacementTransform(iso_text, iso_text_short)) @@ -464,9 +465,18 @@ class AlgebraicSymmetries(Scene): self.wait(3) def matrices(self): - question = MathTex(r"D_n \cong \,? \\ S_n \cong \,? \\ A_n \cong \,?") - question.scale(1.5) + question = MathTex( + r"D_n &\cong \,? \\" + r"S_n &\cong \,? \\" + r"A_n &\cong \,?").scale(1.5) + + answer = MathTex( + r"D_n &\cong \,?\\" + r"S_4 &\cong \mathrm{Aut}(Q_8) \\" + r"A_5 &\cong \mathrm{PSL}_2 (5)").scale(1.5) self.play(Write(question)) + self.wait() + self.play(ReplacementTransform(question, answer)) self.wait(3) -- cgit v1.2.1 From f5c4eff1d1d77b0d7a805e873ff24753e7fc84f2 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sat, 1 May 2021 21:43:50 +0200 Subject: Remove title from GeometriSymmetries scene and add circle group --- vorlesungen/punktgruppen/crystals.py | 44 +++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 136481b..70e1f89 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -16,16 +16,10 @@ config.tex_template.add_to_preamble( class Geometric2DSymmetries(Scene): def construct(self): # title - title = Tex(r"Geometrische \\ Symmetrien") - title.scale(1.5) - self.play(Write(title)) - self.wait() - self.play(FadeOut(title)) - self.wait() - self.intro() self.cyclic() self.dihedral() + self.circle() def intro(self): # create square @@ -114,7 +108,7 @@ class Geometric2DSymmetries(Scene): r"r^3", r"r^4", r"\mathbb{1}"]) action = next(actions, MathTex(r"r")) - + self.play(Create(figure)) self.play(Write(action)) self.wait() @@ -238,6 +232,40 @@ class Geometric2DSymmetries(Scene): self.wait(5) self.play(FadeOut(dihedral), FadeOut(dihedral_title)) + def circle(self): + circle = Circle(radius=2) + dot = Dot() + dot.move_to(2 * RIGHT) + + figure = VGroup(circle, dot) + group_name = MathTex(r"S^1") + + # create circle + self.play(Create(circle)) + self.play(Create(dot)) + + # move it around + self.play(Rotate(figure, PI/3)) + self.play(Rotate(figure, PI/6)) + self.play(Rotate(figure, -PI/3)) + + # show name + self.play(Rotate(figure, PI/4), Write(group_name)) + self.play(Uncreate(figure)) + + nsphere = MathTex(r"S^1 = \left\{z \in \mathbb{C} : |z| = 1\right\}") + nsphere_title = Tex(r"Kreisgruppe") + nsphere_title.next_to(nsphere, 2 * UP) + + nsphere.scale(1.2) + nsphere_title.scale(1.2) + + self.play(ReplacementTransform(group_name, nsphere)) + self.play(FadeInFrom(nsphere_title, UP)) + + self.wait(5) + self.play(FadeOut(nsphere_title), FadeOut(nsphere)) + class Geometric3DSymmetries(ThreeDScene): def construct(self): -- cgit v1.2.1 From 981b0e6a7e490d275e193a53b5ff224ec73e6b21 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sun, 2 May 2021 01:04:33 +0200 Subject: Create 3D scene for axial groups --- vorlesungen/punktgruppen/crystals.py | 171 +++++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 66 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 70e1f89..cbae3d0 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -15,7 +15,6 @@ config.tex_template.add_to_preamble( # scenes class Geometric2DSymmetries(Scene): def construct(self): - # title self.intro() self.cyclic() self.dihedral() @@ -269,75 +268,115 @@ class Geometric2DSymmetries(Scene): class Geometric3DSymmetries(ThreeDScene): def construct(self): - self.symmetric() - - - @staticmethod - def get_cube(): - verts = np.array(list(it.product(*3 * [[-1, 1]]))) - edges = [ - (v1, v2) - for v1, v2 in it.combinations(verts, 2) - if sum(v1 == v2) == 2 - ] - corner_dots = Group(*[ - Sphere().set_height(0.25).move_to(vert) - for vert in verts - ]) - corner_dots.set_color(GREY_B) - edge_rods = Group(*[ - Line3D(v1, v2) - for v1, v2 in edges - ]) - - faces = Cube(square_resolution=(10, 10)) - faces.set_height(2) - faces.set_color(BLUE_E, 0.3) - # faces.add_updater(lambda m: m.sort(lambda p: np.dot(p, [np.sign(self.euler_angles[0]) * 0.2, -1, 0.2]))) - - cube = Group(corner_dots, edge_rods, faces) - cube.corner_dots = corner_dots - cube.edge_rods = edge_rods - cube.faces = faces - return cube - - def symmetric(self): - self.renderer.camera.light_source.move_to(3*IN) # changes the source of the light - self.set_camera_orientation(phi=60 * DEGREES, theta=5 * DEGREES) - - cube = Cube() - self.play(GrowFromCenter(cube)) - - axes = list( - map(lambda v: v / np.linalg.norm(v), - map(np.array, [ - [0, 0, 1], - [0, 1, 1], - [1, 1, 1], - ]) - )) - angles = [ PI, PI, PI * 2/3 ] - lines = list(map(lambda x: Line(-2 * x, 2 * x), axes)) - - camera_thetas = list(map(lambda x: x * DEGREES, [10, 100, 110])) - for axis, line, angle, camera_angle in zip(axes, lines, angles, camera_thetas): - self.move_camera(theta=camera_angle) - self.play(Create(line)) - self.play(Rotate(cube, angle, axis=axis, run_time=3)) - - self.wait(7) + self.improper_rotation() + def improper_rotation(self): + # changes the source of the light and camera + self.renderer.camera.light_source.move_to(3*IN) + self.set_camera_orientation(phi=0, theta=0) -class AlgebraicSymmetries(Scene): - def construct(self): - # title - title = Tex(r"Algebraische \\ Symmetrien") - title.scale(1.5) - self.play(Write(title)) + # initial square + square = Square() + square.set_fill(PINK, opacity=.5) + + self.play(Create(square)) + self.wait() + + self.play(Rotate(square, PI/2)) + self.wait() + + self.move_camera(phi= 75 * DEGREES, theta = -80 * DEGREES) + + # create sphere from slices + cyclic_slices = [] + for i in range(4): + colors = [PINK, RED] if i % 2 == 0 else [BLUE_D, BLUE_E] + cyclic_slices.append(ParametricSurface( + lambda u, v: np.array([ + np.sqrt(2) * np.cos(u) * np.cos(v), + np.sqrt(2) * np.cos(u) * np.sin(v), + np.sqrt(2) * np.sin(u) + ]), + v_min=PI/4 + PI/2 * i, + v_max=PI/4 + PI/2 * (i + 1), + u_min=-PI/2, u_max=PI/2, + checkerboard_colors=colors, resolution=(10,5))) + + self.play(FadeOut(square), *map(Create, cyclic_slices)) + + axis = Line3D(start=[0,0,-2.5], end=[0,0,2.5]) + + axis_name = MathTex(r"r \in Z_4") + # move to yz plane + axis_name.rotate(PI/2, axis = RIGHT) + axis_name.next_to(axis, OUT) + + self.play(Create(axis)) + self.play(Write(axis_name)) + self.wait() + + cyclic_sphere = VGroup(*cyclic_slices) + self.play(Rotate(cyclic_sphere, PI/2)) self.wait() - self.play(FadeOut(title)) + + # reflection plane + self.play(FadeOut(cyclic_sphere), FadeIn(square)) + plane = ParametricSurface( + lambda u, v: np.array([u, 0, v]), + u_min = -2, u_max = 2, + v_min = -2, v_max = 2, + fill_opacity=.3, resolution=(1,1)) + + plane_name = MathTex(r"\sigma \in D_4") + # move to yz plane + plane_name.rotate(PI/2, axis = RIGHT) + plane_name.next_to(plane, OUT + RIGHT) + + self.play(Create(plane)) + self.play(Write(plane_name)) self.wait() + self.move_camera(phi = 25 * DEGREES, theta = -75 * DEGREES) + + self.play(Rotate(square, PI/2)) + self.play(Rotate(square, PI, RIGHT)) + + self.play(Rotate(square, PI/2)) + self.play(Rotate(square, PI, RIGHT)) + + self.move_camera(phi = 75 * DEGREES, theta = -80 * DEGREES) + + # create sphere from slices + dihedral_slices = [] + for i in range(4): + for j in range(2): + colors = [PINK, RED] if i % 2 == 0 else [BLUE_D, BLUE_E] + dihedral_slices.append(ParametricSurface( + lambda u, v: np.array([ + np.sqrt(2) * np.cos(u) * np.cos(v), + np.sqrt(2) * np.cos(u) * np.sin(v), + np.sqrt(2) * np.sin(u) + ]), + v_min=PI/2 * j + PI/4 + PI/2 * i, + v_max=PI/2 * j + PI/4 + PI/2 * (i + 1), + u_min=-PI/2 if j == 0 else 0, + u_max=0 if j == 0 else PI/2, + checkerboard_colors=colors, resolution=(10,5))) + + dihedral_sphere = VGroup(*dihedral_slices) + + self.play(FadeOut(square), Create(dihedral_sphere)) + + self.play(Rotate(dihedral_sphere, PI/2)) + self.play(Rotate(dihedral_sphere, PI, RIGHT)) + + self.play(Rotate(dihedral_sphere, PI/2)) + self.play(Rotate(dihedral_sphere, PI, RIGHT)) + + self.wait(5) + +class AlgebraicSymmetries(Scene): + def construct(self): self.cyclic() self.matrices() @@ -349,7 +388,7 @@ class AlgebraicSymmetries(Scene): r"-1 \cdot i &= -i \\", r"-i \cdot i &= 1") product.scale(1.5) - + for part in product: self.play(Write(part)) -- cgit v1.2.1 From 28d897afbf98b5988a25a9067984e4cc165e0fcc Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Mon, 3 May 2021 23:09:27 +0200 Subject: Use schoenflies notation --- vorlesungen/punktgruppen/crystals.py | 72 +++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 34 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index cbae3d0..7eef9b8 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -130,7 +130,7 @@ class Geometric2DSymmetries(Scene): self.wait() cyclic = MathTex( - r"Z_n = \langle r \rangle" + r"C_n = \langle r \rangle" r"= \left\{\mathbb{1}, r, r^2, \dots, r^{n-1} \right\}") cyclic_title = Tex(r"Zyklische Gruppe") @@ -237,7 +237,7 @@ class Geometric2DSymmetries(Scene): dot.move_to(2 * RIGHT) figure = VGroup(circle, dot) - group_name = MathTex(r"S^1") + group_name = MathTex(r"C_\infty") # create circle self.play(Create(circle)) @@ -252,7 +252,7 @@ class Geometric2DSymmetries(Scene): self.play(Rotate(figure, PI/4), Write(group_name)) self.play(Uncreate(figure)) - nsphere = MathTex(r"S^1 = \left\{z \in \mathbb{C} : |z| = 1\right\}") + nsphere = MathTex(r"C_\infty \cong S^1 = \left\{z \in \mathbb{C} : |z| = 1\right\}") nsphere_title = Tex(r"Kreisgruppe") nsphere_title.next_to(nsphere, 2 * UP) @@ -269,6 +269,7 @@ class Geometric2DSymmetries(Scene): class Geometric3DSymmetries(ThreeDScene): def construct(self): self.improper_rotation() + self.icosahedron() def improper_rotation(self): # changes the source of the light and camera @@ -279,11 +280,12 @@ class Geometric3DSymmetries(ThreeDScene): square = Square() square.set_fill(PINK, opacity=.5) - self.play(Create(square)) - self.wait() + self.play(SpinInFromNothing(square)) + self.wait(2) - self.play(Rotate(square, PI/2)) - self.wait() + for i in range(4): + self.play(Rotate(square, PI/2)) + self.wait(.5) self.move_camera(phi= 75 * DEGREES, theta = -80 * DEGREES) @@ -306,7 +308,7 @@ class Geometric3DSymmetries(ThreeDScene): axis = Line3D(start=[0,0,-2.5], end=[0,0,2.5]) - axis_name = MathTex(r"r \in Z_4") + axis_name = MathTex(r"r \in C_4") # move to yz plane axis_name.rotate(PI/2, axis = RIGHT) axis_name.next_to(axis, OUT) @@ -316,8 +318,9 @@ class Geometric3DSymmetries(ThreeDScene): self.wait() cyclic_sphere = VGroup(*cyclic_slices) - self.play(Rotate(cyclic_sphere, PI/2)) - self.wait() + for i in range(4): + self.play(Rotate(cyclic_sphere, PI/2)) + self.wait() # reflection plane self.play(FadeOut(cyclic_sphere), FadeIn(square)) @@ -367,18 +370,21 @@ class Geometric3DSymmetries(ThreeDScene): self.play(FadeOut(square), Create(dihedral_sphere)) - self.play(Rotate(dihedral_sphere, PI/2)) - self.play(Rotate(dihedral_sphere, PI, RIGHT)) - - self.play(Rotate(dihedral_sphere, PI/2)) - self.play(Rotate(dihedral_sphere, PI, RIGHT)) + for i in range(2): + self.play(Rotate(dihedral_sphere, PI/2)) + self.play(Rotate(dihedral_sphere, PI, RIGHT)) + self.wait() self.wait(5) + def icosahedron(self): + pass + + class AlgebraicSymmetries(Scene): def construct(self): self.cyclic() - self.matrices() + # self.matrices() def cyclic(self): # show the i product @@ -391,30 +397,31 @@ class AlgebraicSymmetries(Scene): for part in product: self.play(Write(part)) + self.wait() - self.wait() self.play(ApplyMethod(product.scale, 1/1.5)) # gather in group group = MathTex(r"G = \left\{ 1, i, -1, -i \right\}") self.play(ReplacementTransform(product, group)) - self.wait() + self.wait(2) # show Z4 grouppow = MathTex( r"G &= \left\{ 1, i, i^2, i^3 \right\} \\", - r"Z_4 &= \left\{ \mathbb{1}, r, r^2, r^3 \right\}") + r"C_4 &= \left\{ \mathbb{1}, r, r^2, r^3 \right\}") self.play(ReplacementTransform(group, grouppow[0])) - self.wait() + self.wait(2) self.play(Write(grouppow[1])) self.wait() self.play(ApplyMethod(grouppow.to_edge, UP)) # define morphisms - morphism = MathTex(r"\phi: Z_4 \to G \\") + morphism = MathTex(r"\phi: C_4 \to G \\") morphism.shift(UP) self.play(Write(morphism)) + self.wait() # show an example mappings = MathTex( @@ -425,34 +432,34 @@ class AlgebraicSymmetries(Scene): mappings.next_to(morphism, DOWN) self.play(Write(mappings)) - self.wait() + self.wait(3) self.play(FadeOutAndShift(mappings, DOWN)) # more general definition homomorphism = MathTex( - r"\phi(r\circ \mathbb{1}) &= i\cdot 1 \\", - r"&= \phi(r)\cdot\phi(\mathbb{1})") + r"\phi(r\circ \mathbb{1}) &= \phi(r)\cdot\phi(\mathbb{1}) \\", + r"&= i\cdot 1") homomorphism.next_to(morphism, DOWN).align_to(morphism, LEFT) for part in homomorphism: self.play(Write(part)) + self.wait() hom_bracegrp = VGroup(morphism, homomorphism) self.play( - ApplyMethod(grouppow.shift, 2.5 * LEFT), - ApplyMethod(hom_bracegrp.shift, 2.5 * LEFT)) + ApplyMethod(grouppow.shift, 3 * LEFT), + ApplyMethod(hom_bracegrp.shift, 3 * LEFT)) hom_brace = Brace(hom_bracegrp, direction=RIGHT) hom_text = Tex("Homomorphismus").next_to(hom_brace.get_tip(), RIGHT) - hom_text_short = MathTex(r"\mathrm{Hom}(G, Z_4)").next_to(hom_brace.get_tip(), RIGHT) + hom_text_short = MathTex(r"\mathrm{Hom}(C_4, G)").next_to(hom_brace.get_tip(), RIGHT) self.play(Create(hom_brace)) self.play(Write(hom_text)) + self.wait() self.play(ReplacementTransform(hom_text, hom_text_short)) self.wait() - # self.play(FadeOut(hom_brace), FadeOut(hom_text_short)) - # add the isomorphism part isomorphism = Tex(r"\(\phi\) ist bijektiv") isomorphism.next_to(homomorphism, DOWN).align_to(homomorphism, LEFT) @@ -462,7 +469,7 @@ class AlgebraicSymmetries(Scene): iso_brace = Brace(iso_bracegrp, RIGHT) iso_text = Tex("Isomorphismus").next_to(iso_brace.get_tip(), RIGHT) - iso_text_short = MathTex("Z_4 \cong G").next_to(iso_brace.get_tip(), RIGHT) + iso_text_short = MathTex("C_4 \cong G").next_to(iso_brace.get_tip(), RIGHT) self.play( ReplacementTransform(hom_brace, iso_brace), @@ -478,9 +485,6 @@ class AlgebraicSymmetries(Scene): self.play( ApplyMethod(grouppow.to_edge, LEFT), ApplyMethod(morphgrp.to_edge, LEFT)) - # self.play( - # FadeOutAndShift(grouppow, UP), - # FadeOutAndShift(morphgrp, DOWN)) # draw a complex plane plane = ComplexPlane(x_min = -2, x_max = 3) @@ -523,7 +527,7 @@ class AlgebraicSymmetries(Scene): FadeOutAndShift(morphgrp, RIGHT)) modulo = MathTex( - r"\phi: Z_4 &\to (\mathbb{Z}/4\mathbb{Z}, +) \\" + r"\phi: C_4 &\to (\mathbb{Z}/4\mathbb{Z}, +) \\" r"\phi(\mathbb{1} \circ r^2) &= 0 + 2 \pmod 4").scale(1.5) self.play(Write(modulo)) self.wait(2) -- cgit v1.2.1 From 6c50dd1aff137beaadca5e46913355d80d3cda3b Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Wed, 5 May 2021 23:09:33 +0200 Subject: Update manim to v0.6.0 --- vorlesungen/punktgruppen/crystals.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index 7eef9b8..b29d7e4 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -487,7 +487,7 @@ class AlgebraicSymmetries(Scene): ApplyMethod(morphgrp.to_edge, LEFT)) # draw a complex plane - plane = ComplexPlane(x_min = -2, x_max = 3) + plane = ComplexPlane(x_range = [-2.5, 2.5]) coordinates = plane.get_coordinate_labels(1, -1, 1j, -1j) roots = list(map(lambda p: Dot(p, fill_color=PINK), ( @@ -503,7 +503,7 @@ class AlgebraicSymmetries(Scene): square = Square().rotate(PI/4).scale(1/m.sqrt(2)) square.set_fill(PINK).set_opacity(.4) - figuregrp = Group(plane, square, arrow, arrowtext, *coordinates, *roots) + figuregrp = VGroup(plane, square, arrow, arrowtext, *coordinates, *roots) figuregrp.to_edge(RIGHT) self.play(Create(plane)) -- cgit v1.2.1 From 28f34a14fce246946b1e0a7d5de3b095c92e342d Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Mon, 10 May 2021 13:17:41 +0200 Subject: Update animation script --- vorlesungen/punktgruppen/crystals.py | 114 ++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 28 deletions(-) (limited to 'vorlesungen/punktgruppen/crystals.py') diff --git a/vorlesungen/punktgruppen/crystals.py b/vorlesungen/punktgruppen/crystals.py index b29d7e4..4a9836a 100644 --- a/vorlesungen/punktgruppen/crystals.py +++ b/vorlesungen/punktgruppen/crystals.py @@ -15,6 +15,8 @@ config.tex_template.add_to_preamble( # scenes class Geometric2DSymmetries(Scene): def construct(self): + self.wait(5) + self.intro() self.cyclic() self.dihedral() @@ -33,6 +35,7 @@ class Geometric2DSymmetries(Scene): self.play(ApplyMethod(square.scale, 1.2)) self.play(ApplyMethod(square.scale, 1/1.2)) self.play(FadeOut(action)) + self.wait() # show some reflections axis = DashedLine(2 * LEFT, 2 * RIGHT) @@ -41,9 +44,7 @@ class Geometric2DSymmetries(Scene): self.play(Create(axis)) self.play(Write(sigma)) - self.play(ApplyMethod(square.flip, RIGHT)) - self.wait() for d in [UP + RIGHT, UP]: self.play( @@ -53,9 +54,7 @@ class Geometric2DSymmetries(Scene): self.play(Rotate(sigma, -PI/4), run_time=.5) self.play(ApplyMethod(square.flip, d)) - self.play( - FadeOutAndShift(sigma), - Uncreate(axis)) + self.play(FadeOutAndShift(sigma), Uncreate(axis)) # show some rotations dot = Dot(UP + RIGHT) @@ -69,7 +68,7 @@ class Geometric2DSymmetries(Scene): self.play( ReplacementTransform(last, newrot), Rotate(figure, PI/2, about_point=ORIGIN)) - self.wait() + self.wait(.5) last = newrot self.play(Uncreate(dot), FadeOut(square), FadeOut(last)) @@ -99,12 +98,13 @@ class Geometric2DSymmetries(Scene): group = MathTex(r"G = \langle r \rangle") self.play(Write(group), run_time = 2) - self.wait() + self.wait(3) + self.play(ApplyMethod(group.to_edge, UP)) actions = map(MathTex, [ r"\mathbb{1}", r"r", r"r^2", - r"r^3", r"r^4", r"\mathbb{1}"]) + r"r^3", r"r^4", r"\mathbb{1}", r"r"]) action = next(actions, MathTex(r"r")) @@ -119,6 +119,14 @@ class Geometric2DSymmetries(Scene): Rotate(figure, 2*PI/5, about_point=ORIGIN)) action = newaction + self.wait() + newaction = next(actions, MathTex(r"r")) + self.play( + ReplacementTransform(action, newaction), + Rotate(figure, 2*PI/5, about_point=ORIGIN)) + action = newaction + self.wait(2) + self.play(Uncreate(figure), FadeOut(action)) whole_group = MathTex( @@ -127,7 +135,7 @@ class Geometric2DSymmetries(Scene): self.play(ApplyMethod(group.move_to, ORIGIN)) self.play(ReplacementTransform(group, whole_group)) - self.wait() + self.wait(5) cyclic = MathTex( r"C_n = \langle r \rangle" @@ -158,10 +166,13 @@ class Geometric2DSymmetries(Scene): r"(\sigma r)^2 = \mathbb{1} \rangle") self.play(Write(group), run_time = 2) - self.wait() + self.wait(5) + self.play(ApplyMethod(group.to_edge, UP)) self.play(FadeIn(square)) + self.wait() + # flips axis = DashedLine(2 * LEFT, 2 * RIGHT) sigma = MathTex(r"\sigma^2 = \mathbb{1}") sigma.next_to(axis, RIGHT) @@ -250,6 +261,7 @@ class Geometric2DSymmetries(Scene): # show name self.play(Rotate(figure, PI/4), Write(group_name)) + self.wait() self.play(Uncreate(figure)) nsphere = MathTex(r"C_\infty \cong S^1 = \left\{z \in \mathbb{C} : |z| = 1\right\}") @@ -264,12 +276,13 @@ class Geometric2DSymmetries(Scene): self.wait(5) self.play(FadeOut(nsphere_title), FadeOut(nsphere)) + self.wait(2) class Geometric3DSymmetries(ThreeDScene): def construct(self): self.improper_rotation() - self.icosahedron() + self.tetrahedron() def improper_rotation(self): # changes the source of the light and camera @@ -289,6 +302,18 @@ class Geometric3DSymmetries(ThreeDScene): self.move_camera(phi= 75 * DEGREES, theta = -80 * DEGREES) + # create rotation axis + axis = Line3D(start=[0,0,-2.5], end=[0,0,2.5]) + + axis_name = MathTex(r"r \in C_4") + # move to yz plane + axis_name.rotate(PI/2, axis = RIGHT) + axis_name.next_to(axis, OUT) + + self.play(Create(axis)) + self.play(Write(axis_name)) + self.wait() + # create sphere from slices cyclic_slices = [] for i in range(4): @@ -306,22 +331,17 @@ class Geometric3DSymmetries(ThreeDScene): self.play(FadeOut(square), *map(Create, cyclic_slices)) - axis = Line3D(start=[0,0,-2.5], end=[0,0,2.5]) - - axis_name = MathTex(r"r \in C_4") - # move to yz plane - axis_name.rotate(PI/2, axis = RIGHT) - axis_name.next_to(axis, OUT) - - self.play(Create(axis)) - self.play(Write(axis_name)) - self.wait() - cyclic_sphere = VGroup(*cyclic_slices) for i in range(4): self.play(Rotate(cyclic_sphere, PI/2)) self.wait() + new_axis_name = MathTex(r"r \in D_4") + # move to yz plane + new_axis_name.rotate(PI/2, axis = RIGHT) + new_axis_name.next_to(axis, OUT) + self.play(ReplacementTransform(axis_name, new_axis_name)) + # reflection plane self.play(FadeOut(cyclic_sphere), FadeIn(square)) plane = ParametricSurface( @@ -340,12 +360,18 @@ class Geometric3DSymmetries(ThreeDScene): self.wait() self.move_camera(phi = 25 * DEGREES, theta = -75 * DEGREES) + self.wait() + condition = MathTex(r"(\sigma r)^2 = \mathbb{1}") + condition.next_to(square, DOWN); + + self.play(Write(condition)) self.play(Rotate(square, PI/2)) self.play(Rotate(square, PI, RIGHT)) self.play(Rotate(square, PI/2)) self.play(Rotate(square, PI, RIGHT)) + self.play(FadeOut(condition)) self.move_camera(phi = 75 * DEGREES, theta = -80 * DEGREES) @@ -375,14 +401,45 @@ class Geometric3DSymmetries(ThreeDScene): self.play(Rotate(dihedral_sphere, PI, RIGHT)) self.wait() - self.wait(5) + self.wait(2) + self.play(*map(FadeOut, [dihedral_sphere, plane, plane_name, new_axis_name]), FadeIn(square)) + self.wait(3) + self.play(*map(FadeOut, [square, axis])) + self.wait(3) + + def tetrahedron(self): + tet = Tetrahedron(edge_length=2) + self.play(FadeIn(tet)) + + self.move_camera(phi = 75 * DEGREES, theta = -100 * DEGREES) + self.begin_ambient_camera_rotation(rate=.1) + + axes = [] + for coord in tet.vertex_coords: + axes.append((-2 * coord, 2 * coord)) + + lines = [ + Line3D(start=s, end=e) for s, e in axes + ] - def icosahedron(self): - pass + self.play(*map(Create, lines)) + self.wait() + + for axis in axes: + self.play(Rotate(tet, 2*PI/3, axis=axis[1])) + self.play(Rotate(tet, 2*PI/3, axis=axis[1])) + + self.wait(5) + self.stop_ambient_camera_rotation() + self.wait() + self.play(*map(Uncreate, lines)) + self.play(FadeOut(tet)) + self.wait(5) class AlgebraicSymmetries(Scene): def construct(self): + self.wait(5) self.cyclic() # self.matrices() @@ -406,7 +463,7 @@ class AlgebraicSymmetries(Scene): self.play(ReplacementTransform(product, group)) self.wait(2) - # show Z4 + # show C4 grouppow = MathTex( r"G &= \left\{ 1, i, i^2, i^3 \right\} \\", r"C_4 &= \left\{ \mathbb{1}, r, r^2, r^3 \right\}") @@ -414,7 +471,8 @@ class AlgebraicSymmetries(Scene): self.wait(2) self.play(Write(grouppow[1])) - self.wait() + self.wait(4) + self.play(ApplyMethod(grouppow.to_edge, UP)) # define morphisms @@ -429,7 +487,7 @@ class AlgebraicSymmetries(Scene): r"\phi(r) &= i \\", r"\phi(r^2) &= i^2 \\", r"\phi(r^3) &= i^3 \\") - mappings.next_to(morphism, DOWN) + mappings.next_to(morphism, 2 * DOWN) self.play(Write(mappings)) self.wait(3) -- cgit v1.2.1