FromGeometryToAlgebra

This commit is contained in:
Grant Sanderson 2018-04-10 19:47:58 -07:00
parent 8589515e82
commit 4ae12a6856

View file

@ -7,7 +7,7 @@ from once_useful_constructs.light import SwitchOn
PRODUCT_COLOR = BLUE
CHEAP_AMBIENT_LIGHT_CONFIG = {
"num_levels": 5,
"radius": 1,
"radius": 0.5,
}
@ -608,30 +608,415 @@ class Lemma2With9Lighthouses(Lemma2):
class FromGeometryToAlgebra(DistanceProductScene):
CONFIG = {
"num_lighthouses": 7,
"ambient_light_config": CHEAP_AMBIENT_LIGHT_CONFIG,
# "ambient_light_config": CHEAP_AMBIENT_LIGHT_CONFIG,
}
def construct(self):
self.setup_lights()
self.point_out_evenly_spaced()
self.transition_to_complex_plane()
self.name_roots_of_unity()
self.discuss_powers()
self.raise_everything_to_the_nth()
def setup_lights(self):
lights = self.get_lights()
circle = self.circle
circle.scale_to_fit_height(5, about_edge=DOWN)
lights = self.get_lights()
dots = VGroup(*[Dot(point) for point in self.get_lh_points()])
for dot, light in zip(dots, lights):
light.add_to_back(dot)
self.add(circle, lights)
def point_out_evenly_spaced(self):
pass
circle = self.circle
step = 1.0 / self.num_lighthouses / 2
alpha_range = np.arange(0, 1 + step, step)
arcs = VGroup(*[
VMobject().pointwise_become_partial(circle, a1, a2)
for a1, a2 in zip(alpha_range, alpha_range[1:])
])
arcs.set_stroke(YELLOW, 5)
for arc in arcs[::2]:
arc.reverse_points()
arcs_anim = ShowCreationThenDestruction(
arcs, submobject_mode="all_at_once", run_time=2
)
spacing_words = self.spacing_words = TextMobject("Evenly-spaced")
spacing_words.scale_to_fit_width(self.get_radius())
spacing_words.move_to(circle)
arrows = self.get_arrows()
geometric_words = self.geometric_words = TextMobject("Geometric property")
geometric_words.to_edge(UP)
geometric_words.add_background_rectangle()
self.add(geometric_words)
self.play(
FadeIn(spacing_words),
arcs_anim,
*map(GrowArrow, arrows)
)
self.play(FadeOut(arrows), arcs_anim)
self.wait()
def transition_to_complex_plane(self):
pass
def name_roots_of_unity(self):
pass
plane = self.complex_plane = ComplexPlane(
unit_size=2, y_radius=6, x_radius=9,
)
plane.shift(1.5 * RIGHT)
plane.add_coordinates()
origin = plane.number_to_point(0)
h_line = Line(plane.number_to_point(-1), plane.number_to_point(1))
circle = self.circle
circle_group = VGroup(circle, self.lights)
circle_group.generate_target()
circle_group.target.scale(h_line.get_width() / circle.get_width())
circle_group.target.shift(
origin - circle_group.target[0].get_center()
)
circle_group.target[0].set_stroke(RED)
geometric_words = self.geometric_words
geometric_words.generate_target()
arrow = TexMobject("\\rightarrow")
arrow.add_background_rectangle()
algebraic_words = TextMobject("Algebraic property")
algebraic_words.add_background_rectangle()
word_group = VGroup(geometric_words.target, arrow, algebraic_words)
word_group.arrange_submobjects(RIGHT)
word_group.move_to(origin)
word_group.to_edge(UP)
unit_circle_words = TextMobject("Unit circle", "")
unit_circle_words.match_color(circle_group.target[0])
for part in unit_circle_words:
part.add_background_rectangle()
unit_circle_words.next_to(origin, UP)
complex_plane_words = TextMobject("Complex Plane")
self.complex_plane_words = complex_plane_words
complex_plane_words.move_to(word_group)
complex_plane_words.add_background_rectangle()
roots_of_unity_words = TextMobject("Roots of\\\\", "unity")
roots_of_unity_words.move_to(origin)
roots_of_unity_words.set_color(YELLOW)
for part in roots_of_unity_words:
part.add_background_rectangle()
self.play(
Write(plane),
MoveToTarget(circle_group),
FadeOut(self.spacing_words),
MoveToTarget(geometric_words),
FadeIn(arrow),
FadeIn(algebraic_words),
)
word_group.submobjects[0] = geometric_words
self.play(Write(unit_circle_words, run_time=1))
# Show complex values
outer_arrows = self.outer_arrows = self.get_arrows()
for arrow, point in zip(outer_arrows, self.get_lh_points()):
arrow.rotate(np.pi, about_point=point)
outer_arrow = self.outer_arrow = outer_arrows[3].copy()
values = map(plane.point_to_number, self.get_lh_points())
complex_decimal = self.complex_decimal = DecimalNumber(
values[3],
num_decimal_points=3,
include_background_rectangle=True
)
complex_decimal.next_to(outer_arrow.get_start(), LEFT, SMALL_BUFF)
complex_decimal_rect = SurroundingRectangle(complex_decimal)
complex_decimal_rect.fade(1)
self.play(
FadeIn(complex_plane_words),
FadeOut(word_group),
FadeIn(complex_decimal),
FadeIn(outer_arrow)
)
self.wait(2)
self.play(
ChangeDecimalToValue(
complex_decimal, values[1],
tracked_mobject=complex_decimal_rect
),
complex_decimal_rect.next_to, outer_arrows[1].get_start(), UP, SMALL_BUFF,
Transform(outer_arrow, outer_arrows[1]),
run_time=1.5
)
self.wait()
arrows = self.get_arrows()
arrows.set_color(YELLOW)
self.play(
ReplacementTransform(unit_circle_words, roots_of_unity_words),
LaggedStart(GrowArrow, arrows)
)
self.wait()
self.play(
complex_plane_words.move_to, word_group,
LaggedStart(FadeOut, VGroup(*it.chain(
arrows, roots_of_unity_words
)))
)
# Turn decimal into z
x_term = self.x_term = TexMobject("x")
x_term.add_background_rectangle()
x_term.move_to(complex_decimal, DOWN)
x_term.shift(0.5 * SMALL_BUFF * (DR))
self.play(ReplacementTransform(complex_decimal, x_term))
def discuss_powers(self):
x_term = self.x_term
outer_arrows = self.outer_arrows
outer_arrows.add(outer_arrows[0].copy())
plane = self.complex_plane
origin = plane.number_to_point(0)
question = TextMobject("What is $x^2$")
question.next_to(x_term, RIGHT, LARGE_BUFF)
question.set_color(YELLOW)
lh_points = list(self.get_lh_points())
lh_points.append(lh_points[0])
lines = VGroup(*[
Line(origin, point)
for point in lh_points
])
lines.set_color(GREEN)
step = 1.0 / self.num_lighthouses
angle_arcs = VGroup(*[
Arc(angle=alpha * TAU, radius=0.35).shift(origin)
for alpha in np.arange(0, 1 + step, step)
])
angle_labels = VGroup()
for i, arc in enumerate(angle_arcs):
label = TexMobject("(%d / %d)\\tau" % (i, self.num_lighthouses))
label.scale(0.5)
label.add_background_rectangle()
point = arc.point_from_proportion(0.5)
point += 1.2 * (point - origin)
label.move_to(point)
angle_labels.add(label)
line = self.angle_line = lines[1].copy()
line_ghost = DashedLine(line.get_start(), line.get_end())
self.ghost_angle_line = line_ghost
line_ghost.set_stroke(line.get_color(), 2)
angle_arc = angle_arcs[1].copy()
angle_label = angle_labels[1].copy()
angle_label.shift(0.25 * SMALL_BUFF * DR)
magnitude_label = TexMobject("1")
magnitude_label.next_to(line.get_center(), UL, buff=SMALL_BUFF)
power_labels = VGroup()
for i, arrow in enumerate(outer_arrows):
label = TexMobject("x^%d" % i)
label.next_to(
arrow.get_start(), -arrow.get_vector(),
submobject_to_align=label[0]
)
label.add_background_rectangle()
power_labels.add(label)
power_labels[-1].next_to(outer_arrows[-1].get_start(), UR, SMALL_BUFF)
power_labels.submobjects[1] = x_term
L_labels = self.L_labels = VGroup(*[
TexMobject("L_%d" % i).move_to(power_label, DOWN).add_background_rectangle()
for i, power_label in enumerate(power_labels)
])
# Ask about squaring
self.play(Write(question))
self.wait()
self.play(
ShowCreation(line),
Write(magnitude_label)
)
self.wait()
self.play(
ShowCreation(angle_arc),
Write(angle_label)
)
self.wait()
self.add(line_ghost)
for i in range(2, self.num_lighthouses + 1):
anims = [
Transform(angle_arc, angle_arcs[i]),
Transform(angle_label, angle_labels[i]),
Transform(line, lines[i], path_arc=TAU / self.num_lighthouses),
]
if i == 2:
anims.append(FadeOut(magnitude_label))
if i == 3:
anims.append(FadeOut(question))
self.play(*anims)
new_anims = [
GrowArrow(outer_arrows[i]),
Write(power_labels[i]),
]
if i == 2:
new_anims.append(FadeOut(self.complex_plane_words))
self.play(*new_anims)
self.wait()
self.play(ReplacementTransform(power_labels[1:], L_labels[1:]))
self.wait()
self.play(
Rotate(self.lights, TAU / self.num_lighthouses / 2),
rate_func=wiggle
)
self.wait()
self.play(
FadeOut(angle_arc),
FadeOut(angle_label),
*map(ShowCreationThenDestruction, lines)
)
self.wait()
def raise_everything_to_the_nth(self):
func_label = TexMobject("L \\rightarrow L^7")
func_label.set_color(YELLOW)
func_label.to_corner(UL, buff=LARGE_BUFF)
func_label.add_background_rectangle()
polynomial_scale_factor = 0.8
polynomial = TexMobject("x^%d - 1" % self.num_lighthouses, "=", "0")
polynomial.scale(polynomial_scale_factor)
polynomial.next_to(func_label, UP)
polynomial.to_edge(LEFT)
factored_polynomial = TexMobject(
"(x-L_1)(x-L_2)\\cdots(x-L_%d)" % self.num_lighthouses, "=", "0"
)
factored_polynomial.scale(polynomial_scale_factor)
factored_polynomial.next_to(polynomial, DOWN, aligned_edge=LEFT)
for group in polynomial, factored_polynomial:
for part in group:
part.add_background_rectangle()
origin = self.complex_plane.number_to_point(0)
lights = self.lights
lights.save_state()
rotations = []
for i, light in enumerate(lights):
rotations.append(Rotating(
light,
radians=(i * TAU - i * TAU / self.num_lighthouses),
about_point=origin,
rate_func=bezier([0, 0, 1, 1]),
))
self.play(Write(func_label, run_time=1))
for i, rotation in enumerate(rotations[:4]):
anims = [rotation]
if i == 3:
rect = SurroundingRectangle(polynomial)
rect.set_color(YELLOW)
anims += [
FadeIn(polynomial),
ShowCreationThenDestruction(rect)
]
self.play(*anims, run_time=np.sqrt(i + 1))
self.play(*rotations[4:], run_time=3)
self.wait()
self.play(lights.restore)
self.play(
FadeOut(func_label),
FadeIn(factored_polynomial)
)
self.wait(3)
self.play(
factored_polynomial[0].next_to, polynomial[1], RIGHT, 1.5 * SMALL_BUFF,
FadeOut(polynomial[2]),
FadeOut(factored_polynomial[1:]),
)
# Comment on formula
formula = VGroup(polynomial[0], polynomial[1], factored_polynomial[0])
rect = SurroundingRectangle(formula)
brace = Brace(factored_polynomial[0], DOWN)
brace2 = Brace(polynomial[0], DOWN)
morty = PiCreature(color=GREY_BROWN)
morty.scale(0.5)
morty.next_to(brace.get_center(), DL, buff=LARGE_BUFF)
L1_rhs = TexMobject("= \\cos(\\tau / 7) + \\\\", "\\sin(\\tau / 7)i")
L1_rhs.next_to(self.L_labels[1], RIGHT, aligned_edge=UP)
for part in L1_rhs:
part.add_background_rectangle()
self.play(ShowCreation(rect))
self.play(FadeOut(rect))
self.wait()
self.play(GrowFromCenter(brace))
self.play(FadeIn(morty))
self.play(morty.change, "horrified", brace)
self.play(Blink(morty))
self.wait()
self.play(
Write(L1_rhs),
morty.change, "confused", L1_rhs
)
self.play(Blink(morty))
self.wait()
self.play(
Transform(brace, brace2),
morty.change, "hooray", brace2
)
self.play(Blink(morty))
self.wait()
# Nothing special about 7
new_lights = self.lights.copy()
new_lights.rotate(
TAU / self.num_lighthouses / 2,
about_point=origin
)
sevens = VGroup(polynomial[0][1][1], factored_polynomial[0][1][-2])
n_terms = VGroup()
for seven in sevens:
n_term = TexMobject("N")
n_term.replace(seven, dim_to_match=1)
n_term.scale(0.9)
n_term.shift(0.25 * SMALL_BUFF * DR)
n_terms.add(n_term)
self.play(LaggedStart(FadeOut, VGroup(*it.chain(
L1_rhs, self.outer_arrows, self.L_labels[1:], self.outer_arrow,
self.angle_line, self.ghost_angle_line
))))
self.play(LaggedStart(SwitchOn, new_lights), morty.look_at, new_lights)
self.play(Transform(sevens, n_terms))
self.wait()
self.play(Blink(morty))
self.wait()
#
def get_arrows(self):
return VGroup(*[
Arrow(
interpolate(self.circle.get_center(), point, 0.6),
interpolate(self.circle.get_center(), point, 0.9),
buff=0
)
for point in self.get_lh_points()
])