def solve_energy(self): loss_in_potential = TextMobject("Loss in potential: ") loss_in_potential.shift(2 * UP) potential = TexMobject("m g y".split()) potential.next_to(loss_in_potential) kinetic = TexMobject(["\\dfrac{1}{2}", "m", "v", "^2", "="]) kinetic.next_to(potential, LEFT) nudge = 0.1 * UP kinetic.shift(nudge) loss_in_potential.shift(nudge) ms = Mobject(kinetic.split()[1], potential.split()[0]) two = TexMobject("2") two.shift(ms.split()[1].get_center()) half = kinetic.split()[0] sqrt = TexMobject("\\sqrt{\\phantom{2mg}}") sqrt.shift(potential.get_center()) nudge = 0.2 * LEFT sqrt.shift(nudge) squared = kinetic.split()[3] equals = kinetic.split()[-1] new_eq = equals.copy().next_to(kinetic.split()[2]) self.play( Transform(Point(loss_in_potential.get_left()), loss_in_potential), *map(GrowFromCenter, potential.split())) self.dither(2) self.play(FadeOut(loss_in_potential), GrowFromCenter(kinetic)) self.dither(2) self.play(ApplyMethod(ms.shift, 5 * UP)) self.dither() self.play(Transform(half, two, path_func=counterclockwise_path())) self.dither() self.play(Transform(squared, sqrt, path_func=clockwise_path()), Transform(equals, new_eq)) self.dither(2)
def solve_energy(self): loss_in_potential = TextMobject("Loss in potential: ") loss_in_potential.shift(2*UP) potential = TexMobject("m g y".split()) potential.next_to(loss_in_potential) kinetic = TexMobject([ "\\dfrac{1}{2}","m","v","^2","=" ]) kinetic.next_to(potential, LEFT) nudge = 0.1*UP kinetic.shift(nudge) loss_in_potential.shift(nudge) ms = Mobject(kinetic.split()[1], potential.split()[0]) two = TexMobject("2") two.shift(ms.split()[1].get_center()) half = kinetic.split()[0] sqrt = TexMobject("\\sqrt{\\phantom{2mg}}") sqrt.shift(potential.get_center()) nudge = 0.2*LEFT sqrt.shift(nudge) squared = kinetic.split()[3] equals = kinetic.split()[-1] new_eq = equals.copy().next_to(kinetic.split()[2]) self.play( Transform( Point(loss_in_potential.get_left()), loss_in_potential ), *map(GrowFromCenter, potential.split()) ) self.dither(2) self.play( FadeOut(loss_in_potential), GrowFromCenter(kinetic) ) self.dither(2) self.play(ApplyMethod(ms.shift, 5*UP)) self.dither() self.play(Transform( half, two, path_func = counterclockwise_path() )) self.dither() self.play( Transform( squared, sqrt, path_func = clockwise_path() ), Transform(equals, new_eq) ) self.dither(2)
def construct(self): n_terms = 4 def func((x, y, ignore)): z = complex(x, y) if (np.abs(x%1 - 0.5)<0.01 and y < 0.01) or np.abs(z)<0.01: return ORIGIN out_z = 1./(2*np.tan(np.pi*z)*(z**2)) return out_z.real*RIGHT - out_z.imag*UP arrows = Mobject(*[ Arrow(ORIGIN, np.sqrt(2)*point) for point in compass_directions(4, RIGHT+UP) ]) arrows.highlight(YELLOW) arrows.ingest_submobjects() all_arrows = Mobject(*[ arrows.copy().scale(0.3/(x)).shift(x*RIGHT) for x in range(1, n_terms+2) ]) terms = TexMobject([ "\\dfrac{1}{%d^2} + "%(x+1) for x in range(n_terms) ]+["\\cdots"]) terms.shift(2*UP) plane = NumberPlane(color = BLUE_E) axes = Mobject(NumberLine(), NumberLine().rotate(np.pi/2)) axes.highlight(WHITE) for term in terms.split(): self.play(ShimmerIn(term, run_time = 0.5)) self.dither() self.play(ShowCreation(plane), ShowCreation(axes)) self.play(*[ Transform(*pair) for pair in zip(terms.split(), all_arrows.split()) ]) self.play(PhaseFlow( func, plane, run_time = 5, virtual_time = 8 ))
class FluidFlow(Scene): DEFAULT_CONFIG = { "arrow_spacing" : 1, "dot_spacing" : 0.5, "dot_color" : BLUE_B, "text_color" : WHITE, "arrow_color" : GREEN_A, "points_height" : SPACE_HEIGHT, "points_width" : SPACE_WIDTH, } def use_function(self, function): self.function = function def get_points(self, spacing): x_radius, y_radius = [ val-val%spacing for val in self.points_width, self.points_height ] return map(np.array, it.product( np.arange(-x_radius, x_radius+spacing, spacing), np.arange(-y_radius, y_radius+spacing, spacing), [0] )) def add_plane(self): self.add(NumberPlane().fade()) def add_dots(self): points = self.get_points(self.dot_spacing) self.dots = Mobject(*map(Dot, points)) self.dots.highlight(self.dot_color) self.play(ShowCreation(self.dots)) self.dither() def add_arrows(self, true_length = False): if not hasattr(self, "function"): raise Exception("Must run use_function first") points = self.get_points(self.arrow_spacing) points = filter( lambda p : np.linalg.norm(self.function(p)) > 0.01, points ) angles = map(angle_of_vector, map(self.function, points)) prototype = Arrow( ORIGIN, RIGHT*self.arrow_spacing/2., color = self.arrow_color, tip_length = 0.1, buff = 0 ) arrows = [] for point in points: arrow = prototype.copy() output = self.function(point) if true_length: arrow.scale(np.linalg.norm(output)) arrow.rotate(angle_of_vector(output)) arrow.shift(point) arrows.append(arrow) self.arrows = Mobject(*arrows) self.play(ShowCreation(self.arrows)) self.dither() def add_paddle(self): pass def flow(self, **kwargs): if not hasattr(self, "function"): raise Exception("Must run use_function first") self.play(ApplyToCenters( PhaseFlow, self.dots.split(), function = self.function, **kwargs )) def label(self, text, time = 5): mob = TextMobject(text) mob.scale(1.5) mob.to_edge(UP) rectangle = region_from_polygon_vertices(*[ mob.get_corner(vect) + 0.3*vect for vect in [ UP+RIGHT, UP+LEFT, DOWN+LEFT, DOWN+RIGHT ] ]) mob.highlight(self.text_color) rectangle = MobjectFromRegion(rectangle, "#111111") rectangle.point_thickness = 3 self.add(rectangle, mob) self.dither(time) self.remove(mob, rectangle)