mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Add progress on project
This commit is contained in:
parent
978b3e71b4
commit
716425247e
5 changed files with 313 additions and 5 deletions
|
|
@ -1,2 +1,3 @@
|
|||
jupyterlab
|
||||
sphinxcontrib-programoutput
|
||||
sphinx-design
|
||||
|
|
|
|||
|
|
@ -1,5 +1,109 @@
|
|||
###############
|
||||
***************
|
||||
A Basic Project
|
||||
###############
|
||||
***************
|
||||
|
||||
This is currently a work in progress.
|
||||
.. image:: ../_static/AdventureManim.png
|
||||
:align: center
|
||||
|
||||
|
||||
**Authors:** `Tristan Schulz <https://github.com/MrDiver>`__ and `Aarush Deshpande <https://github.com/JasonGrace2282>`__
|
||||
|
||||
.. note:: This is a work in progress guide and might not be complete at this point
|
||||
|
||||
############
|
||||
Introduction
|
||||
############
|
||||
Throughout this guide, we'll walk you through how to create a simple 30 second video about vector addition. If you don't
|
||||
already know what that is, it's recommended you watch `this<https://youtu.be/fNk_zzaMoSs?si=fQDML214IeNl0OZ1>`_ video
|
||||
by the original creator of manim, 3Blue1Brown.
|
||||
|
||||
The next step is figuring out how the project should look: what content should it cover, in what order, etc. In this
|
||||
tutorial, we'll focus on two parts of vector addition: the algebraic way, and the geometric way. For the algebraic way,
|
||||
we'll show two vectors (as matricies) being added, and give a short explanation. After that we'll show the typical tip-to-tail
|
||||
method for adding vectors graphically. Of course, choosing good examples is very important to help the viewer understand.
|
||||
In our case, we'll use the two vectors :math:`v_1\equiv\langle 2, 1\rangle` and :math:`v_2\equiv\langle 0,-3 \rangle`.
|
||||
|
||||
#########################
|
||||
Algebraic Vector Addition
|
||||
#########################
|
||||
|
||||
We'll start with the basic setup needed for every manim video. Create
|
||||
a new file called `vector_addition.py`, and paste the contents here.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from manim import *
|
||||
|
||||
|
||||
class VectorAddition(Scene):
|
||||
def construct(self) -> None:
|
||||
self.play(Create(Circle()))
|
||||
|
||||
|
||||
# if you're used to rendering from the terminal,
|
||||
# this way you can just run the python file instead
|
||||
# of doing manim -p vector_addition.py VectorAddition
|
||||
with tempconfig({"preview": True}):
|
||||
VectorAddition().render()
|
||||
|
||||
If you did it correctly, running the python file (either through your IDE
|
||||
or through the terminal with ``python3 vector_addition.py``) should render a scene
|
||||
with a circle being created:
|
||||
|
||||
.. manim:: CreateCircle
|
||||
:hide_source:
|
||||
|
||||
class CreateCircle(Scene):
|
||||
def construct(self):
|
||||
self.play(Create(Circle()))
|
||||
|
||||
============
|
||||
Introduction
|
||||
============
|
||||
First we need to introduce the viewer to what we're going to talk about. Ideally,
|
||||
it would be an interesting hook, but for the sake of learning the library we will
|
||||
stick with a simple text-based intro. Try to recreate the following:
|
||||
|
||||
.. manim:: AdventureIntro
|
||||
:hide_source:
|
||||
:ref_classes: Tex Text Write Unwrite Create
|
||||
|
||||
class AdventureIntro(Scene):
|
||||
def construct(self):
|
||||
intro = Text("Let's try to add two vectors!")
|
||||
# put an r"" instead of a normal string so we don't have any special characters like \n
|
||||
vec_txts = Tex(r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$")
|
||||
self.play(Create(intro))
|
||||
self.wait(1)
|
||||
# "grey out" the intro and shift it upwards as we write the second line
|
||||
self.play(intro.animate.shift(2*UP).set_opacity(0.5), Write(vec_txts))
|
||||
self.wait(1)
|
||||
self.play(Unwrite(intro), Unwrite(vec_txts), run_time=.5)
|
||||
self.wait(0.2)
|
||||
|
||||
.. dropdown:: Authors Solution
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class AdventureIntro(Scene):
|
||||
def construct(self):
|
||||
intro = Text("Let's try to add two vectors!")
|
||||
# put an r"" instead of a normal string so we don't have any special characters like \n
|
||||
vec_txts = Tex(
|
||||
r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$"
|
||||
)
|
||||
self.play(Create(intro))
|
||||
self.wait(1)
|
||||
# "grey out" the intro and shift it upwards as we write the second line
|
||||
self.play(intro.animate.shift(2 * UP).set_opacity(0.5), Write(vec_txts))
|
||||
self.wait(1)
|
||||
self.play(Unwrite(intro), Unwrite(vec_txts), run_time=0.5)
|
||||
self.wait(0.2)
|
||||
|
||||
|
||||
################
|
||||
The Final Result
|
||||
################
|
||||
Putting it all together, we can render the final result.
|
||||
|
||||
.. include:: vector_addition.rst
|
||||
|
|
|
|||
179
docs/source/adventure/vector_addition.rst
Normal file
179
docs/source/adventure/vector_addition.rst
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
.. manim:: Adventure
|
||||
:hide_source:
|
||||
|
||||
class VectorGroup(VGroup):
|
||||
def __init__(
|
||||
self, start, end, labelname: str,
|
||||
vector_color: ParsableManimColor, direction = RIGHT,
|
||||
plane: NumberPlane | None = None, **kwargs
|
||||
) -> None:
|
||||
if plane is not None:
|
||||
# if using a plane convert from plane units
|
||||
# to Munits
|
||||
start = plane.c2p(*start)
|
||||
end = plane.c2p(*end)
|
||||
|
||||
self.vector = Arrow(
|
||||
start,
|
||||
end,
|
||||
color=vector_color,
|
||||
buff=0
|
||||
)
|
||||
self.label = MathTex(labelname, color=vector_color)
|
||||
|
||||
def label_updater(m: MathTex, d=direction):
|
||||
m.next_to(self.vector, direction=d, **kwargs)
|
||||
|
||||
self.label.add_updater(label_updater, call_updater=True)
|
||||
super().__init__(self.vector, self.label, **kwargs)
|
||||
|
||||
@override_animation(Create)
|
||||
def _create_vec_write_label(self) -> AnimationGroup:
|
||||
return AnimationGroup(
|
||||
Create(self.vector),
|
||||
Write(self.label),
|
||||
lag_ratio=0
|
||||
)
|
||||
|
||||
@override_animation(Uncreate)
|
||||
def _uncreate_vec_unwrite_label(self) -> AnimationGroup:
|
||||
return AnimationGroup(
|
||||
Uncreate(self.vector),
|
||||
Unwrite(self.label),
|
||||
lag_ratio=0
|
||||
)
|
||||
class Adventure(Scene):
|
||||
"""Goal: Make an example showcasing manim's features"""
|
||||
|
||||
def construct(self) -> None:
|
||||
intro = Text("Let's try to add two vectors!")
|
||||
vec_txts = Tex(r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$")
|
||||
self.play(Create(intro))
|
||||
self.wait(1)
|
||||
self.play(intro.animate.shift(2*UP).set_opacity(0.5), Write(vec_txts))
|
||||
self.wait(1)
|
||||
self.play(Unwrite(intro), Unwrite(vec_txts), run_time=.5)
|
||||
self.wait(0.2)
|
||||
|
||||
self.show_addition_math()
|
||||
self.wait(0.2)
|
||||
self.show_vector_addition()
|
||||
|
||||
outro = Text("Thanks for watching!")
|
||||
self.play(Create(outro))
|
||||
self.wait()
|
||||
|
||||
def show_addition_math(self) -> None:
|
||||
title = Title("Vector Addition Algebraically")
|
||||
|
||||
v1x, v1y = (2, 2)
|
||||
v2x, v2y = (0, -3)
|
||||
math = MathTex(r"""
|
||||
\begin{bmatrix} %(v1x)d \\ %(v1y)d \end{bmatrix}
|
||||
+\begin{bmatrix} %(v2x)d \\ %(v2y)d \end{bmatrix}
|
||||
""" % {
|
||||
'v1x': v1x,
|
||||
'v2x': v2x,
|
||||
'v1y': v1y,
|
||||
'v2y': v2y
|
||||
}).shift(DOWN)
|
||||
|
||||
resultant_vector = r"=\begin{bmatrix} %(x)d \\ %(y)d \end{bmatrix}" % {
|
||||
'x': v1x+v2x,
|
||||
'y': v1y+v2y
|
||||
}
|
||||
math_with_answer = MathTex(
|
||||
math.get_tex_string()+resultant_vector
|
||||
).move_to(math.get_center())
|
||||
|
||||
self.play(Write(math), FadeIn(title))
|
||||
self.wait(2)
|
||||
self.play(
|
||||
math.animate.shift(2*UP).set_opacity(0.5),
|
||||
Write(math_with_answer)
|
||||
)
|
||||
conclusion = Paragraph("As you can see,\nYou add each component individually").to_edge(DOWN)
|
||||
self.play(Write(conclusion))
|
||||
self.wait(2)
|
||||
self.play(Unwrite(math), Unwrite(math_with_answer), Unwrite(conclusion), Unwrite(title))
|
||||
|
||||
def show_vector_addition(self) -> None:
|
||||
title = Text("Now let's take a look at it geometrically")
|
||||
self.play(Write(title))
|
||||
self.wait(2)
|
||||
self.play(Unwrite(title))
|
||||
|
||||
plane = NumberPlane()
|
||||
|
||||
sum_point = (2, -1, 0)
|
||||
|
||||
v1 = VectorGroup(
|
||||
ORIGIN,
|
||||
(2, 2, 0),
|
||||
r"\boldsymbol{\vec{v}_1}",
|
||||
RED,
|
||||
direction=UP,
|
||||
plane=plane
|
||||
)
|
||||
|
||||
v2 = VectorGroup(
|
||||
ORIGIN,
|
||||
(0, -3, 0),
|
||||
r"\boldsymbol{\vec{v}_2}",
|
||||
YELLOW,
|
||||
direction=LEFT,
|
||||
plane=plane
|
||||
)
|
||||
|
||||
v1moved = VectorGroup(
|
||||
(0, -3, 0),
|
||||
sum_point,
|
||||
r"\boldsymbol{\vec{v}_1}",
|
||||
v1.vector.get_color(),
|
||||
plane=plane
|
||||
)
|
||||
|
||||
v2moved = VectorGroup(
|
||||
(2, 2, 0),
|
||||
sum_point,
|
||||
r"\boldsymbol{\vec{v}_2}",
|
||||
v2.vector.get_color(),
|
||||
plane=plane
|
||||
)
|
||||
|
||||
sum_vec = VectorGroup(
|
||||
ORIGIN,
|
||||
sum_point,
|
||||
r"\boldsymbol{\vec{v}_1}+\boldsymbol{\vec{v}_2}",
|
||||
ORANGE,
|
||||
direction=DOWN,
|
||||
plane=plane
|
||||
)
|
||||
|
||||
self.play(Create(plane), Create(v1))
|
||||
self.wait(0.5)
|
||||
self.play(Create(v2))
|
||||
self.wait()
|
||||
|
||||
# animate movement of vectors
|
||||
self.play(
|
||||
Succession(
|
||||
ReplacementTransform(v1.copy(), v1moved),
|
||||
ReplacementTransform(v2.copy(), v2moved)
|
||||
)
|
||||
)
|
||||
self.wait()
|
||||
# draw sum vector
|
||||
self.play(Create(sum_vec))
|
||||
self.wait()
|
||||
self.play(*[
|
||||
Uncreate(x)
|
||||
for x in (
|
||||
plane,
|
||||
v1,
|
||||
v2,
|
||||
v1moved,
|
||||
v2moved,
|
||||
sum_vec
|
||||
)
|
||||
])
|
||||
27
poetry.lock
generated
27
poetry.lock
generated
|
|
@ -1,4 +1,4 @@
|
|||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
|
|
@ -3942,6 +3942,29 @@ sphinx = ">=1.8"
|
|||
code-style = ["pre-commit (==2.12.1)"]
|
||||
rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx-design"
|
||||
version = "0.5.0"
|
||||
description = "A sphinx extension for designing beautiful, view size responsive web components."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "sphinx_design-0.5.0-py3-none-any.whl", hash = "sha256:1af1267b4cea2eedd6724614f19dcc88fe2e15aff65d06b2f6252cee9c4f4c1e"},
|
||||
{file = "sphinx_design-0.5.0.tar.gz", hash = "sha256:e8e513acea6f92d15c6de3b34e954458f245b8e761b45b63950f65373352ab00"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
sphinx = ">=5,<8"
|
||||
|
||||
[package.extras]
|
||||
code-style = ["pre-commit (>=3,<4)"]
|
||||
rtd = ["myst-parser (>=1,<3)"]
|
||||
testing = ["myst-parser (>=1,<3)", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"]
|
||||
theme-furo = ["furo (>=2023.7.0,<2023.8.0)"]
|
||||
theme-pydata = ["pydata-sphinx-theme (>=0.13.0,<0.14.0)"]
|
||||
theme-rtd = ["sphinx-rtd-theme (>=1.0,<2.0)"]
|
||||
theme-sbt = ["sphinx-book-theme (>=1.0,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-applehelp"
|
||||
version = "1.0.8"
|
||||
|
|
@ -4533,4 +4556,4 @@ jupyterlab = ["jupyterlab", "notebook"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.9,<3.13"
|
||||
content-hash = "ee587c7e3241bf8bbd6334cd1de08bc53d3521978ccd68f9ac54a2cc7f61466f"
|
||||
content-hash = "28e28a2361319583a060b20889be9470d479a49f4fca5775dc83bdbf490a5a41"
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ Sphinx = "^7.2.6"
|
|||
sphinx-copybutton = "^0.5.2"
|
||||
sphinxcontrib-programoutput = "^0.17"
|
||||
sphinxext-opengraph = "^0.9.1"
|
||||
sphinx-design = "^0.5.0"
|
||||
types-decorator = "^0.1.7"
|
||||
types-Pillow = "^10.1.0.2"
|
||||
types-Pygments = "^2.17.0.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue