mirror of
https://github.com/3b1b/manim.git
synced 2025-09-19 04:41:56 +00:00
Up to intro of squaring method in triples project
This commit is contained in:
parent
abccab83bf
commit
b7011ac9e9
3 changed files with 750 additions and 11 deletions
|
@ -189,7 +189,7 @@ class ComplexPlane(NumberPlane):
|
||||||
return self.coords_to_point(number.real, number.imag)
|
return self.coords_to_point(number.real, number.imag)
|
||||||
|
|
||||||
def get_coordinate_labels(self, *numbers):
|
def get_coordinate_labels(self, *numbers):
|
||||||
result = []
|
result = VGroup()
|
||||||
nudge = 0.1*(DOWN+RIGHT)
|
nudge = 0.1*(DOWN+RIGHT)
|
||||||
if len(numbers) == 0:
|
if len(numbers) == 0:
|
||||||
numbers = range(-int(self.x_radius), int(self.x_radius))
|
numbers = range(-int(self.x_radius), int(self.x_radius))
|
||||||
|
@ -206,7 +206,7 @@ class ComplexPlane(NumberPlane):
|
||||||
num = TexMobject(num_str)
|
num = TexMobject(num_str)
|
||||||
num.scale(self.number_scale_factor)
|
num.scale(self.number_scale_factor)
|
||||||
num.shift(point-num.get_corner(UP+LEFT)+nudge)
|
num.shift(point-num.get_corner(UP+LEFT)+nudge)
|
||||||
result.append(num)
|
result.add(num)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def add_coordinates(self, *numbers):
|
def add_coordinates(self, *numbers):
|
||||||
|
|
|
@ -139,7 +139,6 @@ class NumberPlane(VMobject):
|
||||||
"y_line_frequency" : 1,
|
"y_line_frequency" : 1,
|
||||||
"secondary_line_ratio" : 1,
|
"secondary_line_ratio" : 1,
|
||||||
"written_coordinate_height" : 0.2,
|
"written_coordinate_height" : 0.2,
|
||||||
"written_coordinate_nudge" : 0.1*(DOWN+RIGHT),
|
|
||||||
"propogate_style_to_family" : False,
|
"propogate_style_to_family" : False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
756
triples.py
756
triples.py
|
@ -1,4 +1,5 @@
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
import fractions
|
||||||
|
|
||||||
from mobject.tex_mobject import TexMobject
|
from mobject.tex_mobject import TexMobject
|
||||||
from mobject import Mobject
|
from mobject import Mobject
|
||||||
|
@ -32,6 +33,8 @@ A_COLOR = BLUE
|
||||||
B_COLOR = GREEN
|
B_COLOR = GREEN
|
||||||
C_COLOR = YELLOW
|
C_COLOR = YELLOW
|
||||||
SIDE_COLORS = [A_COLOR, B_COLOR, C_COLOR]
|
SIDE_COLORS = [A_COLOR, B_COLOR, C_COLOR]
|
||||||
|
U_COLOR = MAROON_B
|
||||||
|
V_COLOR = RED
|
||||||
|
|
||||||
#revert_to_original_skipping_status
|
#revert_to_original_skipping_status
|
||||||
|
|
||||||
|
@ -88,6 +91,17 @@ class IntroduceTriples(TeacherStudentsScene):
|
||||||
self.dither()
|
self.dither()
|
||||||
self.dither(2)
|
self.dither(2)
|
||||||
|
|
||||||
|
class LastVideoWrapper(Scene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Pi hiding in prime regularities")
|
||||||
|
title.to_edge(UP)
|
||||||
|
screen_rect = ScreenRectangle(height = 6)
|
||||||
|
screen_rect.next_to(title, DOWN)
|
||||||
|
|
||||||
|
self.play(ShowCreation(screen_rect))
|
||||||
|
self.play(Write(title))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
class PythagoreanProof(Scene):
|
class PythagoreanProof(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.add_title()
|
self.add_title()
|
||||||
|
@ -236,14 +250,740 @@ class PythagoreanProof(Scene):
|
||||||
t2, t3 = group
|
t2, t3 = group
|
||||||
return VGroup(t1, t2, t3)
|
return VGroup(t1, t2, t3)
|
||||||
|
|
||||||
|
class ShowManyTriples(Scene):
|
||||||
|
def construct(self):
|
||||||
|
triples = [
|
||||||
|
(u**2 - v**2, 2*u*v, u**2 + v**2)
|
||||||
|
for u in range(1, 15)
|
||||||
|
for v in range(1, u)
|
||||||
|
if fractions.gcd(u, v) == 1 and not (u%2 == v%2)
|
||||||
|
][:40]
|
||||||
|
triangles = VGroup()
|
||||||
|
titles = VGroup()
|
||||||
|
for i, (a, b, c) in enumerate(triples):
|
||||||
|
triangle = Polygon(ORIGIN, a*RIGHT, a*RIGHT+b*UP)
|
||||||
|
triangle.highlight(WHITE)
|
||||||
|
max_width = max_height = 4
|
||||||
|
triangle.scale_to_fit_height(max_height)
|
||||||
|
if triangle.get_width() > max_width:
|
||||||
|
triangle.scale_to_fit_width(max_width)
|
||||||
|
triangle.move_to(2*RIGHT)
|
||||||
|
num_strings = map(str, (a, b, c))
|
||||||
|
labels = map(TexMobject, num_strings)
|
||||||
|
for label, color in zip(labels, SIDE_COLORS):
|
||||||
|
label.highlight(color)
|
||||||
|
labels[0].next_to(triangle, DOWN)
|
||||||
|
labels[1].next_to(triangle, RIGHT)
|
||||||
|
labels[2].next_to(triangle.get_center(), UP+LEFT)
|
||||||
|
triangle.add(*labels)
|
||||||
|
|
||||||
|
title = TexMobject(
|
||||||
|
str(a), "^2", "+", str(b), "^2", "=", str(c), "^2"
|
||||||
|
)
|
||||||
|
for num, color in zip([a, b, c], SIDE_COLORS):
|
||||||
|
title.highlight_by_tex(str(num), color)
|
||||||
|
title.next_to(triangle, UP, LARGE_BUFF)
|
||||||
|
title.generate_target()
|
||||||
|
title.target.scale(0.5)
|
||||||
|
|
||||||
|
title.target.move_to(
|
||||||
|
(-SPACE_WIDTH + MED_LARGE_BUFF + 2.7*(i//8))*RIGHT + \
|
||||||
|
(SPACE_HEIGHT - MED_LARGE_BUFF - (i%8))*UP,
|
||||||
|
UP+LEFT
|
||||||
|
)
|
||||||
|
|
||||||
|
triangles.add(triangle)
|
||||||
|
titles.add(title)
|
||||||
|
|
||||||
|
triangle = triangles[0]
|
||||||
|
title = titles[0]
|
||||||
|
self.play(
|
||||||
|
Write(triangle),
|
||||||
|
Write(title),
|
||||||
|
run_time = 2,
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(MoveToTarget(title))
|
||||||
|
for i in range(1, 17):
|
||||||
|
new_triangle = triangles[i]
|
||||||
|
new_title = titles[i]
|
||||||
|
if i < 4:
|
||||||
|
self.play(
|
||||||
|
Transform(triangle, new_triangle),
|
||||||
|
FadeIn(new_title)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(MoveToTarget(new_title))
|
||||||
|
else:
|
||||||
|
self.play(
|
||||||
|
Transform(triangle, new_triangle),
|
||||||
|
FadeIn(new_title.target)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(triangle))
|
||||||
|
self.play(LaggedStart(
|
||||||
|
FadeIn,
|
||||||
|
VGroup(*[
|
||||||
|
title.target
|
||||||
|
for title in titles[17:]
|
||||||
|
]),
|
||||||
|
run_time = 5
|
||||||
|
))
|
||||||
|
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
class CompareToFermatsLastTheorem(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
expressions = [
|
||||||
|
TexMobject(
|
||||||
|
"a", "^%d"%d, "+", "b", "^%d"%d,
|
||||||
|
"=", "c", "^%d"%d
|
||||||
|
)
|
||||||
|
for d in range(2, 9)
|
||||||
|
]
|
||||||
|
for expression in expressions:
|
||||||
|
for char, color in zip("abc", SIDE_COLORS):
|
||||||
|
expression.highlight_by_tex(char, color)
|
||||||
|
expression.next_to(self.get_pi_creatures(), UP, buff = 1.3)
|
||||||
|
square_expression = expressions[0]
|
||||||
|
low_expression = expressions[1]
|
||||||
|
square_expression.to_edge(UP, buff = 1.3)
|
||||||
|
top_brace = Brace(square_expression, UP, buff = SMALL_BUFF)
|
||||||
|
top_text = top_brace.get_text(
|
||||||
|
"Abundant integer solutions", buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
low_brace = Brace(low_expression, DOWN, buff = SMALL_BUFF)
|
||||||
|
low_text = low_brace.get_text(
|
||||||
|
"No integer solutions", buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
low_text.highlight(RED)
|
||||||
|
|
||||||
|
self.add(square_expression, top_brace, top_text)
|
||||||
|
self.play(
|
||||||
|
ReplacementTransform(
|
||||||
|
square_expression.copy(),
|
||||||
|
low_expression
|
||||||
|
),
|
||||||
|
self.teacher.change_mode, "raise_right_hand",
|
||||||
|
*[
|
||||||
|
ApplyMethod(pi.change, "confused", expressions[1])
|
||||||
|
for pi in self.get_students()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(Transform(low_expression, expressions[2]))
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(low_brace),
|
||||||
|
FadeIn(low_text),
|
||||||
|
)
|
||||||
|
self.change_student_modes(
|
||||||
|
"sassy", "angry", "erm",
|
||||||
|
look_at_arg = low_expression,
|
||||||
|
added_anims = [Transform(low_expression, expressions[3])]
|
||||||
|
)
|
||||||
|
for expression in expressions[4:]:
|
||||||
|
self.play(Transform(low_expression, expression))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class BabylonianTablets(Scene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Plimpton 322 Tablets \\\\ (1800 BC)")
|
||||||
|
title.to_corner(UP+LEFT)
|
||||||
|
ac_pairs = [
|
||||||
|
(119, 169),
|
||||||
|
(3367, 4825),
|
||||||
|
(4601, 6649),
|
||||||
|
(12709, 18541),
|
||||||
|
(65, 97),
|
||||||
|
(319, 481),
|
||||||
|
(2291, 3541),
|
||||||
|
(799, 1249),
|
||||||
|
(481, 769),
|
||||||
|
(4961, 8161),
|
||||||
|
(45, 75),
|
||||||
|
(1679, 2929),
|
||||||
|
(161, 289),
|
||||||
|
(1771, 3229),
|
||||||
|
(56, 106),
|
||||||
|
]
|
||||||
|
triples = VGroup()
|
||||||
|
for a, c in ac_pairs:
|
||||||
|
b = int(np.sqrt(c**2 - a**2))
|
||||||
|
tex = "%s^2 + %s^2 = %s^2"%tuple(
|
||||||
|
map("{:,}".format, [a, b, c])
|
||||||
|
)
|
||||||
|
tex = tex.replace(",", "{,}")
|
||||||
|
triple = TexMobject(tex)
|
||||||
|
triples.add(triple)
|
||||||
|
triples.arrange_submobjects(DOWN, aligned_edge = LEFT)
|
||||||
|
triples.scale_to_fit_height(2*SPACE_HEIGHT - LARGE_BUFF)
|
||||||
|
triples.to_edge(RIGHT)
|
||||||
|
|
||||||
|
self.add(title)
|
||||||
|
self.dither()
|
||||||
|
self.play(LaggedStart(FadeIn, triples, run_time = 5))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class ReframeOnLattice(PiCreatureScene):
|
||||||
|
CONFIG = {
|
||||||
|
"initial_plane_center" : 3*LEFT + DOWN,
|
||||||
|
"new_plane_center" : ORIGIN,
|
||||||
|
"initial_unit_size" : 0.5,
|
||||||
|
"new_unit_size" : 0.8,
|
||||||
|
"dot_radius" : 0.075,
|
||||||
|
"dot_color" : YELLOW,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.remove(self.pi_creature)
|
||||||
|
self.add_plane()
|
||||||
|
self.wander_over_lattice_points()
|
||||||
|
self.show_whole_distance_examples()
|
||||||
|
self.resize_plane()
|
||||||
|
self.show_root_example()
|
||||||
|
self.view_as_complex_number()
|
||||||
|
self.mention_squaring_it()
|
||||||
|
self.work_out_square_algebraically()
|
||||||
|
self.walk_through_square_geometrically()
|
||||||
|
|
||||||
|
def add_plane(self):
|
||||||
|
plane = ComplexPlane(
|
||||||
|
center_point = self.initial_plane_center,
|
||||||
|
unit_size = self.initial_unit_size,
|
||||||
|
stroke_width = 2,
|
||||||
|
secondary_line_ratio = 0,
|
||||||
|
)
|
||||||
|
plane.axes.set_stroke(width = 4)
|
||||||
|
plane.coordinate_labels = VGroup()
|
||||||
|
for x in range(-8, 20, 2):
|
||||||
|
if x == 0:
|
||||||
|
continue
|
||||||
|
label = TexMobject(str(x))
|
||||||
|
label.scale(0.5)
|
||||||
|
label.add_background_rectangle(opacity = 1)
|
||||||
|
label.next_to(plane.coords_to_point(x, 0), DOWN, SMALL_BUFF)
|
||||||
|
plane.coordinate_labels.add(label)
|
||||||
|
|
||||||
|
self.add(plane, plane.coordinate_labels)
|
||||||
|
self.plane = plane
|
||||||
|
|
||||||
|
def wander_over_lattice_points(self):
|
||||||
|
initial_examples = [(5, 3), (6, 8), (2, 7)]
|
||||||
|
integer_distance_examples = [(3, 4), (12, 5), (15, 8)]
|
||||||
|
dot_tuple_groups = VGroup()
|
||||||
|
for x, y in initial_examples + integer_distance_examples:
|
||||||
|
dot = Dot(
|
||||||
|
self.plane.coords_to_point(x, y),
|
||||||
|
color = self.dot_color,
|
||||||
|
radius = self.dot_radius,
|
||||||
|
)
|
||||||
|
tuple_mob = TexMobject("(", str(x), ",", str(y), ")")
|
||||||
|
tuple_mob.add_background_rectangle()
|
||||||
|
tuple_mob.next_to(dot, UP+RIGHT, buff = 0)
|
||||||
|
dot_tuple_groups.add(VGroup(dot, tuple_mob))
|
||||||
|
dot_tuple_group = dot_tuple_groups[0]
|
||||||
|
final_group = dot_tuple_groups[-len(integer_distance_examples)]
|
||||||
|
|
||||||
|
all_dots = self.get_all_plane_dots()
|
||||||
|
|
||||||
|
self.play(Write(dot_tuple_group, run_time = 2))
|
||||||
|
self.dither()
|
||||||
|
for new_group in dot_tuple_groups[1:len(initial_examples)]:
|
||||||
|
self.play(Transform(dot_tuple_group, new_group))
|
||||||
|
self.dither()
|
||||||
|
self.play(LaggedStart(
|
||||||
|
FadeIn, all_dots,
|
||||||
|
rate_func = there_and_back,
|
||||||
|
run_time = 3,
|
||||||
|
lag_ratio = 0.2,
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
self.play(ReplacementTransform(
|
||||||
|
dot_tuple_group, final_group
|
||||||
|
))
|
||||||
|
|
||||||
|
self.integer_distance_dot_tuple_groups = VGroup(
|
||||||
|
*dot_tuple_groups[len(initial_examples):]
|
||||||
|
)
|
||||||
|
|
||||||
|
def show_whole_distance_examples(self):
|
||||||
|
dot_tuple_groups = self.integer_distance_dot_tuple_groups
|
||||||
|
for dot_tuple_group in dot_tuple_groups:
|
||||||
|
dot, tuple_mob = dot_tuple_group
|
||||||
|
p0 = self.plane.get_center_point()
|
||||||
|
p1 = dot.get_center()
|
||||||
|
triangle = Polygon(
|
||||||
|
p0, p1[0]*RIGHT + p0[1]*UP, p1,
|
||||||
|
stroke_width = 0,
|
||||||
|
fill_color = BLUE,
|
||||||
|
fill_opacity = 0.75,
|
||||||
|
)
|
||||||
|
line = Line(p0, p1, color = dot.get_color())
|
||||||
|
a, b = self.plane.point_to_coords(p1)
|
||||||
|
c = int(np.sqrt(a**2 + b**2))
|
||||||
|
hyp_label = TexMobject(str(c))
|
||||||
|
hyp_label.add_background_rectangle()
|
||||||
|
hyp_label.next_to(
|
||||||
|
triangle.get_center(), UP+LEFT, buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
line.add(hyp_label)
|
||||||
|
|
||||||
|
dot_tuple_group.triangle = triangle
|
||||||
|
dot_tuple_group.line = line
|
||||||
|
|
||||||
|
group = dot_tuple_groups[0]
|
||||||
|
|
||||||
|
self.play(Write(group.line))
|
||||||
|
self.play(FadeIn(group.triangle), Animation(group.line))
|
||||||
|
self.dither(2)
|
||||||
|
for new_group in dot_tuple_groups[1:]:
|
||||||
|
self.play(
|
||||||
|
Transform(group, new_group),
|
||||||
|
Transform(group.triangle, new_group.triangle),
|
||||||
|
Transform(group.line, new_group.line),
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(*map(FadeOut, [group, group.triangle, group.line]))
|
||||||
|
|
||||||
|
def resize_plane(self):
|
||||||
|
new_plane = ComplexPlane(
|
||||||
|
plane_center = self.new_plane_center,
|
||||||
|
unit_size = self.new_unit_size,
|
||||||
|
y_radius = 8,
|
||||||
|
x_radius = 11,
|
||||||
|
stroke_width = 2,
|
||||||
|
secondary_line_ratio = 0,
|
||||||
|
)
|
||||||
|
new_plane.axes.set_stroke(width = 4)
|
||||||
|
self.plane.generate_target()
|
||||||
|
self.plane.target.unit_size = self.new_unit_size
|
||||||
|
self.plane.target.plane_center = self.new_plane_center
|
||||||
|
self.plane.target.shift(
|
||||||
|
new_plane.coords_to_point(0, 0) - \
|
||||||
|
self.plane.target.coords_to_point(0, 0)
|
||||||
|
)
|
||||||
|
self.plane.target.scale(
|
||||||
|
self.new_unit_size / self.initial_unit_size
|
||||||
|
)
|
||||||
|
coordinate_labels = self.plane.coordinate_labels
|
||||||
|
for coord in coordinate_labels:
|
||||||
|
x = int(coord.get_tex_string())
|
||||||
|
coord.generate_target()
|
||||||
|
coord.target.scale(1.5)
|
||||||
|
coord.target.next_to(
|
||||||
|
new_plane.coords_to_point(x, 0),
|
||||||
|
DOWN, buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
MoveToTarget(self.plane),
|
||||||
|
*map(MoveToTarget, self.plane.coordinate_labels),
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.remove(self.plane)
|
||||||
|
self.plane = new_plane
|
||||||
|
self.plane.coordinate_labels = coordinate_labels
|
||||||
|
self.add(self.plane, coordinate_labels)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
def show_root_example(self):
|
||||||
|
x, y = (2, 1)
|
||||||
|
point = self.plane.coords_to_point(x, y)
|
||||||
|
dot = Dot(
|
||||||
|
point,
|
||||||
|
color = self.dot_color,
|
||||||
|
radius = self.dot_radius
|
||||||
|
)
|
||||||
|
tuple_label = TexMobject(str((x, y)))
|
||||||
|
tuple_label.add_background_rectangle()
|
||||||
|
tuple_label.next_to(dot, RIGHT, SMALL_BUFF)
|
||||||
|
line = Line(self.plane.get_center_point(), point)
|
||||||
|
line.highlight(dot.get_color())
|
||||||
|
distance_labels = VGroup()
|
||||||
|
for tex in "2^2 + 1^2", "5":
|
||||||
|
pre_label = TexMobject("\\sqrt{%s}"%tex)
|
||||||
|
rect = BackgroundRectangle(pre_label)
|
||||||
|
label = VGroup(
|
||||||
|
rect,
|
||||||
|
VGroup(*pre_label[:2]),
|
||||||
|
VGroup(*pre_label[2:]),
|
||||||
|
)
|
||||||
|
label.scale(0.8)
|
||||||
|
label.next_to(line.get_center(), UP, SMALL_BUFF)
|
||||||
|
label.rotate(
|
||||||
|
line.get_angle(),
|
||||||
|
about_point = line.get_center()
|
||||||
|
)
|
||||||
|
distance_labels.add(label)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
ShowCreation(line),
|
||||||
|
DrawBorderThenFill(
|
||||||
|
dot,
|
||||||
|
stroke_width = 3,
|
||||||
|
stroke_color = PINK
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.play(Write(tuple_label))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeIn(distance_labels[0]))
|
||||||
|
self.dither(2)
|
||||||
|
self.play(Transform(*distance_labels))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
self.distance_label = distance_labels[0]
|
||||||
|
self.example_dot = dot
|
||||||
|
self.example_line = line
|
||||||
|
self.example_tuple_label = tuple_label
|
||||||
|
|
||||||
|
def view_as_complex_number(self):
|
||||||
|
imag_coords = VGroup()
|
||||||
|
for y in range(-4, 5, 2):
|
||||||
|
if y == 0:
|
||||||
|
continue
|
||||||
|
label = TexMobject("%di"%y)
|
||||||
|
label.add_background_rectangle()
|
||||||
|
label.scale(0.75)
|
||||||
|
label.next_to(
|
||||||
|
self.plane.coords_to_point(0, y),
|
||||||
|
LEFT, SMALL_BUFF
|
||||||
|
)
|
||||||
|
imag_coords.add(label)
|
||||||
|
tuple_label = self.example_tuple_label
|
||||||
|
new_label = TexMobject("2+i")
|
||||||
|
new_label.add_background_rectangle()
|
||||||
|
new_label.next_to(
|
||||||
|
self.example_dot,
|
||||||
|
DOWN+RIGHT, buff = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.play(Write(imag_coords))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(tuple_label))
|
||||||
|
self.play(FadeIn(new_label))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
self.example_label = new_label
|
||||||
|
self.plane.coordinate_labels.add(*imag_coords)
|
||||||
|
|
||||||
|
def mention_squaring_it(self):
|
||||||
|
morty = self.pi_creature
|
||||||
|
arrow = Arrow(
|
||||||
|
self.plane.coords_to_point(2, 1),
|
||||||
|
self.plane.coords_to_point(3, 4),
|
||||||
|
path_arc = np.pi/3,
|
||||||
|
color = MAROON_B
|
||||||
|
)
|
||||||
|
square_label = TexMobject("z \\to z^2")
|
||||||
|
square_label.highlight(arrow.get_color())
|
||||||
|
square_label.add_background_rectangle()
|
||||||
|
square_label.next_to(
|
||||||
|
arrow.point_from_proportion(0.5),
|
||||||
|
RIGHT, buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
|
||||||
|
self.play(FadeIn(morty))
|
||||||
|
self.play(
|
||||||
|
PiCreatureSays(
|
||||||
|
morty, "Try squaring \\\\ it!",
|
||||||
|
target_mode = "hooray",
|
||||||
|
bubble_kwargs = {"width" : 4, "height" : 3},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
ShowCreation(arrow),
|
||||||
|
Write(square_label)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(RemovePiCreatureBubble(
|
||||||
|
morty, target_mode = "pondering",
|
||||||
|
look_at_arg = self.example_label
|
||||||
|
))
|
||||||
|
|
||||||
|
def work_out_square_algebraically(self):
|
||||||
|
rect = Rectangle(
|
||||||
|
height = 3.5, width = 6.5,
|
||||||
|
stroke_width = 0,
|
||||||
|
fill_color = BLACK,
|
||||||
|
fill_opacity = 0.8
|
||||||
|
)
|
||||||
|
rect.to_corner(UP+LEFT, buff = 0)
|
||||||
|
top_line = TexMobject("(2+i)", "(2+i)")
|
||||||
|
top_line.next_to(rect.get_top(), DOWN)
|
||||||
|
second_line = TexMobject(
|
||||||
|
"2^2 + 2i + 2i + i^2"
|
||||||
|
)
|
||||||
|
second_line.next_to(top_line, DOWN, MED_LARGE_BUFF)
|
||||||
|
final_line = TexMobject("3 + 4i")
|
||||||
|
final_line.next_to(second_line, DOWN, MED_LARGE_BUFF)
|
||||||
|
|
||||||
|
result_dot = Dot(
|
||||||
|
self.plane.coords_to_point(3, 4),
|
||||||
|
color = MAROON_B,
|
||||||
|
radius = self.dot_radius
|
||||||
|
)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeIn(rect),
|
||||||
|
ReplacementTransform(
|
||||||
|
VGroup(self.example_label[1].copy()),
|
||||||
|
top_line
|
||||||
|
),
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#From top line to second line
|
||||||
|
index_alignment_lists = [
|
||||||
|
[(0, 1, 0), (1, 1, 1)],
|
||||||
|
[(0, 2, 2), (0, 1, 3), (1, 3, 4)],
|
||||||
|
[(0, 2, 5), (1, 1, 6), (0, 3, 7)],
|
||||||
|
[(0, 2, 8), (0, 3, 9), (1, 3, 10)],
|
||||||
|
]
|
||||||
|
for index_alignment in index_alignment_lists:
|
||||||
|
self.play(*[
|
||||||
|
ReplacementTransform(
|
||||||
|
top_line[i][j].copy(), second_line[k],
|
||||||
|
)
|
||||||
|
for i, j, k in index_alignment
|
||||||
|
])
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
#From second line to final line
|
||||||
|
index_alignment_lists = [
|
||||||
|
[(0, 0), (1, 0), (9, 0), (10, 0)],
|
||||||
|
[(2, 1), (3, 2), (4, 3), (6, 2), (7, 3)],
|
||||||
|
]
|
||||||
|
for index_alignment in index_alignment_lists:
|
||||||
|
self.play(*[
|
||||||
|
ReplacementTransform(
|
||||||
|
second_line[i].copy(), final_line[j],
|
||||||
|
run_time = 1.5
|
||||||
|
)
|
||||||
|
for i, j in index_alignment
|
||||||
|
])
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#Move result to appropriate place
|
||||||
|
result_label = final_line.copy()
|
||||||
|
result_label.add_background_rectangle()
|
||||||
|
self.play(
|
||||||
|
result_label.next_to, result_dot, UP+RIGHT, SMALL_BUFF,
|
||||||
|
Animation(final_line),
|
||||||
|
run_time = 2,
|
||||||
|
)
|
||||||
|
self.play(DrawBorderThenFill(
|
||||||
|
result_dot,
|
||||||
|
stroke_width = 4,
|
||||||
|
stroke_color = PINK
|
||||||
|
))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
def walk_through_square_geometrically(self):
|
||||||
|
line = self.example_line
|
||||||
|
dot = self.example_dot
|
||||||
|
example_label = self.example_label
|
||||||
|
distance_label = self.distance_label
|
||||||
|
|
||||||
|
alt_line = line.copy().highlight(RED)
|
||||||
|
arc = Arc(
|
||||||
|
angle = line.get_angle(),
|
||||||
|
radius = 0.7,
|
||||||
|
color = WHITE
|
||||||
|
)
|
||||||
|
double_arc = Arc(
|
||||||
|
angle = 2*line.get_angle(),
|
||||||
|
radius = 0.8,
|
||||||
|
color = RED,
|
||||||
|
)
|
||||||
|
theta = TexMobject("\\theta")
|
||||||
|
two_theta = TexMobject("2\\theta")
|
||||||
|
for tex_mob, arc_mob in (theta, arc), (two_theta, double_arc):
|
||||||
|
tex_mob.scale(0.75)
|
||||||
|
tex_mob.add_background_rectangle()
|
||||||
|
point = arc_mob.point_from_proportion(0.5)
|
||||||
|
tex_mob.move_to(point)
|
||||||
|
tex_mob.shift(tex_mob.get_width()*point/np.linalg.norm(point))
|
||||||
|
|
||||||
|
|
||||||
|
self.play(self.pi_creature.change, "happy", arc)
|
||||||
|
self.play(ShowCreation(alt_line))
|
||||||
|
self.play(ShowCreation(line))
|
||||||
|
self.remove(alt_line)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
ShowCreation(arc),
|
||||||
|
Write(theta)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(Indicate(distance_label))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#Multiply full plane under everything
|
||||||
|
everything = VGroup(*self.get_top_level_mobjects())
|
||||||
|
everything.remove(self.plane)
|
||||||
|
self.plane.save_state()
|
||||||
|
ghost_plane = self.plane.copy().fade()
|
||||||
|
method_args_list = [
|
||||||
|
(self.plane.rotate, (line.get_angle(),)),
|
||||||
|
(self.plane.scale, (np.sqrt(5),)),
|
||||||
|
(self.plane.restore, ()),
|
||||||
|
]
|
||||||
|
for method, args in method_args_list:
|
||||||
|
self.play(
|
||||||
|
Animation(ghost_plane),
|
||||||
|
ApplyMethod(method, *args),
|
||||||
|
Animation(everything),
|
||||||
|
run_time = 1.5
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#Multiply number by itself
|
||||||
|
ghost_arc = arc.copy().fade()
|
||||||
|
ghost_line = line.copy().fade()
|
||||||
|
ghots_dot = dot.copy().fade()
|
||||||
|
self.add(ghost_arc, ghost_line, ghots_dot)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
VGroup(
|
||||||
|
line, dot, distance_label,
|
||||||
|
).rotate, line.get_angle(),
|
||||||
|
Transform(arc, double_arc),
|
||||||
|
Transform(theta, two_theta),
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
five = distance_label[2]
|
||||||
|
distance_label.remove(five)
|
||||||
|
for mob in five, line, dot:
|
||||||
|
mob.generate_target()
|
||||||
|
line.target.scale(np.sqrt(5))
|
||||||
|
five.target.shift(line.target.get_center()-line.get_center())
|
||||||
|
dot.target.move_to(line.target.get_end())
|
||||||
|
self.play(
|
||||||
|
FadeOut(distance_label),
|
||||||
|
*map(MoveToTarget, [five, line, dot]),
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
def get_all_plane_dots(self):
|
||||||
|
x_min, y_min = map(int, self.plane.point_to_coords(
|
||||||
|
SPACE_WIDTH*LEFT + SPACE_HEIGHT*DOWN
|
||||||
|
))
|
||||||
|
x_max, y_max = map(int, self.plane.point_to_coords(
|
||||||
|
SPACE_WIDTH*RIGHT + SPACE_HEIGHT*UP
|
||||||
|
))
|
||||||
|
result = VGroup(*[
|
||||||
|
Dot(
|
||||||
|
self.plane.coords_to_point(x, y),
|
||||||
|
radius = self.dot_radius,
|
||||||
|
color = self.dot_color,
|
||||||
|
)
|
||||||
|
for x in range(int(x_min), int(x_max)+1)
|
||||||
|
for y in range(int(y_min), int(y_max)+1)
|
||||||
|
])
|
||||||
|
result.sort_submobjects(lambda p : np.dot(p, UP+RIGHT))
|
||||||
|
return result
|
||||||
|
|
||||||
|
def create_pi_creature(self):
|
||||||
|
morty = Mortimer().flip()
|
||||||
|
morty.to_corner(DOWN+LEFT, buff = MED_SMALL_BUFF)
|
||||||
|
return morty
|
||||||
|
|
||||||
|
class OneMoreExample(Scene):
|
||||||
|
CONFIG = {
|
||||||
|
"unit_size" : 0.5,
|
||||||
|
"plane_center" : 3*LEFT + 3*DOWN,
|
||||||
|
"dot_color" : YELLOW,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.force_skipping()
|
||||||
|
|
||||||
|
self.add_plane()
|
||||||
|
self.add_point()
|
||||||
|
self.square_algebraically()
|
||||||
|
self.plot_result()
|
||||||
|
self.show_triangle()
|
||||||
|
|
||||||
|
def add_plane(self):
|
||||||
|
plane = ComplexPlane(
|
||||||
|
unit_size = self.unit_size,
|
||||||
|
center_point = self.plane_center,
|
||||||
|
stroke_width = 2,
|
||||||
|
)
|
||||||
|
plane.axes.set_stroke(width = 4)
|
||||||
|
coordinate_labels = VGroup()
|
||||||
|
for x in range(-6, 25, 3):
|
||||||
|
if x == 0:
|
||||||
|
continue
|
||||||
|
coord = TexMobject(str(x))
|
||||||
|
coord.scale(0.75)
|
||||||
|
coord.next_to(plane.coords_to_point(x, 0), DOWN, SMALL_BUFF)
|
||||||
|
coord.add_background_rectangle()
|
||||||
|
coordinate_labels.add(coord)
|
||||||
|
for y in range(3, 13, 3):
|
||||||
|
if y == 0:
|
||||||
|
continue
|
||||||
|
coord = TexMobject("%di"%y)
|
||||||
|
coord.scale(0.75)
|
||||||
|
coord.next_to(plane.coords_to_point(0, y), LEFT, SMALL_BUFF)
|
||||||
|
coord.add_background_rectangle()
|
||||||
|
coordinate_labels.add(coord)
|
||||||
|
self.add(plane, coordinate_labels)
|
||||||
|
|
||||||
|
self.plane = plane
|
||||||
|
self.plane.coordinate_labels = coordinate_labels
|
||||||
|
|
||||||
|
def add_point(self):
|
||||||
|
point = self.plane.coords_to_point(3, 2)
|
||||||
|
dot = Dot(point, color = self.dot_color)
|
||||||
|
line = Line(self.plane.get_center_point(), point)
|
||||||
|
line.highlight(dot.get_color())
|
||||||
|
tuple_label = TexMobject("3+2i")
|
||||||
|
tuple_label.add_background_rectangle()
|
||||||
|
tuple_label.next_to(dot, RIGHT, SMALL_BUFF)
|
||||||
|
distance_labels = VGroup()
|
||||||
|
for tex in "3^2 + 2^2", "13":
|
||||||
|
pre_label = TexMobject("\\sqrt{%s}"%tex)
|
||||||
|
label = VGroup(
|
||||||
|
BackgroundRectangle(pre_label),
|
||||||
|
VGroup(*pre_label[:2]),
|
||||||
|
VGroup(*pre_label[2:]),
|
||||||
|
)
|
||||||
|
label.scale(0.75)
|
||||||
|
label.next_to(line.get_center(), UP, SMALL_BUFF)
|
||||||
|
label.rotate(
|
||||||
|
line.get_angle(),
|
||||||
|
about_point = line.get_center()
|
||||||
|
)
|
||||||
|
distance_labels.add(label)
|
||||||
|
|
||||||
|
self.revert_to_original_skipping_status()
|
||||||
|
self.play(
|
||||||
|
FadeIn(tuple_label),
|
||||||
|
ShowCreation(line),
|
||||||
|
DrawBorderThenFill(dot)
|
||||||
|
)
|
||||||
|
self.play(Write(distance_labels[0]))
|
||||||
|
self.dither()
|
||||||
|
self.play(ReplacementTransform(*distance_labels))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
self.distance_label = distance_labels[1]
|
||||||
|
self.line = line
|
||||||
|
self.dot = dot
|
||||||
|
self.tuple_label = tuple_label
|
||||||
|
|
||||||
|
def square_algebraically(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def plot_result(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def show_triangle(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue