mirror of
https://github.com/3b1b/manim.git
synced 2025-07-29 21:12:35 +08:00
begin quat3d animations
This commit is contained in:
152
active_projects/quat3d.py
Normal file
152
active_projects/quat3d.py
Normal file
@ -0,0 +1,152 @@
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
from active_projects.quaternions import *
|
||||
|
||||
W_COLOR = YELLOW
|
||||
I_COLOR = GREEN
|
||||
J_COLOR = RED
|
||||
K_COLOR = BLUE
|
||||
|
||||
|
||||
class QuaternionLabel(VGroup):
|
||||
CONFIG = {
|
||||
"decimal_config": {}
|
||||
}
|
||||
|
||||
def __init__(self, quat, **kwargs):
|
||||
VGroup.__init__(self, **kwargs)
|
||||
dkwargs = dict(self.decimal_config)
|
||||
self.add(DecimalNumber(quat[0], color=W_COLOR, **dkwargs))
|
||||
dkwargs["include_sign"] = True
|
||||
self.add(
|
||||
DecimalNumber(quat[1], color=I_COLOR, **dkwargs),
|
||||
TexMobject("i"),
|
||||
DecimalNumber(quat[2], color=J_COLOR, **dkwargs),
|
||||
TexMobject("j"),
|
||||
DecimalNumber(quat[3], color=K_COLOR, **dkwargs),
|
||||
TexMobject("k"),
|
||||
)
|
||||
self.arrange_submobjects(RIGHT, buff=SMALL_BUFF)
|
||||
|
||||
|
||||
# Scenes
|
||||
|
||||
class Introduction(QuaternionHistory):
|
||||
CONFIG = {
|
||||
"names_and_quotes": [
|
||||
(
|
||||
"Oliver Heaviside",
|
||||
"""\\Huge ``the quaternion was not only not
|
||||
required, but was a positive evil''"""
|
||||
),
|
||||
(
|
||||
"Lord Kelvin",
|
||||
"""\\Huge ``Quaternions... though beautifully \\\\ ingenious,
|
||||
have been an unmixed evil'' """
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
title_word = TextMobject("Quaternions:")
|
||||
title_equation = TexMobject(
|
||||
"i^2 = j^2 = k^2 = ijk = -1",
|
||||
tex_to_color_map={
|
||||
"i": I_COLOR,
|
||||
"j": J_COLOR,
|
||||
"k": K_COLOR,
|
||||
}
|
||||
)
|
||||
# label = QuaternionLabel([
|
||||
# float(str((TAU * 10**(3 * k)) % 10)[:4])
|
||||
# for k in range(4)
|
||||
# ])
|
||||
title = VGroup(title_word, title_equation)
|
||||
title.arrange_submobjects(RIGHT)
|
||||
title.to_edge(UP)
|
||||
|
||||
images_group = self.get_dissenter_images_quotes_and_names()
|
||||
images_group.to_edge(DOWN)
|
||||
images, quotes, names = images_group
|
||||
for pair in images_group:
|
||||
pair[1].align_to(pair[0], UP)
|
||||
|
||||
self.play(
|
||||
FadeInFromDown(title_word),
|
||||
Write(title_equation)
|
||||
)
|
||||
self.wait()
|
||||
self.play(
|
||||
LaggedStart(
|
||||
FadeInFrom, images,
|
||||
lambda m: (m, 3 * DOWN),
|
||||
lag_ratio=0.75
|
||||
),
|
||||
LaggedStart(FadeInFromLarge, names, lag_ratio=0.75),
|
||||
*[
|
||||
LaggedStart(
|
||||
FadeIn, VGroup(*it.chain(*quote)),
|
||||
lag_ratio=0.3,
|
||||
run_time=3
|
||||
)
|
||||
for quote in quotes
|
||||
],
|
||||
)
|
||||
self.wait(2)
|
||||
self.play(
|
||||
title.shift, 2 * UP,
|
||||
*[
|
||||
ApplyMethod(mob.shift, FRAME_WIDTH * vect / 2)
|
||||
for pair in images_group
|
||||
for mob, vect in zip(pair, [LEFT, RIGHT])
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class WhoCares(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
quotes = Group(*[
|
||||
ImageMobject(
|
||||
"CoderQuaternionResponse_{}".format(d),
|
||||
height=2
|
||||
)
|
||||
for d in range(4)
|
||||
])
|
||||
logos = Group(*[
|
||||
ImageMobject(name, height=0.5)
|
||||
for name in [
|
||||
"TwitterLogo",
|
||||
"HackerNewsLogo",
|
||||
"RedditLogo",
|
||||
"YouTubeLogo",
|
||||
]
|
||||
])
|
||||
for quote, logo in zip(quotes, logos):
|
||||
logo.move_to(quote.get_corner(UR))
|
||||
quote.add(logo)
|
||||
|
||||
quotes.arrange_submobjects_in_grid()
|
||||
quotes.set_height(4)
|
||||
quotes.to_corner(UL)
|
||||
|
||||
self.student_says(
|
||||
"Um...who cares?",
|
||||
target_mode="sassy",
|
||||
added_anims=[self.teacher.change, "guilty"]
|
||||
)
|
||||
self.wait(2)
|
||||
self.play(
|
||||
RemovePiCreatureBubble(self.students[1]),
|
||||
self.teacher.change, "raise_right_hand"
|
||||
)
|
||||
self.play(
|
||||
LaggedStart(
|
||||
FadeInFromDown, quotes,
|
||||
run_time=3
|
||||
),
|
||||
self.get_student_changes(*3 * ["pondering"], look_at_arg=quotes)
|
||||
)
|
||||
self.wait(2)
|
||||
|
||||
# Show HN
|
||||
|
||||
# Show Twitter
|
@ -728,6 +728,24 @@ class IntroduceHamilton(Scene):
|
||||
|
||||
|
||||
class QuaternionHistory(Scene):
|
||||
CONFIG = {
|
||||
"names_and_quotes": [
|
||||
(
|
||||
"Oliver Heaviside",
|
||||
"""\\huge ``As far as the vector analysis I required was
|
||||
concerned, the quaternion was not only not
|
||||
required, but was a positive evil of no
|
||||
inconsiderable magnitude.''"""
|
||||
),
|
||||
(
|
||||
"Lord Kelvin",
|
||||
"""\\huge ``Quaternions... though beautifully \\\\ ingenious,
|
||||
have been an unmixed evil to those who have
|
||||
touched them in any way, including Clerk Maxwell.''"""
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
self.show_dot_product_and_cross_product()
|
||||
self.teaching_students_quaternions()
|
||||
@ -901,48 +919,8 @@ class QuaternionHistory(Scene):
|
||||
self.equation = equation
|
||||
|
||||
def show_anti_quaternion_quote(self):
|
||||
names_and_quotes = [
|
||||
(
|
||||
"Oliver Heaviside",
|
||||
"""``As far as the vector analysis I required was
|
||||
concerned, the quaternion was not only not
|
||||
required, but was a positive evil of no
|
||||
inconsiderable magnitude.''"""
|
||||
),
|
||||
(
|
||||
"Lord Kelvin",
|
||||
"""``Quaternions... though beautifully \\\\ ingenious,
|
||||
have been an unmixed evil to those who have
|
||||
touched them in any way, including Clerk Maxwell.''"""
|
||||
),
|
||||
]
|
||||
images = Group()
|
||||
quotes = VGroup()
|
||||
names = VGroup()
|
||||
images_with_quotes = Group()
|
||||
for name, quote_text in names_and_quotes:
|
||||
image = Group(ImageMobject(name))
|
||||
image.set_height(4)
|
||||
label = TextMobject(name)
|
||||
label.next_to(image, DOWN)
|
||||
names.add(label)
|
||||
quote = TextMobject(
|
||||
"\\huge " + quote_text,
|
||||
tex_to_color_map={
|
||||
"positive evil": RED,
|
||||
"unmixed evil": RED,
|
||||
},
|
||||
alignment=""
|
||||
)
|
||||
quote.scale(0.3)
|
||||
quote.next_to(image, UP)
|
||||
images.add(image)
|
||||
quotes.add(quote)
|
||||
images_with_quotes.add(Group(image, label, quote))
|
||||
|
||||
images_with_quotes.arrange_submobjects(RIGHT, buff=LARGE_BUFF)
|
||||
images_with_quotes.to_edge(DOWN, MED_LARGE_BUFF)
|
||||
|
||||
group = self.get_dissenter_images_quotes_and_names()
|
||||
images, quotes, names = group
|
||||
self.play(
|
||||
LaggedStart(FadeInFromDown, images),
|
||||
LaggedStart(FadeInFromLarge, names),
|
||||
@ -1052,6 +1030,37 @@ class QuaternionHistory(Scene):
|
||||
self.remove(characters)
|
||||
self.wait()
|
||||
|
||||
#
|
||||
def get_dissenter_images_quotes_and_names(self):
|
||||
names_and_quotes = self.names_and_quotes
|
||||
images = Group()
|
||||
quotes = VGroup()
|
||||
names = VGroup()
|
||||
images_with_quotes = Group()
|
||||
for name, quote_text in names_and_quotes:
|
||||
image = Group(ImageMobject(name))
|
||||
image.set_height(4)
|
||||
label = TextMobject(name)
|
||||
label.next_to(image, DOWN)
|
||||
names.add(label)
|
||||
quote = TextMobject(
|
||||
quote_text,
|
||||
tex_to_color_map={
|
||||
"positive evil": RED,
|
||||
"unmixed evil": RED,
|
||||
},
|
||||
alignment=""
|
||||
)
|
||||
quote.scale(0.3)
|
||||
quote.next_to(image, UP)
|
||||
images.add(image)
|
||||
quotes.add(quote)
|
||||
images_with_quotes.add(Group(image, label, quote))
|
||||
|
||||
images_with_quotes.arrange_submobjects(RIGHT, buff=LARGE_BUFF)
|
||||
images_with_quotes.to_edge(DOWN, MED_LARGE_BUFF)
|
||||
return Group(images, quotes, names)
|
||||
|
||||
|
||||
class QuaternionRotationOverlay(Scene):
|
||||
def construct(self):
|
||||
|
Reference in New Issue
Block a user