Work in progress on building up WindingNumber animations

This commit is contained in:
Sridhar Ramesh
2018-01-10 17:58:20 -08:00
parent 0ce1a528c6
commit c1f25338ee

View File

@ -29,64 +29,40 @@ from mobject.svg_mobject import *
from mobject.tex_mobject import * from mobject.tex_mobject import *
from topics.graph_scene import * from topics.graph_scene import *
class Test(Scene): class EquationSolver1d(GraphScene, ZoomedScene, ReconfigurableScene):
def construct(self):
firstname = TextMobject("Sridhar")
lastname = TextMobject("Ramesh")
texObject1 = TexMobject(r"\sum_{x = 0}^{n} \frac{1}{x^2}")
texObject2 = TexMobject(r"\int_{x = 0}^{n} \frac{1}{x^2}")
squareObject = Square(side_length = 2)
squareGroup = Group(*[Square(side_length = x) for x in range(3)])
squareGroup.arrange_submobjects(RIGHT)
#self.play(ReplacementTransform(texObject1, texObject2), run_time = 5)
#self.play(texObject2.shift, 2*RIGHT)
#self.play(Write(firstname))
#self.play(Write(squareGroup))
polygonObject = Polygon(ORIGIN, UP + RIGHT, UP + LEFT)
polygonObject.set_stroke(color = YELLOW, width = 3)
polygonObject.set_fill(color = WHITE, opacity = 0.5)
self.play(DrawBorderThenFill(polygonObject), run_time = 5)
class GraphTest(GraphScene, ZoomedScene):
CONFIG = { CONFIG = {
"x_min" : 0, "graph_func" : lambda x : x,
"x_max" : 6, "targetX" : 0,
"y_min" : -1, "targetY" : 0,
"y_max" : 20, "initial_lower_x" : 0,
"graph_origin" : 2*DOWN + 5 * LEFT, "initial_upper_x" : 10,
"x_axis_width" : 12, "num_iterations" : 10,
"zoom_factor" : 3, "iteration_at_which_to_start_zoom" : None,
"zoomed_canvas_center" : 2 * UP + 1.5 * LEFT "graph_label" : None,
"show_target_line" : True
} }
def construct(self):
# Convenient for skipping animations:
# self.force_skipping()
# self.revert_to_original_skipping_status()
def drawGraph(self):
self.setup_axes() self.setup_axes()
graphFunc = lambda x : x**2 self.graph = self.get_graph(self.graph_func)
graph = self.get_graph(graphFunc) self.add(self.graph)
self.add(graph)
inverseZoomFactor = 1/float(self.zoom_factor) if self.graph_label != None:
self.add(self.get_graph_label(self.graph, self.graph_label,
x_val = 4, direction = RIGHT))
graphLabel = self.get_graph_label(graph, "y = x^2", if self.show_target_line:
x_val = 4, direction = RIGHT) target_line_object = DashedLine(
self.add(graphLabel) self.coords_to_point(self.x_min, self.targetY),
self.coords_to_point(self.x_max, self.targetY),
targetY = 6
targetYLine = DashedLine(
self.coords_to_point(self.x_min, targetY),
self.coords_to_point(self.x_max, targetY),
dashed_segment_length = 0.1) dashed_segment_length = 0.1)
self.add(targetYLine) self.add(target_line_object)
targetYLineLabel = TexMobject("y = " + str(targetY)) target_line_label = TexMobject("y = " + str(self.targetY))
targetYLineLabel.next_to(targetYLine.get_left(), UP + RIGHT) target_line_label.next_to(target_line_object.get_left(), UP + RIGHT)
self.add(targetYLineLabel) self.add(target_line_label)
def solveEquation(self):
leftBrace, rightBrace = xBraces = TexMobject("||") leftBrace, rightBrace = xBraces = TexMobject("||")
xBraces.stretch(2, 0) xBraces.stretch(2, 0)
@ -94,10 +70,10 @@ class GraphTest(GraphScene, ZoomedScene):
yBraces.stretch(2, 0) yBraces.stretch(2, 0)
yBraces.rotate(np.pi/2) yBraces.rotate(np.pi/2)
lowerX = 1 lowerX = self.initial_lower_x
lowerY = graphFunc(lowerX) lowerY = self.graph_func(lowerX)
upperX = 5 upperX = self.initial_upper_x
upperY = graphFunc(upperX) upperY = self.graph_func(upperX)
leftBrace.move_to(self.coords_to_point(lowerX, 0)) leftBrace.move_to(self.coords_to_point(lowerX, 0))
leftBraceLabel = DecimalNumber(lowerX) leftBraceLabel = DecimalNumber(lowerX)
@ -131,14 +107,14 @@ class GraphTest(GraphScene, ZoomedScene):
tracked_mobject = upBrace) tracked_mobject = upBrace)
self.add(upBraceLabelAnimation) self.add(upBraceLabelAnimation)
lowerDotPoint = self.input_to_graph_point(lowerX, graph) lowerDotPoint = self.input_to_graph_point(lowerX, self.graph)
lowerDotXPoint = self.coords_to_point(lowerX, 0) lowerDotXPoint = self.coords_to_point(lowerX, 0)
lowerDotYPoint = self.coords_to_point(0, graphFunc(lowerX)) lowerDotYPoint = self.coords_to_point(0, self.graph_func(lowerX))
lowerDot = Dot(lowerDotPoint) lowerDot = Dot(lowerDotPoint)
upperDotPoint = self.input_to_graph_point(upperX, graph) upperDotPoint = self.input_to_graph_point(upperX, self.graph)
upperDot = Dot(upperDotPoint) upperDot = Dot(upperDotPoint)
upperDotXPoint = self.coords_to_point(upperX, 0) upperDotXPoint = self.coords_to_point(upperX, 0)
upperDotYPoint = self.coords_to_point(0, graphFunc(upperX)) upperDotYPoint = self.coords_to_point(0, self.graph_func(upperX))
lowerXLine = Line(lowerDotXPoint, lowerDotPoint, stroke_width = 1, color = YELLOW) lowerXLine = Line(lowerDotXPoint, lowerDotPoint, stroke_width = 1, color = YELLOW)
upperXLine = Line(upperDotXPoint, upperDotPoint, stroke_width = 1, color = YELLOW) upperXLine = Line(upperDotXPoint, upperDotPoint, stroke_width = 1, color = YELLOW)
@ -146,16 +122,14 @@ class GraphTest(GraphScene, ZoomedScene):
upperYLine = Line(upperDotYPoint, upperDotPoint, stroke_width = 1, color = YELLOW) upperYLine = Line(upperDotYPoint, upperDotPoint, stroke_width = 1, color = YELLOW)
self.add(lowerXLine, upperXLine, lowerYLine, upperYLine) self.add(lowerXLine, upperXLine, lowerYLine, upperYLine)
# TODO: Display lines at start, not just on update
self.add(xBraces, yBraces, lowerDot, upperDot) self.add(xBraces, yBraces, lowerDot, upperDot)
zoomStage = 5 for i in range(self.num_iterations):
for i in range(10): if i == self.iteration_at_which_to_start_zoom:
if i == zoomStage:
self.activate_zooming() self.activate_zooming()
self.little_rectangle.move_to( self.little_rectangle.move_to(
self.coords_to_point(np.sqrt(targetY), targetY)) self.coords_to_point(self.targetX, self.targetY))
inverseZoomFactor = 1/float(self.zoom_factor)
self.play( self.play(
lowerDot.scale_in_place, inverseZoomFactor, lowerDot.scale_in_place, inverseZoomFactor,
upperDot.scale_in_place, inverseZoomFactor) upperDot.scale_in_place, inverseZoomFactor)
@ -165,9 +139,9 @@ class GraphTest(GraphScene, ZoomedScene):
def updater(group, alpha): def updater(group, alpha):
dot, xBrace, yBrace, xLine, yLine = group dot, xBrace, yBrace, xLine, yLine = group
newX = interpolate(xAtStart, midX, alpha) newX = interpolate(xAtStart, midX, alpha)
newY = graphFunc(newX) newY = self.graph_func(newX)
graphPoint = self.input_to_graph_point(newX, graphPoint = self.input_to_graph_point(newX,
graph) self.graph)
dot.move_to(graphPoint) dot.move_to(graphPoint)
xAxisPoint = self.coords_to_point(newX, 0) xAxisPoint = self.coords_to_point(newX, 0)
xBrace.move_to(xAxisPoint) xBrace.move_to(xAxisPoint)
@ -179,7 +153,7 @@ class GraphTest(GraphScene, ZoomedScene):
return updater return updater
midX = (lowerX + upperX)/float(2) midX = (lowerX + upperX)/float(2)
midY = graphFunc(midX) midY = self.graph_func(midX)
midCoords = self.coords_to_point(midX, midY) midCoords = self.coords_to_point(midX, midY)
midColor = RED midColor = RED
@ -190,13 +164,14 @@ class GraphTest(GraphScene, ZoomedScene):
midXLine = Line(self.coords_to_point(midX, 0), midCoords, color = midColor) midXLine = Line(self.coords_to_point(midX, 0), midCoords, color = midColor)
self.play(ShowCreation(midXLine)) self.play(ShowCreation(midXLine))
midDot = Dot(midCoords, color = midColor) midDot = Dot(midCoords, color = midColor)
if(i >= zoomStage): if(self.iteration_at_which_to_start_zoom != None and
i >= self.iteration_at_which_to_start_zoom):
midDot.scale_in_place(inverseZoomFactor) midDot.scale_in_place(inverseZoomFactor)
self.add(midDot) self.add(midDot)
midYLine = Line(midCoords, self.coords_to_point(0, midY), color = midColor) midYLine = Line(midCoords, self.coords_to_point(0, midY), color = midColor)
self.play(ShowCreation(midYLine)) self.play(ShowCreation(midYLine))
if midY < targetY: if midY < self.targetY:
movingGroup = Group(lowerDot, movingGroup = Group(lowerDot,
leftBrace, downBrace, leftBrace, downBrace,
lowerXLine, lowerYLine) lowerXLine, lowerYLine)
@ -216,3 +191,134 @@ class GraphTest(GraphScene, ZoomedScene):
self.remove(midXLine, midDot, midYLine) self.remove(midXLine, midDot, midYLine)
self.dither() self.dither()
def construct(self):
self.drawGraph()
self.solveEquation()
class FirstSqrtScene(EquationSolver1d):
CONFIG = {
"x_min" : 0,
"x_max" : 2,
"y_min" : 0,
"y_max" : 4,
"graph_origin" : 2*DOWN + 5 * LEFT,
"x_axis_width" : 12,
"zoom_factor" : 3,
"zoomed_canvas_center" : 2.25 * UP + 1.75 * LEFT,
"graph_func" : lambda x : x**2,
"targetX" : np.sqrt(2),
"targetY" : 2,
"initial_lower_x" : 1,
"initial_upper_x" : 2,
"num_iterations" : 2,
"iteration_at_which_to_start_zoom" : 1,
"graph_label" : "y = x^2",
"show_target_line" : True,
}
class SecondSqrtScene(FirstSqrtScene, ReconfigurableScene):
def setup(self):
FirstSqrtScene.setup(self)
ReconfigurableScene.setup(self)
def construct(self):
shiftVal = self.targetY
self.drawGraph()
newOrigin = self.coords_to_point(0, shiftVal)
self.transition_to_alt_config(
graph_func = lambda x : x**2 - shiftVal,
targetY = 0,
graph_label = "y = x^2 - " + str(shiftVal),
y_min = self.y_min - shiftVal,
y_max = self.y_max - shiftVal,
show_target_line = False,
graph_origin = newOrigin)
self.solveEquation()
class LoopSplitScene(Scene):
def construct(self):
# Original loop
tl = UP + LEFT
tm = UP
tr = UP + RIGHT
mr = RIGHT
br = DOWN + RIGHT
bm = DOWN
bl = DOWN + LEFT
lm = LEFT
loop_color = BLUE
top_line = Line(tl, tr, color = loop_color)
right_line = Line(tr, br, color = loop_color)
bottom_line = Line(br, bl, color = loop_color)
left_line = Line(bl, tl, color = loop_color)
loop = Group(top_line, right_line, bottom_line, left_line)
self.add(loop)
# TODO: Make the following a continual animation, and on all split loops do the same
bullet = TexMobject("*", fill_color = RED)
bullet.move_to(tl)
self.add(bullet)
list_of_args = reduce(op.add,
[
[ApplyMethod, bullet.move_to, point, {"rate_func" : None}] for
point in [tr, br, bl, tl]
]
)
succ_anim = Succession(*list_of_args)
self.add(CycleAnimation(succ_anim))
# Splits in middle
split_line = DashedLine(interpolate(tl, tr, 0.5), interpolate(bl, br, 0.5))
self.play(ShowCreation(split_line))
self.remove(split_line)
mid_line_left = Line(tm, bm, color = loop_color)
mid_line_right = Line(tm, bm, color = loop_color)
self.add(mid_line_left, mid_line_right)
top_line_left_half = Line(tl, tm, color = loop_color)
top_line_right_half = Line(tm, tr, color = loop_color)
bottom_line_left_half = Line(bl, bm, color = loop_color)
bottom_line_right_half = Line(bm, br, color = loop_color)
self.remove(top_line)
self.add(top_line_left_half)
self.add(top_line_right_half)
self.remove(bottom_line)
self.add(bottom_line_left_half)
self.add(bottom_line_right_half)
left_open_loop = VGroup(top_line_left_half, left_line, bottom_line_left_half)
left_closed_loop = VGroup(left_open_loop, mid_line_left)
right_open_loop = VGroup(top_line_right_half, right_line, bottom_line_right_half)
right_closed_loop = VGroup(right_open_loop, mid_line_right)
self.play(
ApplyMethod(left_closed_loop.shift, LEFT),
ApplyMethod(right_closed_loop.shift, RIGHT)
)
self.dither()
self.play(
ApplyMethod(left_open_loop.shift, LEFT),
ApplyMethod(right_open_loop.shift, RIGHT)
)
self.dither()
mid_lines = VGroup(mid_line_left, mid_line_right)
circle = Circle()
circle.surround(mid_lines)
self.play(ShowCreation(circle))
class EquationSolver2d(ZoomedScene):
#TODO
CONFIG = {}