├── 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 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------