├── img ├── A.png ├── B.png ├── C.png ├── D.png ├── E.png ├── F.png ├── bottom_banner.png └── wooden-crate.svg ├── index.md ├── _config.yml ├── myprojects ├── media │ ├── book_cover.png │ ├── lyricvideo.png │ ├── EffectExamples.gif │ └── exponential_sum.gif ├── README.md ├── _config.yml ├── __pycache__ │ ├── ball.cpython-37.pyc │ ├── song.cpython-37.pyc │ ├── testdice.cpython-37.pyc │ ├── testthai.cpython-37.pyc │ ├── cool_effect.cpython-37.pyc │ ├── perf_scenes.cpython-37.pyc │ ├── puzzle_clip.cpython-37.pyc │ ├── test_graph.cpython-37.pyc │ ├── test_polar.cpython-37.pyc │ ├── two_circles.cpython-37.pyc │ ├── circle_formula.cpython-37.pyc │ ├── example_scenes.cpython-37.pyc │ ├── mysterious_box.cpython-37.pyc │ └── polynomial_arithematic.cpython-37.pyc ├── farey_fractions │ ├── __pycache__ │ │ └── intro.cpython-37.pyc │ └── intro.py ├── tabletop_encyclopedia │ ├── __pycache__ │ │ └── overall.cpython-37.pyc │ ├── README.md │ └── overall.py ├── polynomial_arithematics │ ├── __pycache__ │ │ ├── polynomial_addition.cpython-37.pyc │ │ └── polynomial_multiplication.cpython-37.pyc │ ├── polynomial_addition.py │ ├── polynomial_multiplication.py │ ├── polynomial_division.py │ └── polynomial_subtract.py ├── for_fun │ ├── stream_opening.py │ ├── testthai.py │ ├── mysterious_box.py │ ├── Koch_Snowflake.py │ ├── testjap.py │ ├── puzzle_clip.py │ └── song.py ├── test_polar.py ├── index.md ├── testdice.py ├── exponential_sum.py ├── test │ ├── ball.py │ └── cool_effect.py ├── trig │ ├── formula_angle_sum.py │ └── two_circles.py ├── test_graph2.py ├── test_graph.py └── cal │ ├── diff_eq.py │ ├── sinx_x.py │ ├── circle_formula.py │ └── derivative_basic_properties.py ├── .gitignore ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md └── myconstructs └── randomizer.py /img/A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/A.png -------------------------------------------------------------------------------- /img/B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/B.png -------------------------------------------------------------------------------- /img/C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/C.png -------------------------------------------------------------------------------- /img/D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/D.png -------------------------------------------------------------------------------- /img/E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/E.png -------------------------------------------------------------------------------- /img/F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/F.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | Nothing to see here.... 2 | 3 | Go to [myprojects](myprojects) -------------------------------------------------------------------------------- /img/bottom_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/img/bottom_banner.png -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | title: lemononmars's Manim collection 3 | description: Math meets beauty -------------------------------------------------------------------------------- /myprojects/media/book_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/media/book_cover.png -------------------------------------------------------------------------------- /myprojects/media/lyricvideo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/media/lyricvideo.png -------------------------------------------------------------------------------- /myprojects/media/EffectExamples.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/media/EffectExamples.gif -------------------------------------------------------------------------------- /myprojects/README.md: -------------------------------------------------------------------------------- 1 | A collection of Manim codes. 2 | 3 | See the page [here](https://lemononmars.github.io/manim/myprojects). -------------------------------------------------------------------------------- /myprojects/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | title: lemononmars's Manim collection 3 | description: Math meets beauty -------------------------------------------------------------------------------- /myprojects/media/exponential_sum.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/media/exponential_sum.gif -------------------------------------------------------------------------------- /myprojects/__pycache__/ball.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/ball.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/song.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/song.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/testdice.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/testdice.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/testthai.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/testthai.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/cool_effect.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/cool_effect.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/perf_scenes.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/perf_scenes.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/puzzle_clip.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/puzzle_clip.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/test_graph.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/test_graph.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/test_polar.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/test_polar.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/two_circles.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/two_circles.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/circle_formula.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/circle_formula.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/example_scenes.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/example_scenes.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/mysterious_box.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/mysterious_box.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/__pycache__/polynomial_arithematic.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/__pycache__/polynomial_arithematic.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/farey_fractions/__pycache__/intro.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/farey_fractions/__pycache__/intro.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/tabletop_encyclopedia/__pycache__/overall.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/tabletop_encyclopedia/__pycache__/overall.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/__pycache__/polynomial_addition.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/polynomial_arithematics/__pycache__/polynomial_addition.cpython-37.pyc -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/__pycache__/polynomial_multiplication.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemononmars/manim/HEAD/myprojects/polynomial_arithematics/__pycache__/polynomial_multiplication.cpython-37.pyc -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.bak 3 | .DS_Store 4 | homeless.py 5 | playground.py 6 | cairo_test.py 7 | mayavi_test.py 8 | random_scenes/ 9 | files/ 10 | assets/ 11 | ben_playground.py 12 | ben_cairo_test.py 13 | .floo 14 | .flooignore 15 | .vscode 16 | .vs 17 | *.xml 18 | *.iml 19 | media 20 | manim.sublime-project 21 | manim.sublime-workspace 22 | .eggs/ 23 | build/ 24 | dist/ 25 | manim.egg-info/ 26 | 27 | primes.py 28 | /media_dir.txt -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thanks for contributing to manim! 2 | 3 | **Please ensure that your pull request works with the latest version of manim.** 4 | You should also include: 5 | 6 | 1. The motivation for making this change (or link the relevant issues) 7 | 2. How you tested the new behavior (e.g. a minimal working example, before/after 8 | screenshots, gifs, commands, etc.) This is rather informal at the moment, but 9 | the goal is to show us how you know the pull request works as intended. 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### If this is a support request: 2 | 3 | **Please attempt to solve the problem on your own before opening an issue.** 4 | Between old issues, StackOverflow, and Google, you should be able to find 5 | solutions to most of the common problems. 6 | 7 | Include at least: 8 | 1. Steps to reproduce the issue (e.g. the command you ran) 9 | 2. The unexpected behavior that occurred (e.g. error messages or screenshots) 10 | 3. The environment (e.g. operating system and version of manim) 11 | 12 | 13 | ### If this is a feature request: 14 | Include the motivation for making this change. 15 | -------------------------------------------------------------------------------- /myprojects/for_fun/stream_opening.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class StreamOpening(Scene): 4 | 5 | def change_background_color(self, color_target): 6 | base_color = self.camera.background_color 7 | def update_bc(mob, alpha): 8 | self.camera.background_color = \ 9 | interpolate_color(base_color, color_target, alpha) 10 | return UpdateFromAlphaFunc(Mobject(), update_bc) 11 | 12 | def construct(self): 13 | self.camera.background_color = YELLOW_A 14 | target_color = GREEN 15 | Pawn = ImageMobject("Trophy") 16 | 17 | self.play(FadeIn(Pawn), self.change_background_color(target_color), run_time = 5) 18 | self.wait() -------------------------------------------------------------------------------- /myprojects/tabletop_encyclopedia/README.md: -------------------------------------------------------------------------------- 1 | Building Blocks of Tabletop Game Design: An Encyclopedia of Mechanisms 2 | ==================================================================================================================================== 3 | 4 | This project is an animation for presentation on the topics in the book. 5 | 6 | building blocks of tabletop game design book cover 8 | 9 | Why using Manim? Because it's the only powerful animation tool I know how to use.... 10 | 11 | I use this [guide](https://www.youtube.com/watch?v=KGdA8IB6JL0&ab_channel=TheoremofBeethoven) to create the meeple creature. 12 | 13 | Text are both in Thai and English. Feel free to fork the code and reproduce the animation in your language. -------------------------------------------------------------------------------- /myprojects/for_fun/testthai.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class Thai(Scene): 4 | def construct(self): 5 | # available fonts are: 6 | # KhanaRatsadon, TH SarabunPSK, 2005_iannnnnnCPU, Prompt, TH Charm of AU, Chulabhorn Likit Text 7 | title1 = Tex("รัฐบาลส้นตีน", font="Chulabhorn Likit Text").set_color(Color("#d3dde9")) 8 | title1.scale(2) 9 | #title1.add_background_rectangle(color='white') 10 | 11 | n = 20 12 | titles = [title1] 13 | for i in range(0,n): 14 | newtitle = title1.copy() 15 | newtitle.set_color(random_bright_color()) 16 | newtitle.move_to(np.array([np.random.uniform(-6,7), np.random.uniform(-3,4), 0])) 17 | titles.append(newtitle) 18 | 19 | self.play(AnimationGroup(*[ 20 | DrawBorderThenFill(t, rate_func = linear, run_time = 1) 21 | for t in titles 22 | ], 23 | lag_ratio = 1 24 | )) -------------------------------------------------------------------------------- /myprojects/test_polar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | 5 | class TestPolar(Scene): 6 | def construct(self): 7 | text = TextMobject("Petal plot") 8 | p = PolarCurve(lambda theta: 1 - np.cos(theta)) #custom class, extending ParametricFunction 9 | 10 | theta = ValueTracker(0) 11 | t = DecimalNumber( 12 | 0, 13 | show_ellipsis=True, 14 | num_decimal_places=3, 15 | include_sign=True, 16 | ) 17 | 18 | t.add_updater(lambda x: x.set_value(theta.get_value())) 19 | 20 | d = Dot(p.get_point_from_function(0), radius = 0.1, color = RED) 21 | l = Line(ORIGIN, d.get_center()) 22 | self.add(d, l) 23 | d.add_updater(lambda x: x.move_to(p.get_point_from_function(theta.get_value()))) 24 | l.add_updater(lambda x: x.become(Line(ORIGIN, d.get_center()))) 25 | 26 | text.to_edge(UP) 27 | theta_tex = VGroup(TexMobject(r'\theta = '), t).arrange(RIGHT, aligned_edge = DOWN) 28 | theta_tex.to_edge(DOWN) 29 | self.play(Write(text)) 30 | self.play(Write(theta_tex)) 31 | self.play(ShowCreation(p)) 32 | self.play(ApplyMethod(theta.set_value, TAU), run_time = 3) 33 | self.wait() -------------------------------------------------------------------------------- /myprojects/index.md: -------------------------------------------------------------------------------- 1 | # Manim collection 2 | 3 | I have a collection of Manim codes [here](https://github.com/lemononmars/manim/tree/master/myprojects). Feel free to explore and reuse them all. 4 | 5 | Below are some featured codes. 6 | 7 | ## Exponential Sum 8 | [``exponential_sum.py``](https://github.com/lemononmars/manim/blob/c3826e32847fb710bce2793979fdaebe07580dbe/myprojects/exponential_sum.py) 9 | 10 | exponential sum animation gif 11 | 12 | ## Cool Effect 13 | You can create text animations as seen [here](https://zulko.github.io/moviepy/examples/moving_letters.html). 14 | 15 | See the example below and find the corresponding code in [``cool_effect.py``](https://github.com/lemononmars/manim/blob/c3826e32847fb710bce2793979fdaebe07580dbe/myprojects/test/cool_effect.py) 16 | 17 | cool effect animation gif 18 | 19 | ## Lyric Video 20 | It turns out you can make a lyric video! [``song.py``](https://github.com/lemononmars/manim/blob/c3826e32847fb710bce2793979fdaebe07580dbe/myprojects/for_fun/song.py) 21 | 22 | lyric video using Manim 24 | 25 | Ignoring fancy animations, there's one main trick here. ``time.perf_counter()`` is for compiler, not for animation. You have to jump forward to a specific timestamp using ``self.wait(timestamp - self.time)``. 26 | -------------------------------------------------------------------------------- /myprojects/for_fun/mysterious_box.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | import numpy as np 3 | 4 | class Box(Scene): 5 | 6 | def construct(self): 7 | # create a nice box 8 | box_front = Polygon([0,0,0],[2,0,0],[2,2,0],[0,2,0], stroke_width = 3, stroke_color = WHITE).set_opacity(1) 9 | box_top = Polygon([0,0,0],[2,0,0],[3,1,0],[1,1,0], stroke_width = 3, stroke_color = WHITE).set_opacity(0.4).shift(UP*2) 10 | box_right = Polygon([0,0,0],[1,1,0],[1,3,0],[0,2,0], stroke_width = 3, stroke_color = WHITE).set_opacity(1).shift(RIGHT*2) 11 | box = VGroup(box_front, box_top, box_right) 12 | box.shift(DOWN*3) 13 | 14 | new_box1 = box.copy().scale(0.5) 15 | 16 | num1 = TexMobject("1", color = GREEN).scale(3) 17 | num2 = TexMobject("2", color = RED).scale(3) 18 | 19 | startp = np.array([1,-2,0]) 20 | path1 = ArcBetweenPoints(startp, np.array([-5,3,0])) 21 | path2 = ArcBetweenPoints(startp, np.array([-5,1,0])) 22 | path3 = ArcBetweenPoints(startp, np.array([-3,3,0])) 23 | 24 | num1.align_to(box) 25 | num2.align_to(box) 26 | 27 | self.add_foreground_mobjects(box) 28 | self.wait(6) 29 | self.play(MoveAlongPath(num1, path1), run_time = 2) 30 | self.wait(2) 31 | self.play(MoveAlongPath(num2, path2), run_time = 2) 32 | self.wait(4) 33 | self.play(MoveAlongPath(new_box1, path3), run_time = 2) 34 | self.wait(0.5) 35 | self.play(AnimationGroup( 36 | FadeOut(num1), 37 | FadeOut(num2), 38 | FadeOut(box), 39 | ReplacementTransform(new_box1, box) 40 | )) 41 | self.wait(0.5) -------------------------------------------------------------------------------- /img/wooden-crate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /myprojects/testdice.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | from myconstructs.randomizer import * 5 | from datetime import datetime 6 | import functools 7 | 8 | class DiceScene(Scene): 9 | CONFIG = { 10 | "num_dice": 3, 11 | "show_total": True 12 | } 13 | def construct(self): 14 | random.seed(datetime.now()) 15 | 16 | pip_color = [GREEN, BLUE, ORANGE] 17 | dice = [] 18 | for i in range(self.num_dice): 19 | dice.append(D6(pip_color = pip_color[i])) 20 | 21 | total = Integer( 22 | reduce(lambda a,b: a+b, [d.get_value() for d in dice]) 23 | ) 24 | total.scale(5) 25 | g = VGroup() 26 | for d in dice: 27 | g.add(d) 28 | g.add(TexMobject("="), total) 29 | g.arrange(RIGHT) 30 | 31 | # start animation 32 | self.play(ShowCreation(g), run_time = 3) 33 | self.wait() 34 | text1 = TextMobject("Roll each dice").to_edge(DOWN) 35 | self.play(DrawBorderThenFill(text1)) 36 | for i in range(3): 37 | for d in dice: 38 | self.play(*d.Roll()) 39 | total.set_value( 40 | reduce(lambda a,b: a+b, [d.get_value() for d in dice]) 41 | ) 42 | 43 | text2 = TextMobject("Roll all dice").to_edge(DOWN) 44 | self.play(Transform(text1, text2)) 45 | for i in range(3): 46 | seq = [] 47 | for d in dice: 48 | seq = seq + d.Roll() 49 | self.play(*seq) 50 | total.set_value( 51 | reduce(lambda a,b: a+b, [d.get_value() for d in dice]) 52 | ) 53 | self.wait() 54 | 55 | 56 | class CardScene(Scene): 57 | def construct(self): 58 | random.seed(datetime.now()) 59 | v1 = random.randint(1,13) 60 | v2 = random.randint(1,13) 61 | c1 = PlayingCard(v1, "club", face_up= True) 62 | c2 = PlayingCard(v2, "diamond", face_up = False) 63 | g = VGroup(c1, c2).arrange(RIGHT) 64 | 65 | self.play(FadeInFrom(g, DOWN)) 66 | self.wait(1) 67 | self.play(c1.Flip()) 68 | self.wait(0.5) 69 | self.play(c1.Flip()) 70 | self.wait(0.5) 71 | self.play(c2.Flip()) 72 | self.wait(0.5) 73 | self.play(c2.Flip()) 74 | self.wait(1) -------------------------------------------------------------------------------- /myprojects/exponential_sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from manim import * 3 | 4 | # create new classes so that we can have it memorize its index 5 | class LinkedLine(Line): 6 | def __init__(self, index = 0, **kwargs): 7 | self.index = index 8 | super().__init__(**kwargs) 9 | 10 | class Trace(VMobject): 11 | def __init__(self, index = 0, **kwargs): 12 | self.index = index 13 | super().__init__(**kwargs) 14 | 15 | class Pic(Scene): 16 | def construct(self): 17 | NUM_LINES = 5 18 | 19 | #starting configurations 20 | line_widths = [1/(1.2**x)*RIGHT for x in range(0,NUM_LINES)] 21 | Lines = [LinkedLine(start = ORIGIN, end = 5*RIGHT).to_edge(LEFT)] 22 | Traces = [VMobject()] #add a dummy object so that indices match with lines 23 | for i in range(1, NUM_LINES): 24 | Lines.append( 25 | LinkedLine( 26 | start = Lines[-1].get_end(), 27 | end = Lines[-1].get_end() + line_widths[i], 28 | index = i) 29 | ) 30 | Traces.append( 31 | Trace(index = i).set_points_as_corners([Lines[-1].get_end(), Lines[-1].get_end()]) 32 | ) 33 | 34 | Lines_Group = VGroup(*Lines).set_submobject_colors_by_gradient(GREEN, ORANGE) 35 | Traces_Group = VGroup(*Traces).set_submobject_colors_by_gradient(GREEN, ORANGE) 36 | self.add(Lines_Group, Traces_Group) 37 | Lines_ref = Lines_Group.copy() 38 | 39 | # update each line 40 | def line_update_function(mob): 41 | prev_end = Lines_Group[mob.index-1].get_end() 42 | mob.become(Lines_ref[mob.index]) 43 | mob.put_start_and_end_on(prev_end, prev_end + line_widths[mob.index]) 44 | mob.rotate( 45 | theta_tracker.get_value() * mob.index, about_point = prev_end 46 | ) 47 | 48 | # update each trace 49 | def trace_update_function(mob): 50 | newmob = mob.copy() 51 | newmob.add_points_as_corners([Lines[mob.index].get_end()]) 52 | mob.become(newmob) 53 | 54 | # add updaters to the appropriate objects 55 | for i in range(1, NUM_LINES): 56 | Lines_Group[i].add_updater(line_update_function) 57 | Traces[i].add_updater(trace_update_function) 58 | 59 | # animate! 60 | theta_tracker = ValueTracker(0) 61 | self.play(ApplyMethod(theta_tracker.set_value, 2*PI), run_time=10) 62 | self.wait(1) -------------------------------------------------------------------------------- /myprojects/for_fun/Koch_Snowflake.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | from colour import Color 3 | 4 | class Fractal(Scene): 5 | def construct(self, step = 3, radius = 3): 6 | def next_gen(lines): 7 | new_lines = VGroup() 8 | for l in lines: 9 | new_lines.add(*generate_from_seed(l)) 10 | return new_lines 11 | 12 | def generate_from_seed(line): 13 | p1, p2 = line.get_start_and_end() 14 | points = [p1, 0, 0, 0, p2] 15 | # m2 16 | # / \ 17 | # p1 - m1 m3 - p2 18 | points[1] = 2*p1/3 + p2/3 19 | points[3] = p1/3 + 2*p2/3 20 | theta = PI/3 21 | rot_sixty = np.array([ 22 | [np.cos(theta), -np.sin(theta), 0], 23 | [np.sin(theta), np.cos(theta), 0], 24 | [0,0,1] 25 | ]) 26 | points[2] = points[1] + np.transpose(rot_sixty @ np.transpose(points[3]-points[1])) 27 | 28 | new_group = VGroup() 29 | for i in range(4): 30 | new_group.add(Line(points[i], points[i+1])) 31 | new_group.set_color(line.get_color()) 32 | 33 | return new_group 34 | 35 | #title = TexMobject("\\text{Start}") 36 | #title.to_edge(UP) 37 | #self.add(title) 38 | 39 | start_lines = VGroup() 40 | # create starting lines 41 | for i in range(6): 42 | p1 = np.array([radius * np.cos(TAU*i/6), radius * np.sin(TAU*i/6), 0]) 43 | p2 = np.array([radius * np.cos(TAU*(i+1)/6), radius * np.sin(TAU*(i+1)/6), 0]) 44 | color1 = Color(rgb=(i/6, i/6, 1)) 45 | color2 = Color(rgb=((i+1)/6, (i+1)/6, 1)) 46 | start_lines.add( 47 | Line(p1, p2).set_color_by_gradient([color1, color2]) 48 | ) 49 | 50 | self.add(start_lines) 51 | latest_gen = start_lines 52 | for i in range(step): 53 | #title_text = "n = " + str(i+1) 54 | #title.become(TexMobject(title_text).to_edge(UP)) 55 | new_gen = next_gen(latest_gen) 56 | new_gen.rotate(angle = TAU/12) 57 | self.play( 58 | ReplacementTransform(latest_gen, new_gen), 59 | rate_func = smooth, 60 | run_time = 1 61 | ) 62 | latest_gen = new_gen 63 | 64 | smaller = latest_gen.copy() 65 | self.play(ScaleInPlace(smaller,0.5)) 66 | self.play(Rotating(latest_gen, radians = -TAU, run_time = 5), Rotating(smaller, radians = TAU, run_time = 5)) 67 | 68 | -------------------------------------------------------------------------------- /myprojects/for_fun/testjap.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Thai(Scene): 4 | def construct(self): 5 | title1 = Text("今日も", font="MS Gothic") 6 | title2 = Text("雪歩は", font="MS Gothic") 7 | title3 = Text("可愛いな", font="MS Gothic") 8 | title = VGroup(title1, title2, title3).arrange(DOWN) 9 | #title.scale(3).set_color_by_gradient([, WHITE]) 10 | title.scale(3).set_color_by_gradient([BLUE, Color("#d3dde9")]) 11 | self.play(DrawBorderThenFill(title1)) 12 | self.play(DrawBorderThenFill(title2)) 13 | self.play(DrawBorderThenFill(title3)) 14 | self.wait() 15 | 16 | snow1 = self.get_snow(4) 17 | snow1.to_edge(RIGHT).set_color_by_gradient([BLUE, Color("#d3dde9")]) 18 | snow2 = self.get_snow(4) 19 | snow2.to_edge(LEFT).set_color_by_gradient([BLUE, Color("#d3dde9")]) 20 | self.play(ShowCreation(snow1), ShowCreation(snow2)) 21 | self.play(Rotating(snow1), Rotating(snow2)) 22 | 23 | def get_snow(self, num_gen = 3): 24 | def next_gen(lines): 25 | new_lines = VGroup() 26 | for l in lines: 27 | new_lines.add(*generate_from_seed(l)) 28 | return new_lines 29 | 30 | def generate_from_seed(line): 31 | p1, p2 = line.get_start_and_end() 32 | points = [p1, 0, 0, 0, p2] 33 | # m2 34 | # / \ 35 | # p1 - m1 m3 - p2 36 | points[1] = 2*p1/3 + p2/3 37 | points[3] = p1/3 + 2*p2/3 38 | theta = PI/3 39 | rot_sixty = np.array([ 40 | [np.cos(theta), -np.sin(theta), 0], 41 | [np.sin(theta), np.cos(theta), 0], 42 | [0,0,1] 43 | ]) 44 | points[2] = points[1] + np.transpose(rot_sixty @ np.transpose(points[3]-points[1])) 45 | 46 | new_group = VGroup() 47 | for i in range(4): 48 | new_group.add(Line(points[i], points[i+1])) 49 | new_group.set_color(line.get_color()) 50 | 51 | return new_group 52 | 53 | start_lines = VGroup() 54 | # create starting lines 55 | for i in range(6): 56 | p1 = np.array([np.cos(TAU*i/6), np.sin(TAU*i/6), 0]) 57 | p2 = np.array([np.cos(TAU*(i+1)/6), np.sin(TAU*(i+1)/6), 0]) 58 | start_lines.add( 59 | Line(p1, p2) 60 | ) 61 | 62 | latest_gen = start_lines 63 | for i in range(num_gen): 64 | new_gen = next_gen(latest_gen) 65 | latest_gen = new_gen 66 | 67 | return latest_gen -------------------------------------------------------------------------------- /myprojects/test/ball.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class ThreeDParametricSpring(ThreeDScene): 4 | def construct(self): 5 | curve1 = ParametricFunction( 6 | lambda u: np.array([ 7 | 16 * np.sin(u) * np.sin(u), 8 | 13 * np.cos(u) + 6 * np.cos(4 * u), 9 | u 10 | ]), color=RED, t_min=0, t_max=TAU, 11 | ).set_shade_in_3d(True) 12 | axes = ThreeDAxes() 13 | self.add(axes, curve1) 14 | self.set_camera_orientation(phi=80 * DEGREES, theta=-60 * DEGREES) 15 | self.begin_ambient_camera_rotation(rate = PI/10) 16 | self.wait(10) 17 | 18 | class Ball(Circle): 19 | CONFIG = { 20 | "radius": 0.4, 21 | "fill_color": BLUE, 22 | "fill_opacity": 1, 23 | "color": BLUE 24 | } 25 | 26 | def __init__(self, ** kwargs): 27 | Circle.__init__(self, ** kwargs) 28 | self.velocity = np.array((2, 0, 0)) 29 | 30 | def get_top(self): 31 | return self.get_center()[1] + self.radius 32 | 33 | def get_bottom(self): 34 | return self.get_center()[1] - self.radius 35 | 36 | def get_right_edge(self): 37 | return self.get_center()[0] + self.radius 38 | 39 | def get_left_edge(self): 40 | return self.get_center()[0] - self.radius 41 | 42 | class Box(Rectangle): 43 | CONFIG = { 44 | "height": 6, 45 | "width": FRAME_WIDTH - 2, 46 | "color": GREEN_C 47 | } 48 | 49 | def __init__(self, ** kwargs): 50 | Rectangle.__init__(self, ** kwargs) # Edges 51 | self.top = 0.5 * self.height 52 | self.bottom = -0.5 * self.height 53 | self.right_edge = 0.5 * self.width 54 | self.left_edge = -0.5 * self.width 55 | 56 | class BouncingBall(Scene): 57 | def construct(self): 58 | box = Box() 59 | ball = Ball() 60 | self.play(FadeIn(box)) 61 | self.play(FadeIn(ball)) 62 | 63 | def update_ball(ball,dt): 64 | ball.acceleration = np.array((0, -5, 0)) 65 | ball.velocity = ball.velocity + ball.acceleration * dt 66 | ball.shift(ball.velocity * dt) # Bounce off ground and roof 67 | if ball.get_bottom() <= box.bottom or \ 68 | ball.get_top() >= box.top: 69 | ball.velocity[1] = -ball.velocity[1] 70 | # Bounce off walls 71 | if ball.get_left_edge() <= box.left_edge or \ 72 | ball.get_right_edge() >= box.right_edge: 73 | ball.velocity[0] = -ball.velocity[0] 74 | 75 | ball.add_updater(update_ball) 76 | self.add(ball) 77 | 78 | self.wait(10) -------------------------------------------------------------------------------- /myprojects/trig/formula_angle_sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | 5 | class main(GraphScene): 6 | CONFIG = { 7 | "x_min": -1, 8 | "x_max": 1, 9 | "y_min": 0, 10 | "y_max": 1, 11 | "y_bottom_tick": 0, 12 | "x_axis_width": 8, 13 | "y_axis_height": 4, 14 | "graph_origin": ORIGIN + 2*DOWN, 15 | "function_color": WHITE, 16 | "axes_color": BLUE, 17 | } 18 | 19 | def construct(self): 20 | self.sin_sum() 21 | self.wait() 22 | #self.cos_sum() 23 | self.wait() 24 | 25 | def sin_sum(self): 26 | self.setup_axes() 27 | # set up triangles 28 | a1 = PI/6 29 | a2 = PI/4 30 | pc1 = Dot(self.coords_to_point(math.cos(a1), math.sin(a1))) 31 | pb1 = Dot(self.coords_to_point(math.cos(a1), 0)) 32 | pc2 = Dot(self.coords_to_point(math.cos(a1+a2), math.sin(a1+a2))) 33 | pb2 = Dot(self.coords_to_point(math.cos(a1+a2), 0)) 34 | p_special = Dot(self.coords_to_point(math.cos(a1)*math.cos(a2), math.sin(a1)*math.cos(a2))) 35 | 36 | arc1 = Arc(0, a1, radius = 1).set_color(GREEN).set_fill(GREEN).move_arc_center_to(self.graph_origin) 37 | arc2 = Arc(a1, a2, radius = 1).set_color(PINK).set_fill(PINK).move_arc_center_to(self.graph_origin) 38 | 39 | text_angle1 = TexMobject("\\alpha") 40 | text_angle1.next_to(arc1, RIGHT) 41 | text_angle2 = TexMobject("\\beta") 42 | text_angle2.next_to(arc2, UR) 43 | 44 | # b = base 45 | # c = rotated line 46 | # v = vertical line 47 | line_b1 = Line(self.graph_origin, pb1.get_center()).set_color(GREEN) 48 | line_c1 = Line(self.graph_origin, pc1.get_center()).set_color(GREEN) 49 | line_v1 = Line(pb1.get_center(), pc1.get_center()).set_color(GREEN) 50 | 51 | line_b2 = Line(self.graph_origin, pb2.get_center()).set_color(PINK) 52 | line_c2 = Line(self.graph_origin, pc2.get_center()).set_color(PINK) 53 | line_v2 = Line(pb2.get_center(), pc2.get_center()).set_color(PINK) 54 | line_special = Line(pc2.get_center(), p_special.get_center()) 55 | 56 | # animate triangles 57 | self.play(FadeIn(pb1), FadeIn(pc1)) # for debugging 58 | self.play(ShowCreation(line_b1)) 59 | self.play(ShowCreation(line_v1)) 60 | self.play(ShowCreation(line_c1)) 61 | self.play(ShowCreation(arc1)) 62 | self.play(Write(text_angle1)) 63 | 64 | self.play(ShowCreation(line_b2)) 65 | self.play(ShowCreation(line_v2)) 66 | self.play(ShowCreation(line_c2)) 67 | self.play(ShowCreation(arc2)) 68 | self.play(Write(text_angle2)) 69 | 70 | self.play(ShowCreation(line_special)) 71 | 72 | # bisect the line 73 | 74 | # formulas -------------------------------------------------------------------------------- /myprojects/for_fun/puzzle_clip.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | import numpy as np 3 | 4 | class Puzzle(Scene): 5 | CONFIG={ 6 | "camera_config":{ 7 | "background_color":"#f8f1f1", #puzzle background theme 8 | "frame_height": 10.0, 9 | "frame_width": 10.0 10 | } 11 | } 12 | 13 | def construct(self): 14 | # add logo and bottom layer 15 | banner = ImageMobject(".\img\\bottom_banner.png").scale(0.47) 16 | banner.shift(4.6*DOWN) 17 | self.add_foreground_mobject(banner) 18 | bgsquare = Square(side_length = 4, color = "#16c79a", fill_opacity = 1).to_corner(LEFT+UP).shift(UP*4+0.5*LEFT).rotate(TAU/8) 19 | # messed up due to dimension change.... there must be a better way.... 20 | num = Text("25", font = "Impact").set_color(WHITE).scale(2).next_to(bgsquare).shift(2.8*LEFT+DOWN*1.2) 21 | bgsquare.set_z(1) 22 | num.set_z(-1) 23 | banner.set_z(1) 24 | self.add_foreground_mobjects(bgsquare, num) 25 | 26 | # make hexagonal grid 27 | r = 4 28 | R = RIGHT*r 29 | UR = RIGHT*r/2 + UP*r*(np.sqrt(3))/2 30 | 31 | # add dot as first hint 32 | d = Dot(radius=0.1, color = "#16c79a", fill_opacity = 1) 33 | dot1 = d.copy().shift(R) 34 | dot2 = d.copy().shift(UR) 35 | dot3 = d.copy().shift(-R+UR) 36 | dot4 = d.copy().shift(-R) 37 | dot5 = d.copy().shift(-UR) 38 | dot6 = d.copy().shift(R-UR) 39 | 40 | dots = [dot1, dot2, dot3, dot4, dot5, dot6] 41 | self.add(*dots) 42 | self.play(AnimationGroup(*[ 43 | ShowCreationThenFadeOut(d, run_time = 0.15) 44 | for d in dots 45 | ], 46 | lag_ratio = 0.1 47 | )) 48 | 49 | imA = ImageMobject(".\img\A.png") 50 | imB = ImageMobject(".\img\B.png") 51 | imC = ImageMobject(".\img\C.png") 52 | imD = ImageMobject(".\img\D.png") 53 | imE = ImageMobject(".\img\E.png") 54 | imF = ImageMobject(".\img\F.png") 55 | ims = [imA, imB, imC, imD, imE, imF] 56 | for i in ims: 57 | i.scale(1.2) 58 | #TODO - use SVG instead? 59 | 60 | 61 | 62 | pathA = Line((-2)*R+2*UR, 2*R+(-2)*UR) 63 | pathB = Arc(radius = r, arc_center = UR-R, angle = 2*TAU, start_angle = TAU/6) 64 | pathC = Arc(radius = r, arc_center = R-UR, angle = 2*TAU, start_angle = -TAU/6) 65 | pathD = Arc(radius = r, arc_center = R, angle = 2*TAU, start_angle = 0) 66 | pathE = Line((-2)*R, 2*R) 67 | pathF = Arc(radius = r, arc_center = -R, angle = 2*TAU, start_angle = TAU/2) 68 | paths = [pathA, pathB, pathC, pathD, pathE, pathF] 69 | 70 | rates = [there_and_back, linear, linear, linear, there_and_back, linear] 71 | # DEBUG: display paths 72 | #self.add(*paths) 73 | #self.add(*ims) 74 | #self.wait(1) 75 | 76 | self.play(AnimationGroup(*[ 77 | MoveAlongPath(x, y, rate_func = z, run_time = 6) 78 | for (x, y, z) in zip(ims, paths, rates) 79 | ], 80 | lag_ratio = 0.2 81 | )) 82 | self.wait(1) 83 | -------------------------------------------------------------------------------- /myprojects/trig/two_circles.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class TwoCircle_RightSide(Scene): 4 | def construct(self): 5 | self.show_axis() 6 | self.show_circle_dot() 7 | self.draw_cycle() 8 | 9 | self.wait() 10 | 11 | def show_axis(self): 12 | self.x_start = np.array([-6.5,2,0]) 13 | x_axis = Line(self.x_start, np.array([6, 2, 0])) 14 | y_axis = Line(np.array([-5, 0, 0]), np.array([-5, 0, 0])) 15 | 16 | self.add(x_axis, y_axis) 17 | 18 | self.circle1_origin = np.array([-5, 2, 0]) 19 | self.circle2_origin = np.array([-4, 2, 0]) 20 | 21 | self.one_cycle_length = 2 * PI 22 | 23 | def show_circle_dot(self): 24 | circle1 = Circle(radius=1) 25 | circle2 = Circle(radius=0.3) 26 | circle1.move_to(self.circle1_origin) 27 | circle2.move_to(self.circle2_origin) 28 | 29 | dot1 = Dot(radius=0.04, color=YELLOW) 30 | dot1.move_to(circle1.point_from_proportion(0)) 31 | 32 | dot2 = Dot(radius=0.04, color=YELLOW) 33 | dot2.move_to(circle2.point_from_proportion(0)) 34 | 35 | self.dot1_freq = 1.0 36 | self.dot2_freq = 3.0 37 | 38 | self.add(circle1, circle2, dot1, dot2) 39 | self.circle1, self.circle2 = circle1, circle2 40 | self.dot1, self.dot2 = dot1, dot2 41 | self.curve_start = dot2.get_center() 42 | 43 | def draw_cycle(self): 44 | self.t_offset = 0 45 | self.t_rate = 0.5 46 | self.one_cycle_time = 4 47 | 48 | def rotate_dot1(mob, dt): 49 | self.t_offset += (dt * self.t_rate) 50 | mob.move_to(self.circle1.point_from_proportion(((self.t_offset * self.dot1_freq) / self.one_cycle_time) % 1)) 51 | 52 | def update_circle2(mob): 53 | circle = Circle(radius = 0.3) 54 | circle.move_to(self.dot1.get_center()) 55 | mob.become(circle) 56 | 57 | def update_dot2(mob): 58 | mob.move_to(self.circle2.point_from_proportion(((self.t_offset * self.dot2_freq) / self.one_cycle_time) % 1)) 59 | 60 | line_to_curve = Line(self.dot2.get_center(), self.dot2.get_center()) 61 | def update_line_to_curve(mob): 62 | x = self.curve_start[0] + self.t_offset 63 | y = self.dot2.get_center()[1] 64 | line = Line(self.dot2.get_center(), np.array([x,y,0]), color=YELLOW_A, stroke_width=2 ) 65 | mob.become(line) 66 | 67 | cosine_curve = VGroup() 68 | cosine_curve.add(Line(self.curve_start, self.curve_start)) 69 | def update_curve(mob): 70 | curve = mob.copy() 71 | last_line = curve[-1] 72 | x = self.curve_start[0] + self.t_offset 73 | y = self.dot2.get_center()[1] 74 | new_line = Line(last_line.get_end(), np.array([x, y, 0]), color=YELLOW_D) 75 | curve.add(new_line) 76 | 77 | mob.become(curve) 78 | 79 | self.dot1.add_updater(rotate_dot1) 80 | self.circle2.add_updater(update_circle2) 81 | self.dot2.add_updater(update_dot2) 82 | 83 | line_to_curve.add_updater(update_line_to_curve) 84 | cosine_curve.add_updater(update_curve) 85 | 86 | self.add(line_to_curve, cosine_curve) 87 | self.wait(self.one_cycle_time * 4.1) 88 | 89 | self.dot1.remove_updater(rotate_dot1) -------------------------------------------------------------------------------- /myprojects/test/cool_effect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | text = Text("Cool Effect").scale(3) 5 | 6 | class EffectExamples(Scene): 7 | def construct(self): 8 | self.ellipse() 9 | self.bounce() 10 | self.stack() 11 | self.disperse() 12 | 13 | def ellipse(self): 14 | title = Text(r'self.ellipse()', font = "Consolas", color = YELLOW, t2c = {'self':BLUE, '()':WHITE}) 15 | title.to_edge(DOWN) 16 | self.add(title) 17 | 18 | text_start = text.copy() 19 | self.add(text_start) 20 | 21 | # start from an ellipse that is off screen 22 | ellipse = Ellipse(width = 20, height = 12) 23 | for i in range(len(text)): 24 | # use a built-in function to get points that are equally spaced angle-wise 25 | # +4 is just an offset. play around with the offset to get different effects. 26 | new_pos = ellipse.point_at_angle(TAU*((i+4)%len(text))/len(text)) 27 | text_start[i].move_to(new_pos) 28 | 29 | # animate each letter to the appropriate position 30 | self.play(AnimationGroup( 31 | *[ApplyMethod(text_start[i].move_to, text[i].get_center()) for i in range(len(text))] 32 | )) 33 | self.remove(title) 34 | self.play(FadeOut(text_start)) 35 | 36 | def bounce(self): 37 | title = Text(r'self.bounce()', font = "Consolas", color = YELLOW, t2c = {'self':BLUE, '()':WHITE}) 38 | title.to_edge(DOWN) 39 | self.add(title) 40 | # start from top, off screen 41 | text_start = text.copy().shift(6*UP) 42 | 43 | # set smooth paths for each letter 44 | points = [6*UP, ORIGIN, 0.5*UP, ORIGIN, 0.1*UP, ORIGIN] 45 | path = VMobject().set_points_smoothly(points) 46 | paths = [path.copy().next_to(t.get_center(), DOWN, buff = 0) for t in text_start] 47 | 48 | # animate each letter on their own path to the appropriate position 49 | self.play(AnimationGroup( 50 | *[MoveAlongPath(t, p, rate_func = linear) for t,p in zip(text_start, paths) ], 51 | lag_ratio = 0.2 52 | )) 53 | self.remove(title) 54 | self.play(FadeOut(text_start)) 55 | 56 | def stack(self): 57 | title = Text(r'self.stack()', font = "Consolas", color = YELLOW, t2c = {'self':BLUE, '()':WHITE}) 58 | title.to_edge(DOWN) 59 | self.add(title) 60 | 61 | # start from the right, off screen 62 | text_start = text.copy().move_to(RIGHT*10) 63 | self.add(text_start) 64 | 65 | # animate each letter to the appropriate position 66 | self.play(AnimationGroup( 67 | *[ApplyMethod(text_start[i].move_to, text[i].get_center()) for i in range(len(text))], 68 | lag_ratio = 0.2 69 | )) 70 | self.remove(title) 71 | self.remove(*text_start) #since text_start had been animated individually, we need to remove it the same way 72 | 73 | def disperse(self): 74 | title = Text(r'self.disperse()', font = "Consolas", color = YELLOW, t2c = {'self':BLUE, '()':WHITE}) 75 | title.to_edge(DOWN) 76 | self.add(title) 77 | 78 | text_end = text.copy() 79 | # set endpoints on an ellipse that is off screen 80 | ellipse = Ellipse(width = 20, height = 12) 81 | for i in range(len(text)): 82 | new_pos = ellipse.point_at_angle(TAU*((i+8)%len(text))/len(text)) 83 | text_end[i].move_to(new_pos) 84 | 85 | # animate each letter from the center to the ellipse 86 | self.play(AnimationGroup( 87 | *[ApplyMethod(text[i].move_to, text_end[i].get_center()) for i in range(len(text))] 88 | )) 89 | self.wait(1) 90 | self.remove(title) 91 | -------------------------------------------------------------------------------- /myprojects/farey_fractions/intro.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class Intro(Scene): 4 | def construct(self): 5 | #self.math_def() 6 | self.rotating_tick(5) 7 | 8 | def math_def(self): 9 | return 10 | 11 | def get_farey_fractions(self, n): 12 | points = [(0,1)] 13 | for i in range(1, n+1): 14 | for j in range(1, i+1): 15 | if np.gcd(i,j) == 1: 16 | points.append((j,i)) 17 | points.sort(key=lambda x: self.c2f(x)) 18 | return points 19 | 20 | def c2f(self, c): 21 | return c[0]/c[1] 22 | 23 | def rotating_tick(self, n): 24 | #self.axis = Axes(x_range = [0,n,1], y_range = [0,n,1], x_length = 4, y_length = 4) 25 | #self.play(ShowCreation(self.axis)) 26 | 27 | ff = self.get_farey_fractions(n) 28 | 29 | center = Dot(ORIGIN, radius = 0.1, color = YELLOW) 30 | width = 4/n 31 | self.endpoint = Dot(RIGHT*10) # used with updater 32 | self.line = Line(ORIGIN, width*RIGHT, stroke_width = 3, color = BLUE) # start at (1,0) 33 | 34 | dot_counts = ValueTracker(0) 35 | dot_count_num = Integer(np.int(dot_counts.get_value())) 36 | dot_count_text = VGroup(MathTex('n ='), dot_count_num).arrange(RIGHT) 37 | dot_count_text.to_corner(UL) 38 | self.add(dot_count_text, dot_count_num) 39 | dot_count_num.add_updater( 40 | lambda x: x.set_value( 41 | np.int(dot_counts.get_value()) 42 | ) 43 | ) 44 | 45 | Dark_points = [] 46 | for i in range(1, n+1): 47 | for j in range(0, i+1): 48 | Dark_points.append(Dot(i*width*RIGHT + j*width*UP, fill_opacity = 0.3)) 49 | Dark_point_group = VGroup(*Dark_points) 50 | self.add(Dark_point_group, center) 51 | 52 | ff_text = VGroup(*[MathTex(r"\frac{%d}{%d}"%(f[0],f[1])) for f in ff]).scale(0.8) 53 | ff_text.arrange_in_grid(rows = 2, buff = 0.4) 54 | ff_text.to_edge(DOWN) 55 | 56 | # start animating the line and hitting the first dot 57 | self.play(Create(self.line)) 58 | self.add_sound("Ding") 59 | d = Dot(width*RIGHT + 0*UP, color = GREEN) 60 | self.add(d) 61 | self.add(ff_text[np.int(dot_counts.get_value())]) 62 | dot_counts.increment_value(1) 63 | 64 | def update_func(mob, dt): 65 | if mob.get_y()/mob.get_x() >= 1: 66 | return 67 | mob.rotate(dt*0.1, about_point = ORIGIN) 68 | 69 | # check if the line is about to reach the next dot 70 | if np.int(dot_counts.get_value()) < len(ff) and np.abs(mob.get_y()/mob.get_x() - self.c2f(ff[np.int(dot_counts.get_value())])) <= 0.01: 71 | next_dot = ff[np.int(dot_counts.get_value())] 72 | newdot = Dot(next_dot[1]*width*RIGHT + next_dot[0]*width*UP, color = GREEN) 73 | self.add(newdot) 74 | # TODO: add melody according to distance! 75 | self.add_sound("Ding") 76 | self.add(ff_text[np.int(dot_counts.get_value())]) 77 | dot_counts.increment_value(1) 78 | 79 | # check if the line is leaving the previous dot 80 | self.line.become(Line(ORIGIN, mob, stroke_width = 3, color = RED)) 81 | if np.int(dot_counts.get_value()) > 0 and np.abs(mob.get_y()/mob.get_x() - self.c2f(ff[np.int(dot_counts.get_value())-1])) <= 0.01: 82 | curr_dot = ff[np.int(dot_counts.get_value())-1] 83 | line_len = np.sqrt(curr_dot[0]**2 + curr_dot[1]**2) 84 | self.line.set_color(BLUE) 85 | self.line.scale_about_point(width*line_len/10, ORIGIN) 86 | 87 | self.endpoint.add_updater(update_func) 88 | self.add(self.endpoint) 89 | self.wait(9) 90 | #self.endpoint.remove_updater(update_func) 91 | #self.wait(2) 92 | #self.remove(*dot_passed_texts) 93 | #self.remove(Points_group, self.line) 94 | #self.wait() -------------------------------------------------------------------------------- /myprojects/test_graph2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from manim import * 3 | 4 | class TwoD(GraphScene): 5 | CONFIG = { 6 | "x_min": -2, 7 | "x_max": 2, 8 | "y_min": -2, 9 | "y_max": 2, 10 | "graph_origin": ORIGIN, 11 | "function_color": WHITE, 12 | "axes_color": BLUE 13 | } 14 | def construct(self): 15 | self.setup_axes(animate=True) 16 | func_graph = self.get_graph(self.func_to_graph,self.function_color) 17 | graph_lab = self.get_graph_label(func_graph, label = "x^{2} + y^{2} = 1") 18 | 19 | vert_line = self.get_vertical_line_to_graph(1,func_graph,color=YELLOW) 20 | 21 | x = self.coords_to_point(1, self.func_to_graph(1)) 22 | y = self.coords_to_point(0, self.func_to_graph(1)) 23 | horz_line = Line(x,y, color=YELLOW) 24 | 25 | point = Dot(self.coords_to_point(1,self.func_to_graph(1))) 26 | 27 | self.area = self.get_area(func_graph, 0, 2) 28 | #Display graph 29 | self.play(Create(func_graph), Write(graph_lab)) 30 | self.wait(1) 31 | self.play(Create(vert_line)) 32 | self.play(Create(horz_line)) 33 | self.add(point) 34 | self.play(Create(self.area)) 35 | self.wait(2) 36 | 37 | def func_to_graph(self, x): 38 | return (x**2) 39 | 40 | class para(GraphScene): 41 | CONFIG = { 42 | "x_min": -2, 43 | "x_max": 2, 44 | "y_min": -1.5, 45 | "y_max": 1.5, 46 | "y_bottom_tick": -1, 47 | "x_axis_width": 8, 48 | "y_axis_height": 6, 49 | "graph_origin": ORIGIN, 50 | "function_color": WHITE, 51 | "axes_color": BLUE 52 | } 53 | def construct(self): 54 | def create_angle(a): 55 | return Sector( 56 | start_angle=0, 57 | angle = a, 58 | outer_radius = 0.5, 59 | color = GREEN, 60 | fill_opacity = 0.8 61 | ) 62 | self.setup_axes(animate=True) 63 | f = ParametricFunction(self.func, t_min = 0, t_max = TAU) 64 | theta = ValueTracker(0) 65 | x = DecimalNumber( 66 | np.cos(theta.get_value()), 67 | num_decimal_places=3, 68 | ) 69 | y = DecimalNumber( 70 | np.sin(theta.get_value()), 71 | num_decimal_places=3, 72 | ) 73 | p = Dot(f.get_point_from_function(theta.get_value())) 74 | p.set_color(GREEN) 75 | ar = Arrow(ORIGIN, p.get_center(), buff = 0) 76 | ar.set_color(ORANGE) 77 | s = create_angle(theta.get_value()) 78 | 79 | x.add_updater(lambda v: v.set_value(np.cos(theta.get_value()))) 80 | y.add_updater(lambda v: v.set_value(np.sin(theta.get_value()))) 81 | p.add_updater(lambda v: v.move_to(f.get_point_from_function(theta.get_value()))) 82 | ar.add_updater(lambda v: v.put_start_and_end_on(ORIGIN, p.get_center())) 83 | s.add_updater(lambda v: v.become(create_angle(theta.get_value()))) 84 | 85 | # add value update 86 | tx = MathTex("x = ") 87 | ty = MathTex("y = ") 88 | group = VGroup(tx, ty).arrange(DOWN) 89 | #group = VGroup(tx, x, ty, y).arrange_in_grid(2,2) #<- doesn't work? idk 90 | group.to_corner(UL) 91 | x.next_to(tx, RIGHT) 92 | y.next_to(ty, RIGHT) 93 | 94 | self.play(Create(f)) 95 | self.play(Write(group), Write(x), Write(y), Write(p)) 96 | self.play(GrowArrow(ar), Write(s)) 97 | self.play( 98 | theta.set_value,TAU, 99 | rate_func=there_and_back, 100 | run_time=5 101 | ) 102 | self.wait() 103 | 104 | def func(self, t): 105 | return [2*np.cos(t), 2*np.sin(t), 0] 106 | 107 | 108 | # See old_projects folder for many, many more 109 | -------------------------------------------------------------------------------- /myprojects/test_graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | 5 | class TwoD(GraphScene): 6 | CONFIG = { 7 | "x_min": -2, 8 | "x_max": 2, 9 | "y_min": -2, 10 | "y_max": 2, 11 | "graph_origin": ORIGIN, 12 | "function_color": WHITE, 13 | "axes_color": BLUE 14 | } 15 | def construct(self): 16 | self.setup_axes(animate=True) 17 | func_graph = self.get_graph(self.func_to_graph,self.function_color) 18 | graph_lab = self.get_graph_label(func_graph, label = "x^{2} + y^{2} = 1") 19 | 20 | vert_line = self.get_vertical_line_to_graph(1,func_graph,color=YELLOW) 21 | 22 | x = self.coords_to_point(1, self.func_to_graph(1)) 23 | y = self.coords_to_point(0, self.func_to_graph(1)) 24 | horz_line = Line(x,y, color=YELLOW) 25 | 26 | point = Dot(self.coords_to_point(1,self.func_to_graph(1))) 27 | 28 | self.area = self.get_area(func_graph, 0, 2) 29 | #Display graph 30 | self.play(ShowCreation(func_graph), Write(graph_lab)) 31 | self.wait(1) 32 | self.play(ShowCreation(vert_line)) 33 | self.play(ShowCreation(horz_line)) 34 | self.add(point) 35 | self.play(ShowCreation(self.area)) 36 | self.wait(2) 37 | 38 | def func_to_graph(self, x): 39 | return (x**2) 40 | 41 | class para(GraphScene): 42 | CONFIG = { 43 | "x_min": -2, 44 | "x_max": 2, 45 | "y_min": -1.5, 46 | "y_max": 1.5, 47 | "y_bottom_tick": -1, 48 | "x_axis_width": 8, 49 | "y_axis_height": 6, 50 | "graph_origin": ORIGIN, 51 | "function_color": WHITE, 52 | "axes_color": BLUE 53 | } 54 | def construct(self): 55 | def create_angle(a): 56 | return Sector( 57 | start_angle=0, 58 | angle = a, 59 | outer_radius = 0.5, 60 | color = GREEN, 61 | fill_opacity = 0.8 62 | ) 63 | self.setup_axes(animate=True) 64 | f = ParametricFunction(self.func, t_min = 0, t_max = TAU) 65 | theta = ValueTracker(0) 66 | x = DecimalNumber( 67 | math.cos(theta.get_value()), 68 | num_decimal_places=3, 69 | ) 70 | y = DecimalNumber( 71 | math.sin(theta.get_value()), 72 | num_decimal_places=3, 73 | ) 74 | p = Dot(f.get_point_from_function(theta.get_value())) 75 | p.set_color(GREEN) 76 | ar = Arrow(ORIGIN, p.get_center(), buff = 0) 77 | ar.set_color(ORANGE) 78 | s = create_angle(theta.get_value()) 79 | 80 | x.add_updater(lambda v: v.set_value(math.cos(theta.get_value()))) 81 | y.add_updater(lambda v: v.set_value(math.sin(theta.get_value()))) 82 | p.add_updater(lambda v: v.move_to(f.get_point_from_function(theta.get_value()))) 83 | ar.add_updater(lambda v: v.put_start_and_end_on(ORIGIN, p.get_center())) 84 | s.add_updater(lambda v: v.become(create_angle(theta.get_value()))) 85 | 86 | # add value update 87 | tx = TexMobject("x = ") 88 | ty = TexMobject("y = ") 89 | group = VGroup(tx, ty).arrange(DOWN) 90 | #group = VGroup(tx, x, ty, y).arrange_in_grid(2,2) #<- doesn't work? idk 91 | group.to_corner(UL) 92 | x.next_to(tx, RIGHT) 93 | y.next_to(ty, RIGHT) 94 | 95 | self.play(ShowCreation(f)) 96 | self.play(Write(group), Write(x), Write(y), Write(p)) 97 | self.play(GrowArrow(ar), Write(s)) 98 | self.play( 99 | theta.set_value,TAU, 100 | rate_func=there_and_back, 101 | run_time=5 102 | ) 103 | self.wait() 104 | 105 | def func(self, t): 106 | return [2*math.cos(t), 2*math.sin(t), 0] 107 | 108 | 109 | # See old_projects folder for many, many more 110 | -------------------------------------------------------------------------------- /myprojects/cal/diff_eq.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class linear_first_order(Scene): 4 | def construct(self): 5 | title = Text("สมการเชิงเส้นอันดับ 2 ระดับขั้น 1", font="TH Sarabun New") 6 | title.set_color_by_gradient([GREEN, BLUE]) 7 | title.set(width = self.camera.frame_width - 2*MED_LARGE_BUFF) 8 | title.to_edge(UP) 9 | self.play(Write(title)) 10 | 11 | t2 = Text("สมการลักษณะเฉพาะ", font="TH Sarabun New") 12 | t3 = Text("รากของสมการลักษณะเฉพาะ", font="TH Sarabun New") 13 | t4 = Text("ผลเฉลยทั่วไป", font="TH Sarabun New") 14 | t5 = Text("ค่าคงตัวใด ๆ", font="TH Sarabun New") 15 | 16 | eq1 = MathTex("a", 17 | "y''", 18 | "+", 19 | "b", 20 | "y'", 21 | "+", 22 | "c", 23 | "y", 24 | "= 0", 25 | tex_to_color_map={"a": YELLOW, "b": RED, "c": BLUE}) 26 | 27 | eq2 = MathTex("a", 28 | "m^2", 29 | "+", 30 | "b", 31 | "m", 32 | "+", 33 | "c", 34 | "= 0", 35 | tex_to_color_map={"a": YELLOW, "b": RED, "c": BLUE}) 36 | 37 | eq3 = MathTex("m = ", 38 | "m_1", 39 | ",", 40 | "m_2") 41 | eq3[1].set_color(GREEN) 42 | eq3[3].set_color(PINK) 43 | 44 | eq4 = MathTex("y = ", 45 | "A_1", 46 | "e^", 47 | "{m_1", 48 | "x}+", 49 | "A_2", 50 | "e^", 51 | "{m_2", 52 | "x}") 53 | eq4[3].set_color(GREEN) 54 | eq4[7].set_color(PINK) 55 | 56 | group = VGroup(eq1, eq2, eq3, eq4).arrange(DOWN) 57 | group.set(width = self.camera.frame_width - 5 * LARGE_BUFF) 58 | group.to_edge(DOWN) 59 | 60 | t2.next_to(eq2, UP) 61 | t3.next_to(eq3, UP) 62 | t4.next_to(eq4, UP) 63 | t5.next_to(eq4, UP) 64 | 65 | framebox1 = SurroundingRectangle(eq1, buff = .1) 66 | framebox2 = SurroundingRectangle(eq2, buff = .1) 67 | framebox3 = SurroundingRectangle(eq3, buff = .1) 68 | framebox4 = SurroundingRectangle(eq4, buff = .1) 69 | framebox5 = SurroundingRectangle(eq4[1], buff = .1) 70 | framebox6 = SurroundingRectangle(eq4[5], buff = .1) 71 | 72 | arrow1 = Arrow(t5.get_bottom(), eq4[1].get_top(), buff = 0.1) 73 | arrow2 = Arrow(t5.get_bottom(), eq4[5].get_top(), buff = 0.1) 74 | 75 | arrow1.set_color(YELLOW) 76 | arrow2.set_color(YELLOW) 77 | 78 | # scene sequence 79 | self.play(Write(eq1)) 80 | self.wait(0.5) 81 | self.play(Create(framebox1)) 82 | self.wait(0.5) 83 | self.play(FadeOut(framebox1)) 84 | self.wait(0.5) 85 | 86 | self.play(ReplacementTransform(eq1.copy(), eq2)) 87 | self.wait(0.5) 88 | self.play(Write(t2), Create(framebox2)) 89 | self.wait(0.5) 90 | self.play(FadeOut(t2), FadeOut(framebox2)) 91 | self.wait(0.5) 92 | 93 | self.play(ReplacementTransform(eq2.copy(), eq3)) 94 | self.wait(0.5) 95 | self.play(Write(t3), Create(framebox3)) 96 | self.wait(0.5) 97 | self.play(FadeOut(t3), FadeOut(framebox3)) 98 | self.wait(0.5) 99 | 100 | self.play(ReplacementTransform(eq3.copy(), eq4)) 101 | self.wait(0.5) 102 | self.play(Write(t4), Create(framebox4)) 103 | self.wait(0.5) 104 | self.play(FadeOut(t4), FadeOut(framebox4)) 105 | self.wait(0.5) 106 | self.play(Create(framebox5), Create(framebox6)) 107 | self.play(Write(t5), GrowArrow(arrow1), GrowArrow(arrow2)) 108 | self.wait(0.5) 109 | self.play(FadeOut(t5), FadeOut(arrow1), FadeOut(arrow2), FadeOut(framebox5), FadeOut(framebox6)) 110 | self.wait(0.5) 111 | 112 | self.play(ScaleInPlace(eq1, 1.2), ScaleInPlace(eq4,1.2), FadeOut(eq2), FadeOut(eq3)) 113 | 114 | arrow3 = Arrow(eq1.get_bottom(), eq4.get_top(), buff = 0.1) 115 | arrow3.set_color(YELLOW) 116 | self.play(GrowArrow(arrow3)) 117 | self.wait(3) 118 | -------------------------------------------------------------------------------- /myconstructs/randomizer.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Dice(VGroup): 4 | CONFIG = { 5 | "face": None, 6 | "pip_color": BLUE, 7 | "num_faces": 6 8 | } 9 | def __init__(self, **kwargs): 10 | digest_config(self, kwargs) 11 | VGroup.__init__(self, **kwargs) 12 | if self.face == None: 13 | self.face = random.randint(1,self.num_faces) 14 | #self.face = face 15 | self.border = Square() 16 | self.face_mob = self.get_face_mob() 17 | self.face_mob.set_color(self.pip_color) 18 | self.face_mob.move_to(self.border.get_center()) 19 | self.add(self.border, self.face_mob) 20 | 21 | def Roll(self, new_face = None): 22 | if new_face == None: 23 | new_face = random.randint(1,self.num_faces) 24 | 25 | self.set_value(new_face) 26 | new_face_mob = self.get_face_mob() 27 | new_face_mob.move_to(self.face_mob.get_center()) 28 | new_face_mob.set_color(self.pip_color) 29 | anim_list = [ 30 | Rotate(self.border, angel = TAU/2), 31 | FadeOut(self.face_mob), 32 | GrowFromCenter(new_face_mob) 33 | ] 34 | self.face_mob = new_face_mob 35 | 36 | return anim_list 37 | 38 | def get_value(self): 39 | return self.face 40 | 41 | def set_value(self, v): 42 | self.face = v 43 | 44 | def get_face_mob(self): 45 | return TexMobject(self.get_value()) 46 | 47 | class D6(Dice): 48 | def get_face_mob(self): 49 | ''' 50 | Overwrite get_face_mob from the value itself to pips 51 | ''' 52 | # 1 2 3 53 | # 4 5 6 54 | # 7 8 9 55 | pos_pips = [[], [5], [1,9], [1,5,9], [1,3,7,9], [1,3,5,7,9], [1,3,4,6,7,9]] 56 | pips = VGroup() 57 | for pos in pos_pips[self.face]: 58 | x = (pos-1) % 3 59 | y = np.floor((pos-1)/3) 60 | pips.add( 61 | Dot(x*RIGHT + y*DOWN, radius = 0.3) 62 | ) 63 | # scale to fit dice face 64 | pips.scale(0.6) 65 | return pips 66 | 67 | class D4(Dice): 68 | def __init__(self, **kwargs): 69 | VGroup.__init__(self, **kwargs) 70 | self.num_faces = 4 71 | if face == None: 72 | face = random.randint(1,self.num_faces) 73 | self.face = face 74 | border = Triangle() 75 | face_mob = self.get_face_mob() 76 | face_mob.move_to(border.get_center()) 77 | self.face_mob = face_mob 78 | self.add(border, face_mob) 79 | 80 | class D20(Dice): 81 | def __init__(self, **kwargs): 82 | 83 | VGroup.__init__(self, **kwargs) 84 | self.num_faces = 20 85 | if face == None: 86 | face = random.randint(1,self.num_faces) 87 | self.face = face 88 | border = RegularPolygon(7) 89 | face_mob = self.get_face_mob() 90 | face_mob.move_to(border.get_center()) 91 | self.face_mob = face_mob 92 | self.add(border, face_mob) 93 | 94 | class PlayingCard(VGroup): 95 | CONFIG = { 96 | "value": 1, 97 | "suit": "spade", 98 | "face_up": False 99 | } 100 | 101 | def __init__(self, value = 1, suit = "spade", **kwargs): 102 | VGroup.__init__(self, **kwargs) 103 | 104 | possible_suits = ["spade", "heart", "diamond", "club"] 105 | if possible_suits.count(suit) == 0: 106 | print("Illegal suit. Use spade as a default") 107 | self.suit = "spade" 108 | else: 109 | self.suit = suit 110 | self.value = value 111 | self.border = Rectangle(height = 3, width = 2) 112 | self.border.set_color(BLUE).set_stroke(None, 1).set_fill(PINK) 113 | 114 | # add value 115 | text = ["A", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] 116 | t = TexMobject(text[self.value]).scale(1.2).align_to(self.border, UL) 117 | t.shift(RIGHT*0.1 + DOWN*0.1) 118 | 119 | # add card suit 120 | suit_string = "\\" + self.suit + "suit" 121 | test = TexMobject(suit_string) 122 | self.add(test) 123 | s = TexMobject(suit_string).move_to(self.border.get_center()) 124 | if self.suit == "heart" or self.suit == "diamond": 125 | s.set_color(RED) 126 | self.front = VGroup(t,s) 127 | 128 | # add card back 129 | back = self.border 130 | back.set_fill(GREEN).set_stroke(width = 0) 131 | self.back = VGroup(back) 132 | 133 | ''' 134 | if self.face_up: 135 | self.front.set_z(0.1) 136 | self.back.set_z(-0.1) 137 | else: 138 | self.front.set_z(-0.1) 139 | self.back.set_z(0.1) 140 | ''' 141 | 142 | self.add(self.border, self.front, self.back) 143 | 144 | ''' 145 | Input: none 146 | Output: either card back (if face down), or the face (if face up) 147 | ''' 148 | def get_value(self): 149 | return self.value, self.suit 150 | 151 | def Flip(self): 152 | ''' 153 | Supposed to return card flipping animation 154 | but I can't create a good one yet, so for now let's just deal with transparency 155 | 156 | def flip_transparency(mob): 157 | mob.back.set_opacity(1 - mob.back.get_fill_opacity()) 158 | mob.front.set_opacity(1 - mob.front.get_fill_opacity()) 159 | return mob 160 | ''' 161 | #return ApplyFunction(flip_transparency, self) 162 | return ApplyMethod(self.flip) 163 | -------------------------------------------------------------------------------- /myprojects/for_fun/song.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from time import perf_counter 3 | 4 | class MusicVideo(Scene): 5 | def construct(self): 6 | background = ImageMobject("Yukiho") 7 | background.set_width(FRAME_WIDTH) 8 | background.to_edge(UP, buff = 0) 9 | self.add_sound("Mebuki") 10 | 11 | hw = FRAME_HEIGHT*np.sqrt(3)/2 12 | hh = FRAME_HEIGHT/2 13 | hex_pos = [hh*UP + hw*LEFT, hh*DOWN + hw*RIGHT, hh*UP + hw*RIGHT, hh*DOWN + hw*LEFT, ORIGIN] 14 | hexes = VGroup() 15 | for i in range(5): 16 | newhex = RegularPolygon(6).set_opacity(1).set_height(FRAME_HEIGHT).set_color(Color("#d3dde9")) 17 | newhex.move_to(hex_pos[i]) 18 | hexes.add(newhex) 19 | 20 | self.add(hexes) 21 | self.add(background) 22 | self.wait(0.2) 23 | self.play(AnimationGroup( 24 | *[ApplyMethod(h.set_opacity, 0, run_time = 1) for h in hexes], 25 | lag_ratio = 0.5 26 | )) 27 | self.remove(hexes) 28 | 29 | song_title = Text("芽吹の季", font = "Yu Gothic UI Bold", stroke_width = 3, stroke_color = BLACK) 30 | song_title.shift(2*DOWN).scale(2.5) 31 | singer = Text("萩原雪歩", font = "Yu Gothic UI Bold").set_color(Color("#d3dde9")) 32 | singer.set_stroke(BLACK, width = 3).scale(1.5) 33 | title = VGroup(song_title, singer).arrange(DOWN) 34 | title.to_edge(DOWN) 35 | 36 | title_time = [6.1, 6.6, 7.5, 8] 37 | singer_time = [8.8, 9.4, 10.3, 10.9] 38 | for i in range(len(title_time)): 39 | self.wait(title_time[i] - self.time) 40 | self.play(DrawBorderThenFill(song_title[i]), run_time = 0.2) 41 | for i in range(len(singer_time)): 42 | self.wait(singer_time[i] - self.time) 43 | self.play(DrawBorderThenFill(singer[i]), run_time = 0.2) 44 | self.wait(3) 45 | self.play(FadeOut(title)) 46 | 47 | lyrics= [ 48 | ("微かに眩しい ひとり暗がりの中で",17), 49 | ("土を濡らし", 25), 50 | ("怯えていたけれど", 29.5), 51 | ("いつか芽吹く事も夢見てた", 34), 52 | ("想いは高い空へ(溶け消えてく)", 40.5), 53 | ("あと少しの一歩で春なのに", 46), 54 | ("思い切り泣いたあの日々も", 52), 55 | ("底にしまったあの種もいつか…",55), 56 | ("溢れる涙が花を咲かす!",61), 57 | ("心地よい風感じたら",68), 58 | ("見えなかった景色 そこに広がってる",73), 59 | ("沢山の光を浴びて",79), 60 | ("私なりの詩で もっと咲かせよう",84), 61 | ("季節は変わりゆく",91), 62 | ("ほらね 雪解けは芽吹の季",94), 63 | ("澄み渡る空 ひとり陽だまりの中で",116), 64 | ("呼吸ひとひら",124), 65 | ("目に見えてた息は",128), 66 | ("光となり 風と消えた",133), 67 | ("水面に写る花は(揺れ動いて)",139), 68 | ("それでも負けずに上を向いて",145), 69 | ("まっすぐな気持ちを届けたい",151), 70 | ("きっと平気 もう何も怖くない",154), 71 | ("満ちてく自信が花を咲かす!",159), 72 | ("心地よい風感じたら",167), 73 | ("見えていた景色も 彩られてゆく",172), 74 | ("沢山の勇気抱いて",178), 75 | ("私でも出来ること もっと見つけよう",183), 76 | ("季節は巡りゆく",190), 77 | ("でもね 前向いて咲いていたい",193), 78 | ("a late bloomer say yeah",198), 79 | ("a late bloomer say yeah",204), 80 | ("一歩一歩ずつ",210), 81 | ("私なりに伝えたい",213), 82 | (f'"ありがとう”を',217), 83 | ("時は経ち いつかは",231), 84 | ("儚く散りゆく 次のために",236), 85 | ("そんな気持ちは今はさよなら",242), 86 | ("ただ空に向かって", 248), 87 | ("出来るだけ背伸びをして",251), 88 | ("Ah…",257), 89 | ("心地よい風感じたら",261), 90 | ("見えなかった景色 そこに広がってる",266), 91 | ("沢山の光を浴びて",272), 92 | ("私なりの詩で もっと咲かせよう",278), 93 | ("季節は変わりゆき ほらね",284), 94 | ("雪解けは芽吹の季",289), 95 | ("そのまま強く咲き誇ろう",295), 96 | ("輝きに包まれながら…",309) 97 | ] 98 | 99 | # Yu Gothic UI Bold 100 | snowflake = ImageMobject("snowflake") 101 | lyric = Text("", font = "Century Gothic Bold") 102 | for i in range(len(lyrics)): 103 | ly, time = lyrics[i] 104 | self.wait(time - self.time) # wait until the first time stamp 105 | lyric = Text(ly, font = "Yu Gothic Bold").scale(1.5) 106 | lyric.set_color(Color("#d3dde9")) 107 | lyric.set_stroke(BLACK, width = 3) 108 | 109 | # special word 110 | if time == 284: 111 | lyric[6:10].set_color(BLUE_A) 112 | lyric.to_edge(DOWN) 113 | 114 | self.add(snowflake) 115 | self.play(AnimationGroup( 116 | MoveAlongPath(snowflake, Line(lyric.get_left(), lyric.get_right()), run_time = np.maximum(1.5,0.1*len(ly))), 117 | Write(lyric), run_time = 0.2*len(ly)), 118 | lag_ratio = 0 119 | ) 120 | self.play(FadeOut(snowflake), run_time = 0.2) 121 | 122 | # add kagayaki at the end 123 | if time == 309: 124 | light = Dot(color = WHITE).set_opacity(0.2).set_height(0.2).to_edge(UP).shift(UP) 125 | lights = [light.copy() for _ in range(30)] 126 | 127 | for l in lights: 128 | l.shift((np.random.rand()*14 - 7)*RIGHT) 129 | l.set_opacity(0.2 + np.random.rand()*0.1) 130 | l.set_height(0.2 + np.random.rand()*0.1) 131 | self.add(l) 132 | def update_function(mobject, alpha): 133 | mobject.shift(0.1*DOWN*alpha + 0.01*LEFT*np.sin(np.pi*alpha/2)) 134 | self.play(AnimationGroup( 135 | *[UpdateFromAlphaFunc( 136 | mobject = l, update_function = update_function, run_time = 4) 137 | for l in lights], 138 | lag_ratio = 0.1 139 | )) 140 | for l in lights: 141 | self.remove(l) 142 | 143 | display_time = 7 # show at most 7 seconds 144 | if i < len(lyrics)-1: 145 | display_time = np.minimum(lyrics[i+1][1] - self.time - 0.5, 6.5) 146 | else: 147 | display_time = 0 148 | self.wait(display_time) 149 | self.play(FadeOut(lyric), run_time = 0.5) 150 | self.wait(1) 151 | 152 | 153 | -------------------------------------------------------------------------------- /myprojects/cal/sinx_x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | 5 | class main(GraphScene): 6 | CONFIG = { 7 | "x_min": -1, 8 | "x_max": 1, 9 | "y_min": 0, 10 | "y_max": 1, 11 | "y_bottom_tick": -0, 12 | "x_axis_width": 4, 13 | "y_axis_height": 2, 14 | "graph_origin": ORIGIN, 15 | "function_color": WHITE, 16 | "axes_color": BLUE, 17 | "x_axis_label": None, 18 | "y_axis_label": None, 19 | "radius": 2 20 | } 21 | def construct(self): 22 | def create_sector(a): 23 | return Sector( 24 | start_angle=0, 25 | angle = a, 26 | outer_radius = self.radius, 27 | color = GREEN, 28 | fill_opacity = 0.8 29 | ) 30 | self.setup_axes(animate=True) 31 | f = ParametricFunction(self.func, t_min = 0, t_max = TAU/2) 32 | theta = ValueTracker(PI/6) 33 | # create points 34 | point_sin_top = Dot(f.get_point_from_function(theta.get_value()), radius = 0) 35 | # point_sin_bottom = Dot(self.coords_to_point(math.cos(theta.get_value()),0), radius = 0) 36 | point_tan_top = Dot(self.coords_to_point(1, math.tan(theta.get_value())), radius = 0) 37 | point_tan_bottom = Dot(self.coords_to_point(1,0), radius = 0) 38 | self.add(point_sin_top, point_tan_top, point_sin_bottom) 39 | 40 | # create shapes 41 | sect = create_sector(theta.get_value()) 42 | tri_sin = Polygon(ORIGIN) 43 | tri_tan = Polygon(ORIGIN) 44 | line_to_circle = Line(ORIGIN, point_sin_top) 45 | 46 | # create text 47 | mid = 2*DOWN 48 | pos = [mid - 2*RIGHT, mid-RIGHT, mid, mid+RIGHT, mid+2*RIGHT] 49 | # first set 50 | text_sin = TexMobject("{\\sin x", "\\over 2}").set_color(PINK).move_to(pos[0]) 51 | text_leq1 = TexMobject("\\leq").move_to(pos[1]) 52 | text_sector = TexMobject("{x", "\\over 2}").set_color(GREEN).move_to(pos[2]) 53 | text_leq2 = TexMobject("\\leq").move_to(pos[3]) 54 | text_tan = TexMobject("{\\tan x","\\over 2}").set_color(ORANGE).move_to(pos[4]) 55 | group1 = VGroup(text_sin, text_leq1, text_sector, text_leq2, text_tan) 56 | 57 | # second set 58 | text_sin2 = TexMobject("\\sin x","").move_to(pos[0]) 59 | text_sector2 = TexMobject("x","").move_to(pos[2]) 60 | text_tan2 = TexMobject("\\tan x","").move_to(pos[4]) 61 | group2 = VGroup(text_sin2, text_leq1, text_sector2, text_leq2, text_tan2) 62 | 63 | # third set 64 | text_sin3 = TexMobject("{\\sin x ","\\over \\sin x}").move_to(pos[0]) 65 | text_sector3 = TexMobject("{x","\\over \\sin x}").move_to(pos[2]) 66 | text_tan3 = TexMobject("{ \\tan x","\\over \\sin x").move_to(pos[4]) 67 | group3 = VGroup(text_sin3, text_leq1, text_sector3, text_leq2, text_tan3) 68 | text_sin35 = TexMobject("1").move_to(pos[0]) 69 | text_tan35 = TexMobject("{1 \\over \\cos x").move_to(pos[4]) 70 | 71 | # fourth set 72 | text_sin4 = TexMobject("","1").move_to(pos[0]) 73 | text_sector4 = TexMobject("", "{\\sin x \\over x}").move_to(pos[2]) 74 | text_tan4 = TexMobject("","\\cos x").move_to(pos[4]) 75 | text_geq1 = TexMobject("\\geq").move_to(pos[1]) 76 | text_geq2 = TexMobject("\\geq").move_to(pos[3]) 77 | group4 = VGroup(text_sin4, text_geq1, text_sector4, text_geq2, text_tan4) 78 | 79 | # fifth 80 | text_limit1 = TexMobject("\\lim_{x \\rightarrow 0} 1", 81 | "\\geq", 82 | "\\lim_{x \\rightarrow 0} {\\sin x \\over x}", 83 | "\\geq", 84 | "\\lim_{x \\rightarrow 0} \\cos x" 85 | ).move_to(pos[2]) 86 | 87 | text_limit2 = TexMobject("1", 88 | "\\geq", 89 | "\\lim_{x \\rightarrow 0} {\\sin x \\over x}", 90 | "\\geq", 91 | "1" 92 | ).move_to(pos[2]) 93 | 94 | text_final = TexMobject("\\lim_{x \\rightarrow 0} {\\sin x \\over x} = 1").move_to(pos[2]) 95 | text_final.scale(2) 96 | 97 | # add updaters on points 98 | point_sin_top.add_updater(lambda v: v.move_to( 99 | f.get_point_from_function(theta.get_value()) 100 | )) 101 | #point_sin_bottom.add_updater(lambda v: v.move_to( 102 | # self.coords_to_point(math.cos(theta.get_value()),0) 103 | #)) 104 | point_tan_top.add_updater(lambda v: v.move_to( 105 | self.coords_to_point(1, math.tan(theta.get_value())) 106 | )) 107 | 108 | # add updaters on shapes 109 | sect.add_updater(lambda v: v.become(create_sector(theta.get_value()))) 110 | tri_sin.add_updater(lambda v: v.become( 111 | Polygon(ORIGIN, point_sin_top.get_center(), point_tan_bottom.get_center()) 112 | .set_fill(PINK, opacity=0.8) 113 | )) 114 | tri_tan.add_updater(lambda v: v.become( 115 | Polygon(ORIGIN, point_tan_top.get_center(), point_tan_bottom.get_center()) 116 | .set_fill(ORANGE, opacity=0.8) 117 | )) 118 | 119 | # start animation 120 | self.play(ShowCreation(f)) 121 | self.play(ShowCreation(line_to_circle), ShowCreation(tri_sin)) 122 | self.play(ReplacementTransform(tri_sin, text_sin)) 123 | self.play(ShowCreation(sect)) 124 | self.play(ReplacementTransform(sect, text_sector)) 125 | self.play(ShowCreation(tri_tan)) 126 | self.play(ReplacementTransform(tri_tan,text_tan)) 127 | self.play(ShowCreation(tri_tan)) 128 | self.play(ShowCreation(sect)) 129 | self.play(Write(text_leq2)) 130 | self.play(ShowCreation(tri_sin)) 131 | self.play(Write(text_leq1)) 132 | self.remove(line_to_circle) 133 | fr1 = SurroundingRectangle(text_leq1, buff = .1) 134 | fr2 = SurroundingRectangle(text_leq2, buff = .1) 135 | 136 | self.play(ShowCreation(fr1), ShowCreation(fr2)) 137 | self.play( 138 | theta.set_value,0, 139 | rate_func=there_and_back, 140 | run_time=3 141 | ) 142 | self.play(FadeOut(fr1), FadeOut(fr2)) 143 | 144 | self.play(ReplacementTransform(group1, group2)) 145 | self.wait(1) 146 | self.play(ReplacementTransform(group2, group3)) 147 | self.wait(1) 148 | self.play(ReplacementTransform(text_tan3, text_tan35), ReplacementTransform(text_sin3, text_sin35)) 149 | self.wait(1) 150 | group3.add(text_tan35, text_sin35) 151 | self.play(ReplacementTransform(group3, group4)) 152 | self.wait(1) 153 | self.play(ReplacementTransform(group4, text_limit1)) 154 | self.wait(1) 155 | self.play(ReplacementTransform(text_limit1, text_limit2)) 156 | self.wait(1) 157 | self.play(ReplacementTransform(text_limit2, text_final)) 158 | fr3 = SurroundingRectangle(text_final, buff = .3) 159 | self.play(ShowCreation(fr3)) 160 | self.wait(2) 161 | 162 | def func(self, t): 163 | return [self.radius*math.cos(t), self.radius*math.sin(t), 0] 164 | -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/polynomial_addition.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class poly_sum_ex1(Scene): 4 | def construct(self): 5 | 6 | # Scene 1: show equations 7 | text1 = Text("จงหาผลบวกของ", font="TH Sarabun New").scale(1.5) 8 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 9 | 10 | poly1 = TexMobject("2x^2","+","3x","-","4") 11 | poly2 = TexMobject("3x^2", "-","2x","+","1") 12 | 13 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 14 | group1.to_edge(UP).shift(DOWN) 15 | 16 | # scene 1: animate question 17 | self.play(Write(group1)) 18 | self.wait(0.5) 19 | self.play(Indicate(poly1)) 20 | self.wait(2) 21 | self.play(Indicate(poly2)) 22 | self.wait(2) 23 | 24 | # Scene 2: express the sum and recolor 25 | 26 | term1 = TexMobject("(","2x^2","+","3x","-","4",")","+","(", "3x^2", "-","2x","+","1",")") 27 | term2 = TexMobject("(","2x^2","+","3x","+","(-4)",")","+","(", "3x^2", "+","(-2)x","+","1",")") 28 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 29 | 30 | term1.to_edge(LEFT).shift(UP) 31 | term2.to_edge(LEFT).shift(UP) 32 | eq1 = TexMobject("(","2x^2","+","3x^2",")","+","(","3x","+","(-2)x",")","+","(","(-4)","+","1",")") 33 | eq2 = TexMobject("(","2","+","3",")","x^2","+","(","3","+","(-2)",")","x","+","(","(-4)","+","1",")") 34 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 35 | eq3 = TexMobject("5","x^2","+","1","x","+","(-3)") 36 | eq4 = TexMobject("5","x^2","+","x","-","3") 37 | 38 | eqsign1 = TexMobject("=").to_edge(LEFT) 39 | eqsign2 = TexMobject("=").to_edge(LEFT).shift(DOWN) 40 | eqsign3 = TexMobject("=").to_edge(LEFT).shift(2*DOWN) 41 | eqsign4 = TexMobject("=").to_edge(LEFT).shift(3*DOWN) 42 | 43 | eq1.next_to(eqsign1, RIGHT) 44 | eq2.next_to(eqsign2, RIGHT) 45 | eq3.next_to(eqsign3, RIGHT) 46 | eq4.next_to(eqsign4, RIGHT) 47 | 48 | framebox1 = SurroundingRectangle(term2[1], buff = .1) 49 | framebox2 = SurroundingRectangle(term2[3], buff = .1, color = BLUE) 50 | framebox3 = SurroundingRectangle(term2[5], buff = .1, color = RED) 51 | framebox4 = SurroundingRectangle(term2[9], buff = .1) 52 | framebox5 = SurroundingRectangle(term2[11], buff = .1, color = BLUE) 53 | framebox6 = SurroundingRectangle(term2[13], buff = .1, color = RED) 54 | 55 | framebox7 = SurroundingRectangle(eq1[0:5], buff = .1) 56 | framebox8 = SurroundingRectangle(eq1[6:11], buff = .1, color = BLUE) 57 | framebox9 = SurroundingRectangle(eq1[12:], buff = .1, color = RED) 58 | 59 | ''' 60 | # scene 2: equation 1 61 | ''' 62 | self.play(Write(term1[0]), Write(term1[6])) 63 | self.play(ReplacementTransform(poly1.copy(), term1[1:6])) 64 | self.play(Write(term1[7])) 65 | self.play(Write(term1[8]), Write(term1[14])) 66 | self.play(ReplacementTransform(poly2.copy(), term1[9:14])) 67 | self.wait(1) 68 | self.play(Indicate(term1[4:6])) 69 | self.wait(1) 70 | self.play(Indicate(term1[10:12])) 71 | self.wait(1) 72 | self.play(ReplacementTransform(term1, term2)) 73 | self.wait(3) 74 | 75 | # 76 | # eq1: copy x^2 term 77 | # 78 | self.play(Write(eqsign1)) 79 | 80 | # emphasize x^2 81 | self.play(ShowCreationThenFadeOut(framebox1)) 82 | term2[1].set_color(YELLOW) 83 | self.wait(1) 84 | self.play(ShowCreationThenFadeOut(framebox4)) 85 | term2[9].set_color(YELLOW) 86 | self.wait(1) 87 | 88 | # write parentheses 89 | self.play(Write(eq1[0]), Write(eq1[4])) 90 | eq1[1].set_color(YELLOW) 91 | eq1[3].set_color(YELLOW) 92 | 93 | # move the terms 94 | self.play(ReplacementTransform(term2[1].copy(), eq1[1]), path_arc=-np.pi) 95 | self.play(Write(eq1[2])) 96 | self.play(ReplacementTransform(term2[9].copy(), eq1[3]), path_arc=-np.pi) 97 | self.wait(1) 98 | 99 | # 100 | # eq1: copy x term 101 | # 102 | 103 | self.play(ShowCreationThenFadeOut(framebox2)) 104 | self.play(term2[3].set_color, BLUE, run_time=1) 105 | 106 | self.play(ShowCreationThenFadeOut(framebox5)) 107 | self.play(term2[11].set_color, BLUE, run_time=1) 108 | 109 | self.play(Write(eq1[5])) 110 | self.play(Write(eq1[6]), Write(eq1[10])) 111 | eq1[7].set_color(BLUE) 112 | eq1[9].set_color(BLUE) 113 | 114 | self.play(ReplacementTransform(term2[3].copy(), eq1[7]), path_arc=-np.pi) 115 | self.play(Write(eq1[8])) 116 | self.play(ReplacementTransform(term2[11].copy(), eq1[9]), path_arc=-np.pi) 117 | self.wait(1) 118 | 119 | # 120 | # eq1: copy constant 121 | # 122 | self.play(ShowCreationThenFadeOut(framebox3)) 123 | self.play(term2[5].set_color, RED, run_time=1) 124 | 125 | self.play(ShowCreationThenFadeOut(framebox6)) 126 | self.play(term2[13].set_color, RED, run_time=1) 127 | 128 | self.play(Write(eq1[11])) 129 | self.play(Write(eq1[12]), Write(eq1[16])) 130 | eq1[13].set_color(RED) 131 | eq1[15].set_color(RED) 132 | 133 | self.play(ReplacementTransform(term2[5].copy(), eq1[13]), path_arc=-np.pi) 134 | self.play(Write(eq1[14])) 135 | self.play(ReplacementTransform(term2[13].copy(), eq1[15]), path_arc=-np.pi) 136 | self.wait(1) 137 | 138 | ''' 139 | # scene 2: equation 2 140 | ''' 141 | 142 | self.play(Write(eqsign2)) 143 | self.play(ShowCreationThenFadeOut(framebox7)) 144 | self.play(ReplacementTransform(eq1[0:5].copy(), eq2[0:6])) 145 | self.wait(1) 146 | 147 | self.play(Write(eq2[6])) 148 | self.play(ShowCreationThenFadeOut(framebox8)) 149 | self.play(ReplacementTransform(eq1[6:11].copy(), eq2[7:13])) 150 | self.wait(1) 151 | 152 | self.play(ShowCreationThenFadeOut(framebox9)) 153 | self.play(Write(eq2[13])) 154 | self.play(ReplacementTransform(eq1[12:].copy(), eq2[14:])) 155 | self.wait(1) 156 | ''' 157 | # scene 3: equation 3 158 | ''' 159 | self.play(Write(eqsign3)) 160 | self.play(ReplacementTransform(eq2[0:6].copy(), eq3[0:2])) 161 | self.wait(1) 162 | 163 | self.play(Write(eq3[2])) 164 | self.play(ReplacementTransform(eq2[7:13].copy(), eq3[3:5])) 165 | self.wait(1) 166 | 167 | self.play(Write(eq3[5])) 168 | self.play(ReplacementTransform(eq2[14:].copy(), eq3[6])) 169 | self.wait(2) 170 | 171 | ''' 172 | # scene 4: equation 4 173 | ''' 174 | self.play(Write(eqsign4)) 175 | self.wait(0.5) 176 | self.play(ReplacementTransform(eq3[0:2].copy(), eq4[0:2])) 177 | self.wait(0.5) 178 | self.play(ReplacementTransform(eq3[2:5].copy(), eq4[2:4])) 179 | self.wait(0.5) 180 | self.play(ReplacementTransform(eq3[5:].copy(), eq4[4:])) 181 | self.wait(0.5) 182 | 183 | frameboxfinal = SurroundingRectangle(eq4, buff = .1) 184 | self.play(ShowCreation(frameboxfinal)) 185 | self.wait(2) -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/polynomial_multiplication.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class poly_mult_ex2(Scene): 4 | def construct(self): 5 | 6 | # Scene 1: show equations 7 | text1 = Text("จงหาผลคูณของ", font="TH Sarabun New").scale(1.5) 8 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 9 | 10 | poly1 = TexMobject("x^2","+","2x","-","4") 11 | poly2 = TexMobject("-3x", "+","5") 12 | 13 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 14 | group1.to_edge(UP).shift(DOWN) 15 | text1.shift(0.15*DOWN) # shift manually.... 16 | text2.shift(0.05*DOWN) # shift manually.... 17 | poly2.shift(0.05*DOWN) # shift manually.... 18 | 19 | # scene 1: animate question 20 | self.play(Write(group1)) 21 | self.wait(0.5) 22 | self.play(Indicate(poly1)) 23 | self.play(Indicate(poly2)) 24 | self.wait(1) 25 | 26 | # 27 | # Scene 2: express the sum and recolor 28 | # 29 | term1 = TexMobject("(","x^2","+","2x","-","4",")","\\times","(","-3x", "+","5",")") 30 | term2 = TexMobject("(","x^2","+","2x","+","(-4)",")","\\times","(","(-3x)", "+","5",")") 31 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 32 | term1.to_edge(LEFT).shift(UP) 33 | term2.to_edge(LEFT).shift(UP) 34 | 35 | self.play(ReplacementTransform(poly1.copy(), term1[0:7])) 36 | self.play(Write(term1[7])) 37 | self.play(ReplacementTransform(poly2.copy(), term1[8:])) 38 | self.wait(1) 39 | 40 | fb = SurroundingRectangle(term1[4:6], buff = .1) 41 | self.play(ShowCreationThenFadeOut(fb)) 42 | fb = SurroundingRectangle(term1[9], buff = .1) 43 | self.play(ShowCreationThenFadeOut(fb)) 44 | self.wait(1) 45 | self.play(ReplacementTransform(term1, term2)) 46 | self.wait(1) 47 | 48 | # 49 | # Scene 3: create table and move the terms to the header 50 | # 51 | 52 | row1 = TexMobject("\\times", "x^2", "2x", "(-4)") 53 | row2 = TexMobject("(-3x)", "(-3x)\\times(x^2)", "(-3x)\\times(2x)", "(-3x)\\times(-4)") 54 | row2s = TexMobject("(-3x)", "-3x^3", "-6x^2", "12x") 55 | row3 = TexMobject("5", "5\\times(x^2)", "5\\times(2x)", "5\\times(-4)") 56 | row3s = TexMobject("5", "5x^2", "10x", "-20") 57 | tex_table = [row1, row2, row3] 58 | tex_tables = [row1, row2s, row3s] #row1 isn't used here, but it's put so that the for loop works nicely 59 | 60 | # create a table structure 61 | topleft = LEFT*6 62 | for i in range (0, len(row1)): 63 | for j in range (0, 3): 64 | tex_table[j][i].move_to(topleft + RIGHT*3.5*i + DOWN*j) 65 | tex_tables[j][i].move_to(topleft + RIGHT*3.5*i + DOWN*j) 66 | 67 | # move original terms to the table 68 | hline = Line(topleft + LEFT + DOWN*0.5, topleft + RIGHT*12.5+ DOWN*0.5) 69 | vline = Line(topleft + RIGHT*1.5 + UP*0.5, topleft + RIGHT*1.5 + DOWN*2.5) 70 | self.play(ShowCreation(hline), ShowCreation(vline)) 71 | self.wait(1) 72 | 73 | self.play(ReplacementTransform(term2[1].copy(),row1[1])) 74 | self.play(ReplacementTransform(term2[3].copy(),row1[2])) 75 | self.play(ReplacementTransform(term2[5].copy(),row1[3])) 76 | self.wait(1) 77 | self.play(ReplacementTransform(term2[9].copy(),row2[0])) 78 | self.play(ReplacementTransform(term2[11].copy(),row3[0])) 79 | self.wait(1) 80 | 81 | # 82 | # scene 4 : animation on multiplication table 83 | # 84 | self.wait(1) 85 | framebox1 = SurroundingRectangle(tex_table[1][0], buff = .1) 86 | for i in range (1, 3): 87 | # create a box for the term in the first column (on the left) 88 | # for subsequent rows, move the box down 89 | if i == 1: 90 | self.play(ShowCreation(framebox1)) 91 | else: 92 | frameboxtemp = framebox1 93 | framebox1 = SurroundingRectangle(tex_table[i][0], buff = .1) 94 | self.play(ReplacementTransform(frameboxtemp, framebox1)) 95 | self.wait(0.5) 96 | framebox2 = SurroundingRectangle(tex_table[0][1], buff = .1) 97 | for j in range (1, len(row1)): 98 | # create a box for the term in the first row (on top) 99 | # for subsequent columns, move the box to the right 100 | if j == 1: 101 | self.play(ShowCreation(framebox2)) 102 | else: 103 | frameboxtemp = framebox2 104 | framebox2 = SurroundingRectangle(tex_table[0][j], buff = .1) 105 | self.play(ReplacementTransform(frameboxtemp,framebox2)) 106 | self.wait(0.5) 107 | framebox3 = SurroundingRectangle(tex_table[i][j], buff = .1, color = BLUE) 108 | # highlight the entry and show the product 109 | self.play( 110 | ReplacementTransform(framebox1.copy(), framebox3), 111 | ReplacementTransform(framebox2.copy(), framebox3) 112 | ) 113 | self.play(Write(tex_table[i][j])) 114 | self.wait(0.5) 115 | self.play(FadeOut(framebox3)) 116 | self.play(FadeOut(framebox2)) 117 | self.play(FadeOut(framebox1)) 118 | 119 | # 120 | # scene 5 : simplify the entries in the table 121 | # 122 | for i in range (1, 3): 123 | for j in range (1, len(row1)): 124 | framebox = SurroundingRectangle(tex_table[i][j], buff = .1, color = GREEN) 125 | self.play(ShowCreation(framebox)) 126 | self.play(ReplacementTransform(tex_table[i][j], tex_tables[i][j])) 127 | self.play(FadeOut(framebox)) 128 | self.wait(1) 129 | 130 | # 131 | # scene 6 : collect the terms 132 | # 133 | 134 | ans1 = TexMobject("=","(-3x^3)", "+", "(-6x^2)", "+", "12x", "+", "5x^2", "+", "10x", "+", "(-20)") 135 | ans1.to_edge(BOTTOM + LEFT).shift(0.8*DOWN) 136 | 137 | ans1up = ans1.copy() 138 | ans1up.to_edge(LEFT).shift(2.5*UP) 139 | for i in range (0,2): 140 | for j in range (0,3): 141 | # write sign 142 | self.play(Write(ans1[6*i+2*j])) 143 | # move the term to the sign 144 | self.play(ReplacementTransform(tex_tables[i+1][j+1], ans1[6*i + 2*j +1])) 145 | self.wait(1) 146 | 147 | # 148 | # scene 7 : clear the table and simplify 149 | # 150 | 151 | self.play(FadeOut(row1[1]), FadeOut(row1[2]), FadeOut(row1[3]), FadeOut(row2[0]), FadeOut(row3[0]), FadeOut(hline), FadeOut(vline)) 152 | self.play(ReplacementTransform(ans1, ans1up)) 153 | self.wait(1) 154 | 155 | ans2 = TexMobject("=", "(-3x^3)", "+", "(-x^2)", "+", "22x", "+", "(-20)") 156 | ans2.to_edge(LEFT).shift(DOWN) 157 | 158 | self.play(Write(ans2[0])) 159 | # x^3 160 | ans1up[1].set_color(YELLOW) 161 | ans2[1].set_color(YELLOW) 162 | self.wait(0.5) 163 | self.play(ReplacementTransform(ans1up[1].copy(), ans2[1])) 164 | self.play(Write(ans2[2])) 165 | self.wait(1) 166 | # x^2 167 | ans1up[3].set_color(GREEN) 168 | ans1up[7].set_color(GREEN) 169 | ans2[3].set_color(GREEN) 170 | self.wait(0.5) 171 | self.play(ReplacementTransform(ans1up[3].copy(), ans2[3]), ReplacementTransform(ans1up[7].copy(), ans2[3])) 172 | self.play(Write(ans2[4])) 173 | self.wait(1) 174 | # x 175 | ans1up[5].set_color(RED) 176 | ans1up[9].set_color(RED) 177 | ans2[5].set_color(RED) 178 | self.wait(0.5) 179 | self.play(ReplacementTransform(ans1up[5].copy(), ans2[5]), ReplacementTransform(ans1up[9].copy(), ans2[5])) 180 | self.play(Write(ans2[6])) 181 | self.wait(1) 182 | # 1 183 | ans1up[11].set_color(BLUE) 184 | ans2[7].set_color(BLUE) 185 | self.wait(0.5) 186 | self.play(ReplacementTransform(ans1up[11].copy(), ans2[7])) 187 | self.wait(1) 188 | 189 | # simplify 190 | ans3 = TexMobject("=", "-3x^3", "-", "x^2", "+", "22x", "-", "20") 191 | ans3.to_edge(LEFT).shift(DOWN*2) 192 | 193 | self.play(Write(ans3[0])) 194 | self.wait(0.5) 195 | self.play(ReplacementTransform(ans2[1:].copy(), ans3[1:])) 196 | self.wait(1) 197 | frameboxfinal = SurroundingRectangle(ans3[1:], buff = .1) 198 | self.play(ShowCreation(frameboxfinal)) 199 | self.wait(2) 200 | -------------------------------------------------------------------------------- /myprojects/cal/circle_formula.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from manimlib.imports import * 4 | 5 | class main(GraphScene): 6 | CONFIG = { 7 | "x_min": -1, 8 | "x_max": 1, 9 | "y_min": 0, 10 | "y_max": 1, 11 | "y_bottom_tick": -0, 12 | "x_axis_width": 8, 13 | "y_axis_height": 4, 14 | "graph_origin": ORIGIN + DOWN, 15 | "function_color": WHITE, 16 | "axes_color": BLUE, 17 | "radius": 2 18 | } 19 | 20 | def construct(self): 21 | self.integral_normal() 22 | self.wait() 23 | # clear scene? 24 | self.integral_polar() 25 | self.wait() 26 | 27 | def integral_normal(self): 28 | self.setup_axes(animate = True) 29 | 30 | eq_original = TexMobject("y = \\sqrt{1-x^2}") 31 | eq_original.to_edge(UL) 32 | self.play(Write(eq_original)) 33 | 34 | graph = self.get_graph(self.func, color = None, x_min = -1, x_max = 1) 35 | self.play(ShowCreation(graph)) 36 | 37 | # demo with points 38 | for i in range(1,3): 39 | dots_axis = VGroup() 40 | dots_curve = VGroup() 41 | lines = VGroup() 42 | prev_dot = Dot(self.coords_to_point(-1, 0)) 43 | # create points on x-axis 44 | for k in range(2**(i+1)+1): 45 | x = -1 + (k/2**i) 46 | da = Dot(self.coords_to_point(x, 0), radius = 0.1).set_color(PINK) 47 | dots_axis.add(da) 48 | self.play(FadeIn(da), run_time = 0.1) 49 | # create points on the curve 50 | for k in range(2**(i+1)+1): 51 | x = -1 + (k/2**i) 52 | dc = Dot(self.coords_to_point(x, self.func(x)), radius = 0.1).set_color(GREEN) 53 | dots_curve.add(dc) 54 | self.play(FadeIn(dc), run_time = 0.1) 55 | if k > 0: 56 | new_line = Line(prev_dot, dc) 57 | self.play(FadeIn(new_line), run_time = 0.1) 58 | lines.add(new_line) 59 | prev_dot = dc 60 | self.play(FadeOut(dots_axis), FadeOut(dots_curve), FadeOut(lines)) 61 | 62 | for i in range(3,6): 63 | k=1 64 | 65 | # animation showing arc length formula 66 | x0 = -1 + (1/2**2) 67 | p1 = Dot(self.coords_to_point(-1, 0)) 68 | p2 = Dot(self.coords_to_point(x0, 0)) 69 | p3 = Dot(self.coords_to_point(x0, self.func(x0))) 70 | l1 = Line(p1.get_center(), p2.get_center()).set_color(PINK) 71 | l2 = Line(p2, p3).set_color(GREEN) 72 | l3 = Line(p3, p1).set_color(BLUE) 73 | x_brace = DoubleArrow(p1, p2, buff = 0).shift(DOWN*0.2) 74 | x_text = TexMobject("dx").next_to(x_brace, DOWN) 75 | y_brace = DoubleArrow(p2, p3, buff = 0).shift(RIGHT*0.2) 76 | y_text = TexMobject("dy").next_to(y_brace, RIGHT) 77 | z_brace = DoubleArrow(p3, p1, buff = 0).shift(UP*0.2 + LEFT*0.2) 78 | z_text = TexMobject("\\sqrt{(dx)^2 + (dy)^2}") 79 | z_text.next_to(z_brace.get_center(), UL).scale(0.8) 80 | all_texts = VGroup(x_brace, x_text, y_brace, y_text, z_brace, z_text) 81 | self.play(ShowCreation(l1)) 82 | self.play(FadeIn(x_brace), FadeIn(x_text)) 83 | self.play(ShowCreation(l2)) 84 | self.play(FadeIn(y_brace), FadeIn(y_text)) 85 | self.play(ShowCreation(l3)) 86 | self.play(FadeIn(z_brace), FadeIn(z_text)) 87 | self.wait(1) 88 | self.play(Uncreate(l1), Uncreate(l2), Uncreate(l3), Uncreate(all_texts)) 89 | 90 | # animate equation 91 | # move camera down first? 92 | 93 | eq_diff = TexMobject("\\frac{dy}{dx} = -\\frac{x}{\\sqrt{1-x^2}}") 94 | eqs = [] 95 | eqs.append(TexMobject("\\sum \\sqrt{dy^2 + dx^2}")) 96 | eqs.append(TexMobject("\\int_{-1}^1 \\sqrt{","(dy)^2","+","(dx)^2", "}x")) 97 | eqs.append(TexMobject("\\int_{-1}^1 \\sqrt{","\\frac{(dy)^2}{(dx)^2}(dx)^2","+","\\frac{(dx)^2}{(dx)^2} (dx)^{2}", "}x")) 98 | eqs.append(TexMobject("\\int_{-1}^1 \\sqrt{","\\left( \\frac{dy}{dx} \\right)^2","+","1", "}\\, dxx")) 99 | eqs.append(TexMobject("\\int_{-1}^1 \\sqrt{","\\left( -\\frac{x}{\\sqrt{1-x^2}} \\right)^2","+","1", "}\\, dxx")) 100 | eqs.append(TexMobject("\\int_{-1}^1 \\sqrt{","\\left( \\frac{x^2}{1-x^2} \\right)","+","1", "}\\, dxx")) 101 | eqs.append(TexMobject("\\int_{-1}^1 \\frac{1}{\\sqrt{1-x^2}} \\, dxx")) 102 | eqs.append(TexMobject("\\arcsin x \\Big|_{-1}^{1}")) 103 | eqs.append(TexMobject("\\arcsin 1 - \\arcsin (-1)")) 104 | eqs.append(TexMobject("\\frac{\\pi}{2} - \\frac{-\\pi}{2}")) 105 | eqs.append(TexMobject("\\pi")) 106 | g1 = VGroup(*eqs) 107 | g1.scale(1.2).to_edge(DOWN) 108 | 109 | # start equation animation 110 | g0 = VGroup(eq_original, eq_diff, buff=2).arrange(DOWN).to_edge(UL) 111 | self.play(ReplacementTransform(eq_original, g0)) 112 | self.play(ReplacementTransform(lines, eqs[0])) 113 | for i in range(len(eqs)-1): 114 | self.play(ReplacementTransform(eqs[i], eqs[i+1])) 115 | self.wait(0.5) 116 | self.wait() 117 | 118 | 119 | def func(self, x): 120 | return (math.sqrt(1-x**2)) 121 | 122 | 123 | def integral_polar(self): 124 | self.setup_axes(animate = True) 125 | 126 | eq_original = TexMobject("\\vec{r}(\\theta) = \\cos \\theta \\vec{i} + \\sin \\theta \\vec{j}") 127 | eq_diff_norm = TexMobject("|| \\vec{r}\\,'(\\theta) || = 1") 128 | g_original = VGroup(eq_original, eq_diff_norm).arrange(DOWN) 129 | g_original.to_edge(UL) 130 | self.play(Write(eq_original)) 131 | 132 | graph = self.get_graph(self.func, color = None, x_min = -1, x_max = 1) 133 | self.play(ShowCreation(graph)) 134 | 135 | # demo with points 136 | for i in range(1,3): 137 | rays = VGroup() 138 | dots_curve = VGroup() 139 | lines = VGroup() 140 | 141 | prev_dot = Dot(self.coords_to_point(1, 0), radius = 0.1).set_color(BLUE) 142 | for k in range(2**(i+1)+1): 143 | theta = (PI*k/(2**(i+1))) 144 | ray = Arrow(self.graph_origin, self.coords_to_point(math.cos(theta), math.sin(theta)), buff = 0).set_color(PINK) 145 | rays.add(ray) 146 | self.play(ShowCreation(ray), run_time = 0.1) 147 | for k in range(2**(i+1)+1): 148 | theta = (PI*k/(2**(i+1))) 149 | dc = Dot(self.coords_to_point(math.cos(theta), math.sin(theta)), radius = 0.1).set_color(GREEN) 150 | dots_curve.add(dc) 151 | self.play(FadeIn(dc), run_time = 0.2) 152 | if k > 0: 153 | new_line = Line(prev_dot, dc) 154 | self.play(FadeIn(new_line), run_time = 0.1) 155 | lines.add(new_line) 156 | prev_dot = dc 157 | self.play(FadeOut(rays), FadeOut(dots_curve), FadeOut(lines)) 158 | 159 | # animation showing arc length formula 160 | theta_0 = TAU/12 161 | p1 = Dot(self.coords_to_point(1, 0)) 162 | p2 = Dot(self.coords_to_point(math.cos(theta_0), math.sin(theta_0))) 163 | l1 = Arrow(self.graph_origin, p1.get_center(), buff = 0).set_color(PINK) 164 | l2 = Arrow(self.graph_origin, p2.get_center(), buff = 0).set_color(GREEN) 165 | l3 = Arrow(p1.get_center(), p2.get_center(), buff = 0).set_color(BLUE) 166 | l1_text = TexMobject("\\vec{r}(\\theta)").next_to(l1, DOWN, buff = 0.2) 167 | l2_text = TexMobject("\\vec{r}(\\theta + \\Delta\\theta)").next_to(l2, UP, buff = 0.2) 168 | dr_text = TexMobject("\\vec{r}\\,'(\\theta)").next_to(l3, RIGHT) 169 | g = VGroup(l1, l2, l3, l1_text, l2_text) 170 | self.play(ShowCreation(l1)) 171 | self.play(Write(l1_text)) 172 | self.play(ShowCreation(l2)) 173 | self.play(Write(l2_text)) 174 | self.play(ShowCreation(l3)) 175 | self.play(FadeIn(dr_text)) 176 | self.wait(1) 177 | self.play(FadeOut(g)) 178 | 179 | # animate equations 180 | 181 | eq_diff = TexMobject("\\vec{r}\\,'(\\theta) = -\\sin \\theta \\vec{i} + \\cos\\theta\\vec{j}") 182 | eq_diff_norm_new = TexMobject("|| \\vec{r}\\,'(\\theta) || = \\sqrt{(-\\sin\\theta)^{2} + (\\cos\\theta)^{2}} = 1") 183 | eq_diff_norm_new.generate_target() 184 | eq_diff_norm_new.target = eq_diff_norm 185 | ''' 186 | eqs.append(TexMobject("\\sum ||\\vec{r} \\,'(\\theta) ||")) 187 | eqs.append(TexMobject("\\int_{0}^{\\pi} ||\\vec{r} \\,' || \\, d\\theta")) 188 | eqs.append(TexMobject("\\pi")) 189 | ''' 190 | g1 = VGroup(eq_diff, eq_diff_norm_new).arrange(DOWN) 191 | g1.scale(1.2).to_edge(DOWN) 192 | self.play(Write(g1)) 193 | self.wait(1) 194 | self.play(MoveToTarget(eq_diff_norm_new), FadeOut(eq_diff)) 195 | self.wait() 196 | # start equation animation 197 | #g0 = VGroup(eq_original, eq_diff, buff=2).arrange(DOWN).to_edge(UL) 198 | #self.play(ReplacementTransform(eq_original, g0)) 199 | #self.play(ReplacementTransform(lines, eqs[0])) 200 | ''' 201 | for i in range(len(eqs)-1): 202 | self.play(ReplacementTransform(eqs[i], eqs[i+1])) 203 | self.wait(0.5) 204 | self.wait() 205 | ''' 206 | # now use parametric 207 | #f_para = ParametricFunction(self.func, t_min = 0, t_max = TAU) 208 | 209 | 210 | def func(self, x): 211 | return (math.sqrt(1-x**2)) -------------------------------------------------------------------------------- /myprojects/cal/derivative_basic_properties.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class scalar_multiplication(Scene): 4 | def construct(self): 5 | t = Text("1. การคูณด้วยค่าคงที่", font="TH Sarabun New") 6 | t.scale(3) 7 | t.to_edge(UP) 8 | self.play(Write(t)) 9 | text = tex_scalar_mul() 10 | 11 | text.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 12 | self.play(Write(text[0:6])) 13 | self.wait(0.5) 14 | self.play(Write(text[6])) 15 | self.wait(0.5) 16 | self.play(Transform(text[2].copy(), text[7]), run_time = 1, path_arc=-np.pi) 17 | self.play(Transform(text[0].copy(), text[8]), run_time = 1) 18 | self.play(Transform(text[4].copy(), text[9]), run_time = 1, path_arc=-np.pi) 19 | self.wait() 20 | 21 | class addition(Scene): 22 | def construct(self): 23 | t = Text("2. อนุพันธ์ของผลบวกฟังก์ชัน", font="TH Sarabun New") 24 | t.scale(3) 25 | t.to_edge(UP) 26 | self.play(Write(t)) 27 | 28 | text = tex_add() 29 | text.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 30 | 31 | self.play(Write(text[0:6])) 32 | self.wait(0.5) 33 | self.play(Write(text[6])) 34 | self.wait(0.5) 35 | self.play(Transform(text[0].copy(), text[7]), run_time = 1) 36 | self.play(Transform(text[2].copy(), text[8]), run_time = 2, path_arc=-np.pi) 37 | self.play(Write(text[9])) 38 | self.play(Transform(text[0].copy(), text[10]), run_time = 1) 39 | self.play(Transform(text[4].copy(), text[11]), run_time = 2, path_arc=-np.pi) 40 | self.wait() 41 | 42 | class multiplication(Scene): 43 | def construct(self): 44 | t = Text("3. อนุพันธ์ของผลคูณฟังก์ชัน", font="TH Sarabun New") 45 | t.scale(3) 46 | t.to_edge(UP) 47 | self.play(Write(t)) 48 | 49 | text = tex_mul() 50 | text.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 51 | 52 | self.play(Write(text[0:6])) 53 | self.wait(0.5) 54 | self.play(Write(text[6])) 55 | self.wait(0.5) 56 | self.play(Transform(text[2].copy(), text[7]), run_time = 1, path_arc=-np.pi) 57 | self.play(Transform(text[0].copy(), text[8]), run_time = 1) 58 | self.play(Transform(text[4].copy(), text[9]), run_time = 1, path_arc=-np.pi) 59 | self.play(Write(text[10])) 60 | self.play(Transform(text[4].copy(), text[11]), run_time = 1, path_arc=-np.pi) 61 | self.play(Transform(text[0].copy(), text[12]), run_time = 1) 62 | self.play(Transform(text[2].copy(), text[13]), run_time = 1, path_arc=-np.pi) 63 | self.wait() 64 | 65 | class division(Scene): 66 | def construct(self): 67 | t = Text("4. อนุพันธ์ของผลหารฟังก์ชัน", font="TH Sarabun New") 68 | t.scale(3) 69 | t.to_edge(UP) 70 | self.play(Write(t)) 71 | 72 | text = tex_div() 73 | text.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 74 | 75 | self.play(Write(text[0:6])) 76 | self.wait(0.5) 77 | self.play(Write(text[6])) 78 | self.wait(0.5) 79 | self.play(Transform(text[4].copy(), text[7]), run_time = 1, path_arc=np.pi) 80 | self.play(Transform(text[0].copy(), text[8]), run_time = 1) 81 | self.play(Transform(text[2].copy(), text[9]), run_time = 1, path_arc=-np.pi) 82 | self.play(Write(text[10])) 83 | self.play(Transform(text[2].copy(), text[11]), run_time = 1, path_arc=-np.pi) 84 | self.play(Transform(text[0].copy(), text[12]), run_time = 1) 85 | self.play(Transform(text[4].copy(), text[13]), run_time = 1, path_arc=np.pi) 86 | self.play(Write(text[14])) 87 | self.play(Transform(text[4].copy(), text[15]), run_time = 1, path_arc=np.pi) 88 | self.play(Write(text[16])) 89 | self.wait() 90 | 91 | class composite(Scene): 92 | def construct(self): 93 | t = Text("5. อนุพันธ์ของฟังก์ชันประกอบ (กฎลูกโซ่)", font="TH Sarabun New") 94 | t.scale(2) 95 | t.to_edge(UP) 96 | self.play(Write(t)) 97 | 98 | text = tex_comp() 99 | text.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 100 | h = text.get_height() 101 | 102 | self.play(Write(text[0:6])) 103 | self.wait(0.5) 104 | self.play(Write(text[6])) 105 | self.wait(0.5) 106 | self.play(ReplacementTransform(text[0].copy(), text[7]), run_time = 1) 107 | self.play(ReplacementTransform(text[4].copy(), text[8]), run_time = 1, path_arc=-np.pi) 108 | self.wait(0.5) 109 | self.play(ReplacementTransform(text[2].copy(), text[9]), ReplacementTransform(text[2].copy(), text[11]), run_time = 1, path_arc=-np.pi) 110 | self.wait(0.5) 111 | self.play(ReplacementTransform(text[4].copy(), text[10]), run_time = 1, path_arc=-np.pi) 112 | self.play(Write(text[12])) 113 | self.play(ReplacementTransform(text[0].copy(), text[13]), run_time = 1) 114 | self.play(ReplacementTransform(text[4].copy(), text[14]), run_time = 1, path_arc=-np.pi) 115 | self.wait() 116 | 117 | abb1 = TexMobject("\\frac{d}{dx} ( ", "f", "\\circ","g", ") = \\frac{d}{d", "g", "}", "f(", "g", ")", "\\cdot \\frac{d}{dx}", "g") 118 | abb1.set_height(h) 119 | 120 | for i in [1,7,9]: 121 | abb1[i].set_color(YELLOW) 122 | for i in [3,5,8,11]: 123 | abb1[i].set_color(BLUE) 124 | 125 | abb2 = TexMobject("(", "f", "\\circ", "g", ")' = ", "f'(", "g", ")", "\\cdot", "g'") 126 | abb2.set_height(h) 127 | 128 | for i in [1,5,7]: 129 | abb2[i].set_color(YELLOW) 130 | for i in [3,6,9]: 131 | abb2[i].set_color(BLUE) 132 | 133 | self.play(ReplacementTransform(text, abb1), run_time = 2) 134 | self.wait(2) 135 | self.play(Transform(abb1, abb2), run_time = 2) 136 | self.wait(2) 137 | 138 | class summary(Scene): 139 | def construct(self): 140 | t = Text("สรุปสมบัติทั้งหมดของอนุพันธ์", font="TH Sarabun New") 141 | t.scale(2) 142 | t.to_edge(UP) 143 | t.set_color(GREEN) 144 | self.play(Write(t)) 145 | 146 | t1 = tex_scalar_mul() 147 | t2 = tex_add() 148 | 149 | group1 = VGroup(t1, t2).arrange(DOWN) 150 | group1.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 151 | 152 | self.play(Write(t1)) 153 | self.play(Write(t2)) 154 | self.wait(3) 155 | self.play(FadeOut(group1)) 156 | t3 = tex_mul() 157 | t4 = tex_div() 158 | 159 | group2 = VGroup(t3, t4).arrange(DOWN) 160 | group2.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 161 | self.play(Write(t3)) 162 | self.play(Write(t4)) 163 | self.wait(3) 164 | self.play(FadeOut(group2)) 165 | 166 | t5 = tex_comp() 167 | t5.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 168 | self.play(Write(t5)) 169 | self.wait(3) 170 | self.play(FadeOut(t5)) 171 | 172 | group3 = VGroup(t1, t2, t3, t4, t5).arrange(DOWN) 173 | group3.to_edge(UP) 174 | group3.set_height(FRAME_HEIGHT - 2.5 * LARGE_BUFF) 175 | self.play(Write(group3)) 176 | self.wait(5) 177 | 178 | def tex_add(): 179 | text = TexMobject("\\frac{d}{dx}", "( ", "f", #2 180 | "+", "g", #4 181 | ")(x)","=", "\\frac{d}{dx}", "f(x)", #8 182 | "+", "\\frac{d}{dx}", "g(x)" #11 183 | ) 184 | text[2].set_color(YELLOW) 185 | text[8].set_color(YELLOW) 186 | text[4].set_color(BLUE) 187 | text[11].set_color(BLUE) 188 | return text 189 | 190 | def tex_scalar_mul(): 191 | text = TexMobject("\\frac{d}{dx}", "(", "c", #2 192 | "\\cdot", "f", #4 193 | ")(x)", "=", "c", #7 194 | "\\frac{d}{dx}", "f(x)") #9 195 | text[2].set_color(YELLOW) 196 | text[7].set_color(YELLOW) 197 | text[4].set_color(BLUE) 198 | text[9].set_color(BLUE) 199 | return text 200 | 201 | def tex_mul(): 202 | text = TexMobject("\\frac{d}{dx}", "(", "f", #2 203 | "\cdot", "g", #4 204 | ")(x)", "=", "f(x)", #7 205 | "\\frac{d}{dx}", "g(x)", #9 206 | "+", "g(x)", #11 207 | "\\frac{d}{dx}", "f(x)") #13 208 | text[2].set_color(YELLOW) 209 | text[7].set_color(YELLOW) 210 | text[13].set_color(YELLOW) 211 | text[4].set_color(BLUE) 212 | text[9].set_color(BLUE) 213 | text[11].set_color(BLUE) 214 | return text 215 | 216 | def tex_div(): 217 | text = TexMobject("\\frac{d}{dx}", "\\left({", "f", #2 218 | "\\over", "g", #4 219 | "}\\right)(x)", "=", "{g(x)", #7 220 | "\\frac{d}{dx}", "f(x)", #9 221 | "-", "f(x)", #11 222 | "\\frac{d}{dx}", "g(x)", #13 223 | "\\over", "g(x)", #15 224 | "^2}") 225 | text[2].set_color(YELLOW) 226 | text[9].set_color(YELLOW) 227 | text[11].set_color(YELLOW) 228 | text[4].set_color(BLUE) 229 | text[7].set_color(BLUE) 230 | text[13].set_color(BLUE) 231 | text[15].set_color(BLUE) 232 | return text 233 | 234 | def tex_comp(): 235 | text = TexMobject("\\frac{d}{dx}", "(", "f", #2 236 | "\\circ", "g", #4 237 | ")(x)", "=", "\\frac{d}{d", "g(x)}", #8 238 | "f(", #9 239 | "g(x)", #10 240 | ")", "\cdot", "\\frac{d}{dx}", "g(x)") #14 241 | text[2].set_color(YELLOW) 242 | text[9].set_color(YELLOW) 243 | text[11].set_color(YELLOW) 244 | text[4].set_color(BLUE) 245 | text[8].set_color(BLUE) 246 | text[10].set_color(BLUE) 247 | text[14].set_color(BLUE) 248 | return text 249 | -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/polynomial_division.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class poly_sum_ex1(Scene): 4 | def construct(self): 5 | title = Text("ผลบวกพหุนาม ตัวอย่างที่ 1", font="TH Sarabun New") 6 | title.scale(2).set_color(GREEN) 7 | title.to_edge(UP) 8 | self.add(title) 9 | 10 | # Scene 1: show equations 11 | text1 = Text("จงหาผลบวกของ", font="TH Sarabun New").scale(1.5) 12 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 13 | 14 | poly1 = TexMobject("2x^2","+","3x","-","4") 15 | poly2 = TexMobject("3x^2", "-","2x","+","1") 16 | 17 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 18 | group1.to_edge(UP).shift(DOWN) 19 | 20 | # scene 1: animate question 21 | self.play(Write(group1)) 22 | self.wait(0.5) 23 | self.play(Indicate(poly1)) 24 | self.play(Indicate(poly2)) 25 | 26 | # Scene 2: express the sum and recolor 27 | 28 | term1 = TexMobject("(","2x^2","+","3x","-","4",")","+","(", "3x^2", "-","2x","+","1",")") 29 | term2 = TexMobject("(","2x^2","+","3x","+","(-4)",")","+","(", "3x^2", "+","(-2)x","+","1",")") 30 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 31 | 32 | term1.to_edge(LEFT).shift(UP) 33 | term2.to_edge(LEFT).shift(UP) 34 | eq1 = TexMobject("(","2x^2","+","3x^2",")","+","(","3x","+","(-2)x",")","+","(","(-4)","+","1",")") 35 | eq2 = TexMobject("(","2","+","3",")","x^2","+","(","3","+","(-2)",")","x","+","(","(-4)","+","1",")") 36 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 37 | eq3 = TexMobject("5","x^2","+","1","x","+","(-3)") 38 | eq4 = TexMobject("5","x^2","+","x","-","3") 39 | 40 | eqsign1 = TexMobject("=").to_edge(LEFT) 41 | eqsign2 = TexMobject("=").to_edge(LEFT).shift(DOWN) 42 | eqsign3 = TexMobject("=").to_edge(LEFT).shift(2*DOWN) 43 | eqsign4 = TexMobject("=").to_edge(LEFT).shift(3*DOWN) 44 | 45 | eq1.next_to(eqsign1, RIGHT) 46 | eq2.next_to(eqsign2, RIGHT) 47 | eq3.next_to(eqsign3, RIGHT) 48 | eq4.next_to(eqsign4, RIGHT) 49 | 50 | framebox1 = SurroundingRectangle(term2[1], buff = .1) 51 | framebox2 = SurroundingRectangle(term2[3], buff = .1, color = BLUE) 52 | framebox3 = SurroundingRectangle(term2[5], buff = .1, color = RED) 53 | framebox4 = SurroundingRectangle(term2[9], buff = .1) 54 | framebox5 = SurroundingRectangle(term2[11], buff = .1, color = BLUE) 55 | framebox6 = SurroundingRectangle(term2[13], buff = .1, color = RED) 56 | 57 | ''' 58 | # scene 2: equation 1 59 | ''' 60 | self.play(Write(term1[0]), Write(term1[6])) 61 | self.play(ReplacementTransform(poly1.copy(), term1[1:6])) 62 | self.play(Write(term1[7])) 63 | self.play(Write(term1[8]), Write(term1[14])) 64 | self.play(ReplacementTransform(poly2.copy(), term1[9:14])) 65 | #self.wait(1) 66 | self.play(Indicate(term1[4:6])) 67 | #self.wait(1) 68 | self.play(Indicate(term1[10:12])) 69 | #self.wait(1) 70 | self.play(ReplacementTransform(term1, term2)) 71 | 72 | # 73 | # eq1: copy x^2 term 74 | # 75 | self.play(Write(eqsign1)) 76 | 77 | # emphasize x^2 78 | self.play(ShowCreationThenFadeOut(framebox1)) 79 | term2[1].set_color(YELLOW) 80 | self.play(ShowCreationThenFadeOut(framebox4)) 81 | term2[9].set_color(YELLOW) 82 | 83 | # write parentheses 84 | self.play(Write(eq1[0]), Write(eq1[4])) 85 | eq1[1].set_color(YELLOW) 86 | eq1[3].set_color(YELLOW) 87 | 88 | # move the terms 89 | self.play(ReplacementTransform(term2[1].copy(), eq1[1]), path_arc=-np.pi) 90 | self.play(Write(eq1[2])) 91 | self.play(ReplacementTransform(term2[9].copy(), eq1[3]), path_arc=-np.pi) 92 | #self.wait(0.5) 93 | 94 | # 95 | # eq1: copy x term 96 | # 97 | 98 | self.play(ShowCreationThenFadeOut(framebox2)) 99 | self.play(term2[3].set_color, BLUE, run_time=1) 100 | #self.wait(0.5) 101 | self.play(ShowCreationThenFadeOut(framebox5)) 102 | self.play(term2[11].set_color, BLUE, run_time=1) 103 | 104 | self.play(Write(eq1[5])) 105 | self.play(Write(eq1[6]), Write(eq1[10])) 106 | eq1[7].set_color(BLUE) 107 | eq1[9].set_color(BLUE) 108 | 109 | self.play(ReplacementTransform(term2[3].copy(), eq1[7]), path_arc=-np.pi) 110 | #self.wait(0.5) 111 | self.play(Write(eq1[8])) 112 | self.play(ReplacementTransform(term2[11].copy(), eq1[9]), path_arc=-np.pi) 113 | #self.wait(0.5) 114 | 115 | # 116 | # eq1: copy constant 117 | # 118 | self.play(ShowCreationThenFadeOut(framebox3)) 119 | self.play(term2[5].set_color, RED, run_time=1) 120 | #self.wait(0.5) 121 | self.play(ShowCreationThenFadeOut(framebox6)) 122 | self.play(term2[13].set_color, RED, run_time=1) 123 | 124 | self.play(Write(eq1[11])) 125 | self.play(Write(eq1[12]), Write(eq1[16])) 126 | eq1[13].set_color(RED) 127 | eq1[15].set_color(RED) 128 | 129 | self.play(ReplacementTransform(term2[5].copy(), eq1[13]), path_arc=-np.pi) 130 | #self.wait(0.5) 131 | self.play(Write(eq1[14])) 132 | self.play(ReplacementTransform(term2[13].copy(), eq1[15]), path_arc=-np.pi) 133 | #self.wait(0.5) 134 | 135 | ''' 136 | # scene 2: equation 2 137 | ''' 138 | self.play(Write(eqsign2)) 139 | self.play(ReplacementTransform(eq1[0:5].copy(), eq2[0:6])) 140 | #self.wait(0.5) 141 | self.play(Write(eq2[6])) 142 | self.play(ReplacementTransform(eq1[7:12].copy(), eq2[7:13])) 143 | #self.wait(0.5) 144 | self.play(Write(eq2[13])) 145 | self.play(ReplacementTransform(eq1[14:].copy(), eq2[14:])) 146 | #self.wait(0.5) 147 | ''' 148 | # scene 3: equation 3 149 | ''' 150 | self.play(Write(eqsign3)) 151 | self.play(ReplacementTransform(eq2[0:6].copy(), eq3[0:2])) 152 | #self.wait(0.5) 153 | self.play(Write(eq3[2])) 154 | self.play(ReplacementTransform(eq2[7:13].copy(), eq3[3:5])) 155 | #self.wait(0.5) 156 | self.play(Write(eq3[5])) 157 | self.play(ReplacementTransform(eq2[14:].copy(), eq3[6])) 158 | #self.wait(0.5) 159 | 160 | ''' 161 | # scene 4: equation 4 162 | ''' 163 | self.play(Write(eqsign4)) 164 | self.play(ReplacementTransform(eq3.copy(), eq4)) 165 | 166 | frameboxfinal = SurroundingRectangle(eq4, buff = .1) 167 | self.play(ShowCreation(frameboxfinal)) 168 | self.wait(1) 169 | 170 | class poly_sum_ex2(Scene): 171 | def construct(self): 172 | title = Text("ผลบวกพหุนาม ตัวอย่างที่ 1", font="TH Sarabun New") 173 | title.scale(2).set_color(GREEN) 174 | title.to_edge(UP) 175 | self.add(title) 176 | 177 | # Scene 1: show equations 178 | text1 = Text("จงหาผลบวกของ", font="TH Sarabun New").scale(1.5) 179 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 180 | 181 | poly1 = TexMobject("2x^2","+","3x","-","4") 182 | poly2 = TexMobject("3x^2", "-","2x","+","1") 183 | 184 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 185 | group1.to_edge(UP).shift(DOWN) 186 | 187 | # scene 1: animate question 188 | self.play(Write(group1)) 189 | self.wait(0.5) 190 | self.play(Indicate(poly1)) 191 | self.play(Indicate(poly2)) 192 | 193 | # Scene 2: express the sum and recolor 194 | 195 | term1 = TexMobject("(","2x^2","+","3x","-","4",")","+","(", "3x^2", "-","2x","+","1",")") 196 | term2 = TexMobject("(","2x^2","+","3x","+","(-4)",")","+","(", "3x^2", "+","(-2)x","+","1",")") 197 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 198 | 199 | term1.to_edge(LEFT).shift(UP) 200 | term2.to_edge(LEFT).shift(UP) 201 | eq1 = TexMobject("(","2x^2","+","3x^2",")","+","(","3x","+","(-2)x",")","+","(","(-4)","+","1",")") 202 | eq2 = TexMobject("(","2","+","3",")","x^2","+","(","3","+","(-2)",")","x","+","(","(-4)","+","1",")") 203 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 204 | eq3 = TexMobject("5","x^2","+","1","x","+","(-3)") 205 | eq4 = TexMobject("5","x^2","+","x","-","3") 206 | 207 | eqsign1 = TexMobject("=").to_edge(LEFT) 208 | eqsign2 = TexMobject("=").to_edge(LEFT).shift(DOWN) 209 | eqsign3 = TexMobject("=").to_edge(LEFT).shift(2*DOWN) 210 | eqsign4 = TexMobject("=").to_edge(LEFT).shift(3*DOWN) 211 | 212 | eq1.next_to(eqsign1, RIGHT) 213 | eq2.next_to(eqsign2, RIGHT) 214 | eq3.next_to(eqsign3, RIGHT) 215 | eq4.next_to(eqsign4, RIGHT) 216 | 217 | framebox1 = SurroundingRectangle(term2[1], buff = .1) 218 | framebox2 = SurroundingRectangle(term2[3], buff = .1, color = BLUE) 219 | framebox3 = SurroundingRectangle(term2[5], buff = .1, color = RED) 220 | framebox4 = SurroundingRectangle(term2[9], buff = .1) 221 | framebox5 = SurroundingRectangle(term2[11], buff = .1, color = BLUE) 222 | framebox6 = SurroundingRectangle(term2[13], buff = .1, color = RED) 223 | 224 | ''' 225 | # scene 2: equation 1 226 | ''' 227 | self.play(Write(term1[0]), Write(term1[6])) 228 | self.play(ReplacementTransform(poly1.copy(), term1[1:6])) 229 | self.play(Write(term1[7])) 230 | self.play(Write(term1[8]), Write(term1[14])) 231 | self.play(ReplacementTransform(poly2.copy(), term1[9:14])) 232 | #self.wait(1) 233 | self.play(Indicate(term1[4:6])) 234 | #self.wait(1) 235 | self.play(Indicate(term1[10:12])) 236 | #self.wait(1) 237 | self.play(ReplacementTransform(term1, term2)) 238 | 239 | # 240 | # eq1: copy x^2 term 241 | # 242 | self.play(Write(eqsign1)) 243 | 244 | # emphasize x^2 245 | self.play(ShowCreationThenFadeOut(framebox1)) 246 | term2[1].set_color(YELLOW) 247 | self.play(ShowCreationThenFadeOut(framebox4)) 248 | term2[9].set_color(YELLOW) 249 | 250 | # write parentheses 251 | self.play(Write(eq1[0]), Write(eq1[4])) 252 | eq1[1].set_color(YELLOW) 253 | eq1[3].set_color(YELLOW) 254 | 255 | # move the terms 256 | self.play(ReplacementTransform(term2[1].copy(), eq1[1]), path_arc=-np.pi) 257 | self.play(Write(eq1[2])) 258 | self.play(ReplacementTransform(term2[9].copy(), eq1[3]), path_arc=-np.pi) 259 | #self.wait(0.5) 260 | 261 | # 262 | # eq1: copy x term 263 | # 264 | 265 | self.play(ShowCreationThenFadeOut(framebox2)) 266 | self.play(term2[3].set_color, BLUE, run_time=1) 267 | #self.wait(0.5) 268 | self.play(ShowCreationThenFadeOut(framebox5)) 269 | self.play(term2[11].set_color, BLUE, run_time=1) 270 | 271 | self.play(Write(eq1[5])) 272 | self.play(Write(eq1[6]), Write(eq1[10])) 273 | eq1[7].set_color(BLUE) 274 | eq1[9].set_color(BLUE) 275 | 276 | self.play(ReplacementTransform(term2[3].copy(), eq1[7]), path_arc=-np.pi) 277 | #self.wait(0.5) 278 | self.play(Write(eq1[8])) 279 | self.play(ReplacementTransform(term2[11].copy(), eq1[9]), path_arc=-np.pi) 280 | #self.wait(0.5) 281 | 282 | # 283 | # eq1: copy constant 284 | # 285 | self.play(ShowCreationThenFadeOut(framebox3)) 286 | self.play(term2[5].set_color, RED, run_time=1) 287 | #self.wait(0.5) 288 | self.play(ShowCreationThenFadeOut(framebox6)) 289 | self.play(term2[13].set_color, RED, run_time=1) 290 | 291 | self.play(Write(eq1[11])) 292 | self.play(Write(eq1[12]), Write(eq1[16])) 293 | eq1[13].set_color(RED) 294 | eq1[15].set_color(RED) 295 | 296 | self.play(ReplacementTransform(term2[5].copy(), eq1[13]), path_arc=-np.pi) 297 | #self.wait(0.5) 298 | self.play(Write(eq1[14])) 299 | self.play(ReplacementTransform(term2[13].copy(), eq1[15]), path_arc=-np.pi) 300 | #self.wait(0.5) 301 | 302 | ''' 303 | # scene 2: equation 2 304 | ''' 305 | self.play(Write(eqsign2)) 306 | self.play(ReplacementTransform(eq1[0:5].copy(), eq2[0:6])) 307 | #self.wait(0.5) 308 | self.play(Write(eq2[6])) 309 | self.play(ReplacementTransform(eq1[7:12].copy(), eq2[7:13])) 310 | #self.wait(0.5) 311 | self.play(Write(eq2[13])) 312 | self.play(ReplacementTransform(eq1[14:].copy(), eq2[14:])) 313 | #self.wait(0.5) 314 | ''' 315 | # scene 3: equation 3 316 | ''' 317 | self.play(Write(eqsign3)) 318 | self.play(ReplacementTransform(eq2[0:6].copy(), eq3[0:2])) 319 | #self.wait(0.5) 320 | self.play(Write(eq3[2])) 321 | self.play(ReplacementTransform(eq2[7:13].copy(), eq3[3:5])) 322 | #self.wait(0.5) 323 | self.play(Write(eq3[5])) 324 | self.play(ReplacementTransform(eq2[14:].copy(), eq3[6])) 325 | #self.wait(0.5) 326 | 327 | ''' 328 | # scene 4: equation 4 329 | ''' 330 | self.play(Write(eqsign4)) 331 | self.play(ReplacementTransform(eq3.copy(), eq4)) 332 | 333 | frameboxfinal = SurroundingRectangle(eq4, buff = .1) 334 | self.play(ShowCreation(frameboxfinal)) 335 | self.wait(1) -------------------------------------------------------------------------------- /myprojects/polynomial_arithematics/polynomial_subtract.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class poly_sum_ex1(Scene): 4 | def construct(self): 5 | title = Text("ผลบวกพหุนาม ตัวอย่างที่ 1", font="TH Sarabun New") 6 | title.scale(2).set_color(GREEN) 7 | title.to_edge(UP) 8 | self.add(title) 9 | 10 | # Scene 1: show equations 11 | text1 = Text("จงหาผลบวกของ", font="TH Sarabun New").scale(1.5) 12 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 13 | 14 | poly1 = TexMobject("2x^2","+","3x","-","4") 15 | poly2 = TexMobject("3x^2", "-","2x","+","1") 16 | 17 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 18 | group1.to_edge(UP).shift(DOWN) 19 | 20 | # scene 1: animate question 21 | self.play(Write(group1)) 22 | self.wait(0.5) 23 | self.play(Indicate(poly1)) 24 | self.play(Indicate(poly2)) 25 | 26 | # Scene 2: express the sum and recolor 27 | 28 | term1 = TexMobject("(","2x^2","+","3x","-","4",")","+","(", "3x^2", "-","2x","+","1",")") 29 | term2 = TexMobject("(","2x^2","+","3x","+","(-4)",")","+","(", "3x^2", "+","(-2)x","+","1",")") 30 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 31 | 32 | term1.to_edge(LEFT).shift(UP) 33 | term2.to_edge(LEFT).shift(UP) 34 | eq1 = TexMobject("(","2x^2","+","3x^2",")","+","(","3x","+","(-2)x",")","+","(","(-4)","+","1",")") 35 | eq2 = TexMobject("(","2","+","3",")","x^2","+","(","3","+","(-2)",")","x","+","(","(-4)","+","1",")") 36 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 37 | eq3 = TexMobject("5","x^2","+","1","x","+","(-3)") 38 | eq4 = TexMobject("5","x^2","+","x","-","3") 39 | 40 | eqsign1 = TexMobject("=").to_edge(LEFT) 41 | eqsign2 = TexMobject("=").to_edge(LEFT).shift(DOWN) 42 | eqsign3 = TexMobject("=").to_edge(LEFT).shift(2*DOWN) 43 | eqsign4 = TexMobject("=").to_edge(LEFT).shift(3*DOWN) 44 | 45 | eq1.next_to(eqsign1, RIGHT) 46 | eq2.next_to(eqsign2, RIGHT) 47 | eq3.next_to(eqsign3, RIGHT) 48 | eq4.next_to(eqsign4, RIGHT) 49 | 50 | framebox1 = SurroundingRectangle(term2[1], buff = .1) 51 | framebox2 = SurroundingRectangle(term2[3], buff = .1, color = BLUE) 52 | framebox3 = SurroundingRectangle(term2[5], buff = .1, color = RED) 53 | framebox4 = SurroundingRectangle(term2[9], buff = .1) 54 | framebox5 = SurroundingRectangle(term2[11], buff = .1, color = BLUE) 55 | framebox6 = SurroundingRectangle(term2[13], buff = .1, color = RED) 56 | 57 | ''' 58 | # scene 2: equation 1 59 | ''' 60 | self.play(Write(term1[0]), Write(term1[6])) 61 | self.play(ReplacementTransform(poly1.copy(), term1[1:6])) 62 | self.play(Write(term1[7])) 63 | self.play(Write(term1[8]), Write(term1[14])) 64 | self.play(ReplacementTransform(poly2.copy(), term1[9:14])) 65 | #self.wait(1) 66 | self.play(Indicate(term1[4:6])) 67 | #self.wait(1) 68 | self.play(Indicate(term1[10:12])) 69 | #self.wait(1) 70 | self.play(ReplacementTransform(term1, term2)) 71 | 72 | # 73 | # eq1: copy x^2 term 74 | # 75 | self.play(Write(eqsign1)) 76 | 77 | # emphasize x^2 78 | self.play(ShowCreationThenFadeOut(framebox1)) 79 | term2[1].set_color(YELLOW) 80 | self.play(ShowCreationThenFadeOut(framebox4)) 81 | term2[9].set_color(YELLOW) 82 | 83 | # write parentheses 84 | self.play(Write(eq1[0]), Write(eq1[4])) 85 | eq1[1].set_color(YELLOW) 86 | eq1[3].set_color(YELLOW) 87 | 88 | # move the terms 89 | self.play(ReplacementTransform(term2[1].copy(), eq1[1]), path_arc=-np.pi) 90 | self.play(Write(eq1[2])) 91 | self.play(ReplacementTransform(term2[9].copy(), eq1[3]), path_arc=-np.pi) 92 | #self.wait(0.5) 93 | 94 | # 95 | # eq1: copy x term 96 | # 97 | 98 | self.play(ShowCreationThenFadeOut(framebox2)) 99 | self.play(term2[3].set_color, BLUE, run_time=1) 100 | #self.wait(0.5) 101 | self.play(ShowCreationThenFadeOut(framebox5)) 102 | self.play(term2[11].set_color, BLUE, run_time=1) 103 | 104 | self.play(Write(eq1[5])) 105 | self.play(Write(eq1[6]), Write(eq1[10])) 106 | eq1[7].set_color(BLUE) 107 | eq1[9].set_color(BLUE) 108 | 109 | self.play(ReplacementTransform(term2[3].copy(), eq1[7]), path_arc=-np.pi) 110 | #self.wait(0.5) 111 | self.play(Write(eq1[8])) 112 | self.play(ReplacementTransform(term2[11].copy(), eq1[9]), path_arc=-np.pi) 113 | #self.wait(0.5) 114 | 115 | # 116 | # eq1: copy constant 117 | # 118 | self.play(ShowCreationThenFadeOut(framebox3)) 119 | self.play(term2[5].set_color, RED, run_time=1) 120 | #self.wait(0.5) 121 | self.play(ShowCreationThenFadeOut(framebox6)) 122 | self.play(term2[13].set_color, RED, run_time=1) 123 | 124 | self.play(Write(eq1[11])) 125 | self.play(Write(eq1[12]), Write(eq1[16])) 126 | eq1[13].set_color(RED) 127 | eq1[15].set_color(RED) 128 | 129 | self.play(ReplacementTransform(term2[5].copy(), eq1[13]), path_arc=-np.pi) 130 | #self.wait(0.5) 131 | self.play(Write(eq1[14])) 132 | self.play(ReplacementTransform(term2[13].copy(), eq1[15]), path_arc=-np.pi) 133 | #self.wait(0.5) 134 | 135 | ''' 136 | # scene 2: equation 2 137 | ''' 138 | self.play(Write(eqsign2)) 139 | self.play(ReplacementTransform(eq1[0:5].copy(), eq2[0:6])) 140 | #self.wait(0.5) 141 | self.play(Write(eq2[6])) 142 | self.play(ReplacementTransform(eq1[7:12].copy(), eq2[7:13])) 143 | #self.wait(0.5) 144 | self.play(Write(eq2[13])) 145 | self.play(ReplacementTransform(eq1[14:].copy(), eq2[14:])) 146 | #self.wait(0.5) 147 | ''' 148 | # scene 3: equation 3 149 | ''' 150 | self.play(Write(eqsign3)) 151 | self.play(ReplacementTransform(eq2[0:6].copy(), eq3[0:2])) 152 | #self.wait(0.5) 153 | self.play(Write(eq3[2])) 154 | self.play(ReplacementTransform(eq2[7:13].copy(), eq3[3:5])) 155 | #self.wait(0.5) 156 | self.play(Write(eq3[5])) 157 | self.play(ReplacementTransform(eq2[14:].copy(), eq3[6])) 158 | #self.wait(0.5) 159 | 160 | ''' 161 | # scene 4: equation 4 162 | ''' 163 | self.play(Write(eqsign4)) 164 | self.play(ReplacementTransform(eq3.copy(), eq4)) 165 | 166 | frameboxfinal = SurroundingRectangle(eq4, buff = .1) 167 | self.play(ShowCreation(frameboxfinal)) 168 | self.wait(1) 169 | 170 | class poly_sum_ex2(Scene): 171 | def construct(self): 172 | title = Text("ผลบวกพหุนาม ตัวอย่างที่ 1", font="TH Sarabun New") 173 | title.scale(2).set_color(GREEN) 174 | title.to_edge(UP) 175 | self.add(title) 176 | 177 | # Scene 1: show equations 178 | text1 = Text("จงหาผลบวกของ", font="TH Sarabun New").scale(1.5) 179 | text2 = Text("และ", font="TH Sarabun New").scale(1.5) 180 | 181 | poly1 = TexMobject("2x^2","+","3x","-","4") 182 | poly2 = TexMobject("3x^2", "-","2x","+","1") 183 | 184 | group1 = VGroup(text1, poly1, text2, poly2).arrange(RIGHT) 185 | group1.to_edge(UP).shift(DOWN) 186 | 187 | # scene 1: animate question 188 | self.play(Write(group1)) 189 | self.wait(0.5) 190 | self.play(Indicate(poly1)) 191 | self.play(Indicate(poly2)) 192 | 193 | # Scene 2: express the sum and recolor 194 | 195 | term1 = TexMobject("(","2x^2","+","3x","-","4",")","+","(", "3x^2", "-","2x","+","1",")") 196 | term2 = TexMobject("(","2x^2","+","3x","+","(-4)",")","+","(", "3x^2", "+","(-2)x","+","1",")") 197 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 198 | 199 | term1.to_edge(LEFT).shift(UP) 200 | term2.to_edge(LEFT).shift(UP) 201 | eq1 = TexMobject("(","2x^2","+","3x^2",")","+","(","3x","+","(-2)x",")","+","(","(-4)","+","1",")") 202 | eq2 = TexMobject("(","2","+","3",")","x^2","+","(","3","+","(-2)",")","x","+","(","(-4)","+","1",")") 203 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 204 | eq3 = TexMobject("5","x^2","+","1","x","+","(-3)") 205 | eq4 = TexMobject("5","x^2","+","x","-","3") 206 | 207 | eqsign1 = TexMobject("=").to_edge(LEFT) 208 | eqsign2 = TexMobject("=").to_edge(LEFT).shift(DOWN) 209 | eqsign3 = TexMobject("=").to_edge(LEFT).shift(2*DOWN) 210 | eqsign4 = TexMobject("=").to_edge(LEFT).shift(3*DOWN) 211 | 212 | eq1.next_to(eqsign1, RIGHT) 213 | eq2.next_to(eqsign2, RIGHT) 214 | eq3.next_to(eqsign3, RIGHT) 215 | eq4.next_to(eqsign4, RIGHT) 216 | 217 | framebox1 = SurroundingRectangle(term2[1], buff = .1) 218 | framebox2 = SurroundingRectangle(term2[3], buff = .1, color = BLUE) 219 | framebox3 = SurroundingRectangle(term2[5], buff = .1, color = RED) 220 | framebox4 = SurroundingRectangle(term2[9], buff = .1) 221 | framebox5 = SurroundingRectangle(term2[11], buff = .1, color = BLUE) 222 | framebox6 = SurroundingRectangle(term2[13], buff = .1, color = RED) 223 | 224 | ''' 225 | # scene 2: equation 1 226 | ''' 227 | self.play(Write(term1[0]), Write(term1[6])) 228 | self.play(ReplacementTransform(poly1.copy(), term1[1:6])) 229 | self.play(Write(term1[7])) 230 | self.play(Write(term1[8]), Write(term1[14])) 231 | self.play(ReplacementTransform(poly2.copy(), term1[9:14])) 232 | #self.wait(1) 233 | self.play(Indicate(term1[4:6])) 234 | #self.wait(1) 235 | self.play(Indicate(term1[10:12])) 236 | #self.wait(1) 237 | self.play(ReplacementTransform(term1, term2)) 238 | 239 | # 240 | # eq1: copy x^2 term 241 | # 242 | self.play(Write(eqsign1)) 243 | 244 | # emphasize x^2 245 | self.play(ShowCreationThenFadeOut(framebox1)) 246 | term2[1].set_color(YELLOW) 247 | self.play(ShowCreationThenFadeOut(framebox4)) 248 | term2[9].set_color(YELLOW) 249 | 250 | # write parentheses 251 | self.play(Write(eq1[0]), Write(eq1[4])) 252 | eq1[1].set_color(YELLOW) 253 | eq1[3].set_color(YELLOW) 254 | 255 | # move the terms 256 | self.play(ReplacementTransform(term2[1].copy(), eq1[1]), path_arc=-np.pi) 257 | self.play(Write(eq1[2])) 258 | self.play(ReplacementTransform(term2[9].copy(), eq1[3]), path_arc=-np.pi) 259 | #self.wait(0.5) 260 | 261 | # 262 | # eq1: copy x term 263 | # 264 | 265 | self.play(ShowCreationThenFadeOut(framebox2)) 266 | self.play(term2[3].set_color, BLUE, run_time=1) 267 | #self.wait(0.5) 268 | self.play(ShowCreationThenFadeOut(framebox5)) 269 | self.play(term2[11].set_color, BLUE, run_time=1) 270 | 271 | self.play(Write(eq1[5])) 272 | self.play(Write(eq1[6]), Write(eq1[10])) 273 | eq1[7].set_color(BLUE) 274 | eq1[9].set_color(BLUE) 275 | 276 | self.play(ReplacementTransform(term2[3].copy(), eq1[7]), path_arc=-np.pi) 277 | #self.wait(0.5) 278 | self.play(Write(eq1[8])) 279 | self.play(ReplacementTransform(term2[11].copy(), eq1[9]), path_arc=-np.pi) 280 | #self.wait(0.5) 281 | 282 | # 283 | # eq1: copy constant 284 | # 285 | self.play(ShowCreationThenFadeOut(framebox3)) 286 | self.play(term2[5].set_color, RED, run_time=1) 287 | #self.wait(0.5) 288 | self.play(ShowCreationThenFadeOut(framebox6)) 289 | self.play(term2[13].set_color, RED, run_time=1) 290 | 291 | self.play(Write(eq1[11])) 292 | self.play(Write(eq1[12]), Write(eq1[16])) 293 | eq1[13].set_color(RED) 294 | eq1[15].set_color(RED) 295 | 296 | self.play(ReplacementTransform(term2[5].copy(), eq1[13]), path_arc=-np.pi) 297 | #self.wait(0.5) 298 | self.play(Write(eq1[14])) 299 | self.play(ReplacementTransform(term2[13].copy(), eq1[15]), path_arc=-np.pi) 300 | #self.wait(0.5) 301 | 302 | ''' 303 | # scene 2: equation 2 304 | ''' 305 | self.play(Write(eqsign2)) 306 | self.play(ReplacementTransform(eq1[0:5].copy(), eq2[0:6])) 307 | #self.wait(0.5) 308 | self.play(Write(eq2[6])) 309 | self.play(ReplacementTransform(eq1[7:12].copy(), eq2[7:13])) 310 | #self.wait(0.5) 311 | self.play(Write(eq2[13])) 312 | self.play(ReplacementTransform(eq1[14:].copy(), eq2[14:])) 313 | #self.wait(0.5) 314 | ''' 315 | # scene 3: equation 3 316 | ''' 317 | self.play(Write(eqsign3)) 318 | self.play(ReplacementTransform(eq2[0:6].copy(), eq3[0:2])) 319 | #self.wait(0.5) 320 | self.play(Write(eq3[2])) 321 | self.play(ReplacementTransform(eq2[7:13].copy(), eq3[3:5])) 322 | #self.wait(0.5) 323 | self.play(Write(eq3[5])) 324 | self.play(ReplacementTransform(eq2[14:].copy(), eq3[6])) 325 | #self.wait(0.5) 326 | 327 | ''' 328 | # scene 4: equation 4 329 | ''' 330 | self.play(Write(eqsign4)) 331 | self.play(ReplacementTransform(eq3.copy(), eq4)) 332 | 333 | frameboxfinal = SurroundingRectangle(eq4, buff = .1) 334 | self.play(ShowCreation(frameboxfinal)) 335 | self.wait(1) -------------------------------------------------------------------------------- /myprojects/tabletop_encyclopedia/overall.py: -------------------------------------------------------------------------------- 1 | from sys import builtin_module_names 2 | from manim import * 3 | from MeepleCreature.MeepleCreature import * 4 | 5 | NUM_PLAYERS = 4 6 | 7 | class Movie(Scene): 8 | def construct(self): 9 | self.MC = MeepleCreature() 10 | self.add(self.MC) 11 | self.intro() 12 | #self.toc() 13 | #self.tictactoe() 14 | #self.game_structure() 15 | #self.turn_order() 16 | 17 | def intro(self): 18 | self.MC.to_edge(DOWN) 19 | text1 = Text("สวัสดีครับ\nผมชื่อกลครับ", font = "Anakotmai Light", line_spacing= 4) 20 | text1.set_color(random_bright_color()).scale(1.5) 21 | text2 = Text("วันนี้เรามาศึกษา\nกลไกในบอร์ดเกมกัน", font = "Anakotmai Light", line_spacing = 3) 22 | text2.set_color(random_bright_color()).scale(1.5) 23 | self.play(Create(self.MC)) 24 | self.play(Blink(self.MC)) 25 | 26 | self.play(MeepleCreatureSays( 27 | self.MC, text1, 28 | bubble_kwargs = {"height" : 4, "width" : 6}, 29 | target_mode="speaking", 30 | is_looking_direction_purposeful = False, 31 | )) 32 | 33 | self.wait() 34 | self.play(Blink(self.MC)) 35 | self.play(RemoveMeepleCreatureBubble(self.MC)) 36 | self.play(MeepleCreatureSays( 37 | self.MC, text2, 38 | bubble_kwargs = {"height" : 4, "width" : 6}, 39 | target_mode="speaking", 40 | is_looking_direction_purposeful = False, 41 | )) 42 | self.play(Blink(self.MC)) 43 | 44 | book = ImageMobject("book_cover") 45 | book.shift(UP + 4*RIGHT).scale(2.5) 46 | self.play(FadeIn(book, shift = DOWN)) 47 | self.MC.look_at(book) 48 | self.wait(1) 49 | 50 | self.play(RemoveMeepleCreatureBubble(self.MC)) 51 | self.play(FadeOut(self.MC, shift = DOWN)) 52 | 53 | author_image = ImageMobject("geoff").scale(2) 54 | author_title = Text(f'Geoffrey Engelstein', font = "Prompt") 55 | author = Group(author_image, author_title).arrange(DOWN) 56 | 57 | author.shift(UP + 3*LEFT) 58 | self.play(FadeIn(author_image, shift = DOWN)) 59 | self.play(Write(author_title)) 60 | 61 | quote = Paragraph(f'Building Blocks of Tabletop Game Design: An Encyclopedia of Mechanisms\ncompiles hundreds of different mechanisms, organized by category.\nEach has a description of how it works, discussion of its pros and cons,\nhow it can be implemented, and examples of specific games that use it.', font = "Prompt").scale(0.6).set_color(GOLD_A) 62 | quote.to_edge(LEFT, buff = 1).shift(2.5*DOWN) 63 | self.play(ShowCreation(quote), run_time = 15) #13 seconds to read 64 | 65 | self.play(AnimationGroup( 66 | FadeOut(quote, shift = DOWN), 67 | FadeOut(author, shift = DOWN), 68 | FadeOut(book, shift = DOWN) 69 | )) 70 | self.play(FadeIn(self.MC, shift = DOWN)) 71 | 72 | def toc(self): 73 | 74 | topics = [ 75 | "Game Structure", 76 | "Turn Order and Structure", 77 | "Actions", 78 | "Resolution", 79 | "Game End and Victory", 80 | "Uncertainty", 81 | "Economics", 82 | "Auctions", 83 | "Worker Placement", 84 | "Movement", 85 | "Area Control", 86 | "Set Collection", 87 | "Card Mechanism" 88 | ] 89 | 90 | topics = ["Game Structure"] # overwrite for shorter animation 91 | 92 | self.play( 93 | MoveAlongPath(self.MC, Line(self.MC.get_center(), 5*RIGHT + 2*DOWN), rate_func = smooth) 94 | ) 95 | 96 | text = [] 97 | for i in range(0,len(topics)): 98 | newtitle = Text(str(i+1) + ") " + topics[i], font = "Prompt").set_color(random_bright_color()) 99 | text.append(newtitle) 100 | 101 | t = VGroup(*text).arrange(DOWN, center = False, aligned_edge = LEFT, buff = 0.1) 102 | t.to_corner(UL) 103 | 104 | for i in t: 105 | self.MC.look_at(i) 106 | self.play(Write(i)) 107 | self.play(Blink(self.MC)) 108 | 109 | text = Text("ทำไมเยอะจัง?", font = "Anakotmai Light", line_spacing = 3) 110 | text.set_color(random_bright_color()).scale(1.5) 111 | 112 | self.play(Blink(self.MC)) 113 | self.play(MeepleCreatureSays( 114 | self.MC, text, 115 | bubble_class = ThoughtBubble, 116 | bubble_kwargs = {"height" : 4, "width" : 6}, 117 | target_mode="speaking", 118 | is_looking_direction_purposeful = True, 119 | )) 120 | self.play(Blink(self.MC)) 121 | self.play(RemoveMeepleCreatureBubble(self.MC)) 122 | 123 | def tictactoe(self): 124 | self.add_sound("narrate") 125 | self.add_sound("windrider_edited") 126 | self.MC2 = Meeple(color = RED, start_corner = DL) 127 | self.MC.to_corner(DR).look_at(ORIGIN) 128 | self.MC2.to_corner(DL).look_at(ORIGIN) 129 | 130 | line_endpoints = [ 131 | [3*UP + LEFT, 3*DOWN + LEFT], 132 | [3*UP + RIGHT, 3*DOWN + RIGHT], 133 | [3*LEFT + UP, 3*RIGHT + UP], 134 | [3*LEFT + DOWN, 3*RIGHT + DOWN] 135 | ] 136 | 137 | self.play(FadeInFromDown(self.MC2)) 138 | self.play(FadeInFromDown(self.MC)) 139 | 140 | #create tictactoe grid 141 | lines = [Line(start = line_endpoints[i][0], end = line_endpoints[i][1]) for i in range(len(line_endpoints))] 142 | self.play(AnimationGroup( 143 | *[ShowCreation(l, run_time = 1) for l in lines], 144 | lag_ratio = 0.2 145 | )) 146 | 147 | title = Text("Tic Tac Toe", color = GREEN_A).scale(1.2) 148 | title.to_edge(DOWN) 149 | self.play(FadeInFromDown(title)) 150 | 151 | self.wait(7-self.time) 152 | text = Text("เกมนี้ประกอบด้วย\nกลไกอะไรบ้าง?", line_spacing = 3) 153 | self.play(MeepleCreatureSays( 154 | self.MC, text, 155 | bubble_kwargs = {"height" : 4, "width" : 8}, 156 | target_mode="speaking", 157 | is_looking_direction_purposeful = True, 158 | )) 159 | self.play(Blink(self.MC)) 160 | self.play(RemoveMeepleCreatureBubble(self.MC)) 161 | 162 | #add sequence of play 163 | tictactoe_plays = [(1,1), (1,0), (0,0), (2,2), (0,1), (0,2), (2,1)] 164 | corner = 2*UP + 2*LEFT 165 | marks = [] 166 | for i in range(len(tictactoe_plays)): 167 | x, y = tictactoe_plays[i] 168 | p1 = Circle(color = BLUE).scale(0.5) 169 | if i % 2 == 1: 170 | p1 = Cross(p1, color = RED).scale(0.8) 171 | p1.move_to(corner + 2*x*RIGHT + 2*y*DOWN) 172 | self.play(ShowCreation(p1), run_time = 0.5) 173 | marks.append(p1) 174 | 175 | winning = Line(3*LEFT, 3*RIGHT, color = BLUE, stroke_width = 10) 176 | self.play(ShowCreation(winning)) 177 | trophy = ImageMobject("Trophy").next_to(self.MC, UP).set_color(GOLD) 178 | self.play(FadeInFromLarge(trophy)) 179 | self.wait(1) 180 | self.remove(winning, trophy) 181 | 182 | # clear the board and start discussion 183 | board = VGroup(*marks, *lines, title) 184 | new_board = board.copy().scale(0.5).next_to(self.MC, UP, buff = MED_LARGE_BUFF) 185 | self.play(FadeOutAndShiftDown(self.MC2)) 186 | self.play(ReplacementTransform(board, new_board)) 187 | 188 | self.wait(20-self.time) 189 | 190 | types = [ 191 | "2-player game", 192 | "turn by turn", 193 | "square grid", 194 | "single action", 195 | "pattern matching", 196 | "single winner" 197 | ] 198 | 199 | type_text = VGroup(*[Text(t) for t in types]).arrange(DOWN, aligned_edge=LEFT) 200 | type_text.scale(1.5).to_corner(UL) 201 | for t in type_text: 202 | self.play(Write(t)) 203 | self.wait(2) 204 | 205 | self.wait(35-self.time) 206 | text = Text("ถ้าเปลี่ยนบางส่วน\nแล้วจะเป็นอย่างไร?", font = "Anakotmai Light", line_spacing = 3) 207 | text.set_color(random_bright_color()).scale(1.5) 208 | 209 | self.play(Blink(self.MC)) 210 | self.play(MeepleCreatureSays( 211 | self.MC, text, 212 | bubble_class = ThoughtBubble, 213 | bubble_kwargs = {"height" : 4, "width" : 6}, 214 | target_mode="speaking", 215 | is_looking_direction_purposeful = True, 216 | )) 217 | self.play(Blink(self.MC)) 218 | self.wait(42-self.time) 219 | self.play(RemoveMeepleCreatureBubble(self.MC)) 220 | 221 | # changing first part 222 | text = Text("3-player game?", fill_color = GREEN) 223 | text.next_to(type_text[0], RIGHT) 224 | cross = Line(type_text[0].get_left(), type_text[0].get_right(), color = RED, stroke_width = 10) 225 | self.play(Indicate(type_text[0])) 226 | self.wait(1) 227 | self.play(ShowCreation(cross)) 228 | self.play(FadeInFrom(text, LEFT)) 229 | self.wait(47-self.time) 230 | self.play(Indicate(type_text[4])) 231 | self.play(ApplyMethod(type_text[4].set_opacity, 0.3)) 232 | self.wait(54-self.time) 233 | self.remove(cross, text) 234 | type_text[4].set_opacity(1) 235 | self.wait(1) 236 | 237 | # changing second part 238 | text = Text("real time?", fill_color = GREEN) 239 | text.next_to(type_text[1], RIGHT) 240 | cross = Line(type_text[1].get_left(), type_text[1].get_right(), color = RED, stroke_width = 10) 241 | self.wait(55-self.time) 242 | self.play(Indicate(type_text[1])) 243 | self.wait(1) 244 | self.play(ShowCreation(cross)) 245 | self.play(FadeInFrom(text, LEFT)) 246 | self.wait(62-self.time) 247 | self.play(Indicate(type_text[5])) 248 | self.play(ApplyMethod(type_text[5].set_opacity, 0.3)) 249 | self.wait(69-self.time) 250 | self.remove(cross, text) 251 | type_text[5].set_opacity(1) 252 | 253 | text = Text("เปลี่ยนอย่างไร\nได้บ้าง?", font = "Anakotmai Light", line_spacing = 3) 254 | self.play(Blink(self.MC)) 255 | self.play(MeepleCreatureThinks( 256 | self.MC, text, 257 | bubble_kwargs = {"height" : 4, "width" : 6}, 258 | target_mode="speaking", 259 | is_looking_direction_purposeful = True, 260 | )) 261 | self.play(Blink(self.MC)) 262 | self.wait(85-self.time) 263 | self.play(RemoveMeepleCreatureBubble(self.MC)) 264 | 265 | self.play(AnimationGroup( 266 | *[FadeOutAndShiftDown(t) for t in type_text], 267 | lag_ratio = 0.1 268 | )) 269 | 270 | # new types 271 | types = [ 272 | "STR-01 Competitive Games", 273 | "TRN-01 Fixed-Turn Order", 274 | "ACT-01 Action Points", 275 | "VIC-01 Victory Points from Game State" 276 | ] 277 | 278 | type_text = VGroup(*[Text(t) for t in types]).arrange(DOWN, aligned_edge=LEFT, buff = 0.8) 279 | type_text.scale(1).to_corner(UL) 280 | self.play(AnimationGroup( 281 | *[FadeInFromDown(t) for t in type_text], 282 | lag_ratio = 0.1 283 | )) 284 | 285 | self.wait(88-self.time) 286 | self.play(AnimationGroup( 287 | *[Indicate(t[4:6]) for t in type_text], 288 | lag_ratio = 0.2 289 | )) 290 | 291 | self.wait(99-self.time) 292 | text = Text("Worker Placement?\nArea Control?", line_spacing = 3) 293 | text.set_color(random_bright_color()).scale(1.5) 294 | 295 | self.play(FadeInFromDown(self.MC2)) 296 | self.MC.make_eye_contact(self.MC2) 297 | self.play(Blink(self.MC)) 298 | self.play(MeepleCreatureSays( 299 | self.MC2, text, 300 | bubble_kwargs = {"height" : 4, "width" : 6}, 301 | target_mode="speaking", 302 | is_looking_direction_purposeful = True, 303 | )) 304 | self.play(Blink(self.MC2)) 305 | 306 | self.wait(108-self.time) 307 | self.play(RemoveMeepleCreatureBubble(self.MC2)) 308 | text = Text("อ่านคำจำกัดความ\nในหนังสือดูสิ", line_spacing = 3) 309 | self.play(MeepleCreatureSays( 310 | self.MC, text, 311 | bubble_kwargs = {"height" : 4, "width" : 6}, 312 | target_mode="speaking", 313 | is_looking_direction_purposeful = True, 314 | )) 315 | self.play(Blink(self.MC)) 316 | 317 | book = ImageMobject("book_cover") 318 | book.scale(1.5).to_edge(DOWN) 319 | self.play(FadeInFromDown(book)) 320 | self.MC.look_at(book) 321 | self.wait(114-self.time) 322 | #self.remove(book) 323 | #self.play(RemoveMeepleCreatureBubble(self.MC)) 324 | #self.wait() 325 | 326 | def game_structure(self): 327 | subtypes = [ 328 | "STR-01 Competitive Games", 329 | "STR-02 Cooperative Games", 330 | "STR-03 Team-Based Games", 331 | "STR-04 Solo Games", 332 | "STR-05 Semi-Cooperative Games", 333 | "STR-06 Single Loser Games", 334 | "STR-07 Traitor Games", 335 | "STR-08 Scenario/Mission/Campaign Games", 336 | "STR-09 Score-and-Reset Games", 337 | "STR-10 Legacy Games" 338 | ] 339 | 340 | creature = Meeple() 341 | bot = SVGMobject("Robot") 342 | creature.scale(0.7) 343 | bot.scale(1.2).set_color(WHITE) 344 | 345 | creatures = [] 346 | creature_positions = [] 347 | for i in range (0,4): 348 | newcreature = creature.copy() 349 | newcreature.set_color(random_bright_color()) 350 | creatures.append(newcreature) 351 | 352 | 353 | # subtype 1 354 | title = Text(subtypes[0], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 355 | 356 | creature_positions = [UL*2, UR*2, DR*2, DL*2] 357 | for c,p in zip(creatures, creature_positions): 358 | c.move_to(p) 359 | c.look_at(ORIGIN) 360 | 361 | self.play(AnimationGroup( 362 | Write(title), 363 | *[FadeInFromDown(c) for c in creatures], 364 | lag_ratio = 0.2 365 | )) 366 | self.wait(0.5) 367 | self.remove(title) 368 | #''' 369 | # STR-02 Cooperative Games 370 | title = Text(subtypes[1], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 371 | self.wait(1) 372 | 373 | creature_positions = [UP + 4*LEFT, UP + 2*LEFT, DOWN + 2*LEFT, DOWN + 4*LEFT] 374 | bot.move_to(3*RIGHT) 375 | for c in creatures: 376 | c.look_at(bot) 377 | 378 | self.play(AnimationGroup( 379 | Write(title), 380 | FadeInFromDown(bot), 381 | *[MoveAlongPath(c, Line(c.get_center(), p), rate_func = smooth) for c,p in zip(creatures, creature_positions)], 382 | lag_ratio = 0 383 | )) 384 | self.wait(0.5) 385 | self.remove(title) 386 | 387 | # STR-03 Team-Based Games 388 | title = Text(subtypes[2], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 389 | self.wait(1) 390 | 391 | creature_positions = [UP + 3*LEFT, UP + 3*RIGHT, DOWN + 3*RIGHT, DOWN + 3*LEFT] 392 | creatures[0].look_at(creatures[1]) 393 | creatures[1].look_at(creatures[0]) 394 | creatures[2].look_at(creatures[3]) 395 | creatures[3].look_at(creatures[2]) 396 | self.play(AnimationGroup( 397 | Write(title), 398 | FadeOutAndShiftDown(bot), 399 | *[MoveAlongPath(c, Line(c.get_center(), p), rate_func = smooth) for c,p in zip(creatures, creature_positions)], 400 | lag_ratio = 0 401 | )) 402 | self.wait(0.5) 403 | self.remove(title) 404 | 405 | # STR-04 Solo Games 406 | title = Text(subtypes[3], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 407 | self.wait(1) 408 | creatures[0].look_at(bot) 409 | 410 | self.play(AnimationGroup( 411 | Write(title), 412 | FadeOut(creatures[1]), 413 | FadeOut(creatures[2]), 414 | FadeOut(creatures[3]), 415 | FadeInFromDown(bot), 416 | MoveAlongPath(creatures[0], Line(creatures[0].get_center(), 3*LEFT), rate_func = smooth), 417 | lag_ratio = 0 418 | )) 419 | self.wait(0.5) 420 | self.remove(title) 421 | 422 | # subtype 5 423 | title = Text(subtypes[4], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 424 | self.wait(1) 425 | 426 | creature_positions = [2*UP + 5*LEFT, 2*UP + LEFT, 2*DOWN + LEFT, 2*DOWN + 5*LEFT] 427 | bot.move_to(3*RIGHT) 428 | for c in creatures: 429 | self.add(c) 430 | c.move_to(creatures[0].get_center()) 431 | c.look_at(bot) 432 | 433 | self.play(AnimationGroup( 434 | Write(title), 435 | FadeInFromDown(bot), 436 | *[MoveAlongPath(c, Line(c.get_center(), p), rate_func = smooth) for c,p in zip(creatures, creature_positions)], 437 | lag_ratio = 0 438 | )) 439 | 440 | self.wait(0.5) 441 | self.remove(title) 442 | 443 | # STR-06 Single Loser Games 444 | title = Text(subtypes[5], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 445 | self.wait(1) 446 | 447 | creature_positions = [UL*2, UR*2, DR*2, DL*2] 448 | for c in creatures: 449 | c.look_at(ORIGIN) 450 | 451 | self.play(AnimationGroup( 452 | Write(title), 453 | FadeOutAndShiftDown(bot), 454 | *[MoveAlongPath(c, Line(c.get_center(), p), rate_func = smooth) for c,p in zip(creatures, creature_positions)], 455 | lag_ratio = 0 456 | )) 457 | 458 | for c in creatures: 459 | c.look_at(creatures[1]) 460 | cross = Cross(creatures[1]) 461 | self.play(ShowCreation(cross)) 462 | #self.play(ApplyMethod(creatures[1].set_fill, creatures[1].get_color(), 0.2)) 463 | self.remove(title, cross) 464 | #''' 465 | 466 | # "STR-07 Traitor Games" 467 | title = Text(subtypes[6], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 468 | role_unknown = [Text("?", color = WHITE).next_to(c, DOWN) for c in creatures] 469 | roles = ["Good", "Good", "Traitor", "Good"] # to be replaced by image ? 470 | role_text = [Text(r, color = GREEN).next_to(c, DOWN) for r,c in zip(roles, creatures)] 471 | role_text[2].set_color(RED) 472 | 473 | for c in creatures: 474 | c.look_at(ORIGIN) 475 | 476 | self.play(AnimationGroup( 477 | Write(title), 478 | *[FadeInFromDown(unknown) for unknown in role_unknown] 479 | )) 480 | self.wait(0.5) 481 | self.play(AnimationGroup( 482 | *[ReplacementTransform(unknown, rt) for unknown, rt in zip(role_unknown, role_text)] 483 | )) 484 | 485 | self.wait(0.5) 486 | self.remove(title, *[rt for rt in role_text]) 487 | 488 | # STR-08 Scenario/Mission/Campaign Games 489 | # ???? 490 | 491 | # STR-09 Score-and-Reset Games 492 | title = Text(subtypes[8], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 493 | self.wait(1) 494 | 495 | creature_positions = [2*UP + 4.5*LEFT, 2*UP + 1.5*LEFT, 2*UP + 1.5*RIGHT, 2*UP + 4.5*RIGHT] 496 | self.play(AnimationGroup( 497 | Write(title), 498 | *[MoveAlongPath(c, Line(c.get_center(), p), rate_func = smooth) for c,p in zip(creatures, creature_positions)], 499 | lag_ratio = 0 500 | )) 501 | for c in creatures: 502 | c.look_at(ORIGIN) 503 | 504 | scores = [[3,4,2,5], [2,3,4,1], [3,4,5,6], [8, 11, 11, 12]] 505 | score_text = [] 506 | for i in range(0, 4): 507 | st = [Text(str(s)).move_to(p + (i+2)*DOWN) for s,p in zip(scores[i], creature_positions)] 508 | if i == 3: 509 | [s.set_color(BLUE) for s in st] 510 | score_text.append(st) 511 | 512 | for st in score_text: 513 | self.play(AnimationGroup( 514 | *[FadeIn(s) for s in st] 515 | )) 516 | self.wait(0.5) 517 | self.remove(title) 518 | 519 | # STR-10 Legacy Games 520 | 521 | def turn_order(self): 522 | subtypes = [ 523 | "TRN-01 Fixed Turn Order", 524 | "TRN-02 Stat Turn Order", 525 | "TRN-03 Bid Turn Order", 526 | "TRN-04 Progressive Turn Order", 527 | "TRN-05 Claim Turn Order", 528 | "TRN-06 Pass Order", 529 | "TRN-07 Real-Time", 530 | "TRN-08 Punctuated Real-Time", 531 | "TRN-09 Simultaneous Action Selection", 532 | "TRN-10 Role Order", 533 | "TRN-11 Random Turn Order", 534 | "TRN-12 Action Timer", 535 | "TRN-13 Time Track", 536 | "TRN-14 Passed Action Token", 537 | "TRN-15 Interleaved vs. Sequential Phases", 538 | "TRN-16 Lose a Turn", 539 | "TRN-17 Interrupts" 540 | ] 541 | 542 | creature = Meeple() 543 | creature.scale(1.2) 544 | 545 | creatures = [] 546 | creature_positions = [] 547 | for i in range (0,NUM_PLAYERS): 548 | newcreature = creature.copy() 549 | newcreature.set_color(random_bright_color()) 550 | creatures.append(newcreature) 551 | 552 | # TRN-01 Fixed Turn Order 553 | title = Text(subtypes[0], font = "Prompt").set_color(random_bright_color()).to_edge(UP).scale(1.2) 554 | 555 | creature_positions = [4.5*LEFT, 1.5*LEFT, 1.5*RIGHT, 4.5*RIGHT] 556 | for c,p in zip(creatures, creature_positions): 557 | c.move_to(p) 558 | 559 | self.play(AnimationGroup( 560 | Write(title), 561 | *[FadeInFromDown(c) for c in creatures], 562 | lag_ratio = 0.2 563 | )) 564 | self.wait(0.5) 565 | #self.add_sound("Ding") 566 | border = SurroundingRectangle(creatures[0], buff = MED_SMALL_BUFF) 567 | self.play(FadeIn(border)) 568 | 569 | 570 | for i in range(0,NUM_PLAYERS*2): 571 | self.play( 572 | MoveAlongPath(border, 573 | Line( 574 | creatures[i%NUM_PLAYERS].get_center(), 575 | creatures[(i+1)%NUM_PLAYERS].get_center() 576 | ), 577 | rate_func = smooth 578 | ) 579 | ) 580 | #self.add_sound("Ding") 581 | self.remove(title) 582 | --------------------------------------------------------------------------------