mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Up to squiggling on random extensions in zeta
This commit is contained in:
19
camera.py
19
camera.py
@ -17,6 +17,9 @@ class Camera(object):
|
||||
"space_shape" : (SPACE_HEIGHT, SPACE_WIDTH),
|
||||
"space_center" : ORIGIN,
|
||||
"background_color" : BLACK,
|
||||
#Points in vectorized mobjects with norm greater
|
||||
#than this value will be rescaled.
|
||||
"max_allowable_norm" : 5*SPACE_WIDTH,
|
||||
}
|
||||
|
||||
def __init__(self, background = None, **kwargs):
|
||||
@ -138,6 +141,7 @@ class Camera(object):
|
||||
result = ""
|
||||
for mob in [vmobject]+vmobject.get_subpath_mobjects():
|
||||
points = mob.points
|
||||
points = self.adjust_out_of_range_points(points)
|
||||
if len(points) == 0:
|
||||
continue
|
||||
points = self.align_points_to_camera(points)
|
||||
@ -190,6 +194,21 @@ class Camera(object):
|
||||
## This is where projection should live
|
||||
return points - self.space_center
|
||||
|
||||
def adjust_out_of_range_points(self, points):
|
||||
if not np.any(points > self.max_allowable_norm):
|
||||
return points
|
||||
norms = np.apply_along_axis(np.linalg.norm, 1, points)
|
||||
violator_indices = norms > self.max_allowable_norm
|
||||
violators = points[violator_indices,:]
|
||||
violator_norms = norms[violator_indices]
|
||||
reshaped_norms = np.repeat(
|
||||
violator_norms.reshape((len(violator_norms), 1)),
|
||||
points.shape[1], 1
|
||||
)
|
||||
rescaled = self.max_allowable_norm * violators / reshaped_norms
|
||||
points[violator_indices] = rescaled
|
||||
return points
|
||||
|
||||
def points_to_pixel_coords(self, points):
|
||||
result = np.zeros((len(points), 2))
|
||||
ph, pw = self.pixel_shape
|
||||
|
170
zeta.py
170
zeta.py
@ -27,10 +27,11 @@ mpmath.mp.dps = 7
|
||||
|
||||
|
||||
def zeta(z):
|
||||
max_norm = 5*SPACE_WIDTH
|
||||
try:
|
||||
return np.complex(mpmath.zeta(z))
|
||||
except:
|
||||
return np.complex(10*SPACE_WIDTH, 0)
|
||||
return np.complex(max_norm, 0)
|
||||
|
||||
class ComplexTransformationScene(Scene):
|
||||
CONFIG = {
|
||||
@ -48,7 +49,7 @@ class ComplexTransformationScene(Scene):
|
||||
"horiz_start_color" : GREEN_B,
|
||||
"horiz_end_color" : YELLOW,
|
||||
"num_anchors_to_add_per_line" : 50,
|
||||
"thincken_lines_after_transformation" : False,
|
||||
"post_transformation_storke_width" : None,
|
||||
"default_apply_complex_function_kwargs" : {
|
||||
"run_time" : 5,
|
||||
},
|
||||
@ -152,7 +153,7 @@ class ComplexTransformationScene(Scene):
|
||||
self.add_points_to_plane(plane)
|
||||
transformer = VGroup(
|
||||
plane, *self.transformable_mobjects
|
||||
)
|
||||
)
|
||||
return transformer, transform_kwargs
|
||||
|
||||
|
||||
@ -162,8 +163,8 @@ class ComplexTransformationScene(Scene):
|
||||
transformer.target.apply_complex_function(func)
|
||||
for mob in transformer.target[0].family_members_with_points():
|
||||
mob.make_smooth()
|
||||
if mob.get_stroke_width() == 1 and self.thincken_lines_after_transformation:
|
||||
mob.set_stroke(width = 2)
|
||||
if self.post_transformation_storke_width is not None:
|
||||
transformer.target.set_stroke(width = self.post_transformation_storke_width)
|
||||
self.play(
|
||||
MoveToTarget(transformer, **transform_kwargs),
|
||||
*added_anims
|
||||
@ -187,7 +188,7 @@ class ZetaTransformationScene(ComplexTransformationScene):
|
||||
CONFIG = {
|
||||
"num_anchors_in_extra_lines" : 300,
|
||||
"num_anchors_to_add_per_line" : 75,
|
||||
"thincken_lines_after_transformation" : True,
|
||||
"post_transformation_storke_width" : 2,
|
||||
"default_apply_complex_function_kwargs" : {
|
||||
"run_time" : 5,
|
||||
}
|
||||
@ -231,12 +232,17 @@ class ZetaTransformationScene(ComplexTransformationScene):
|
||||
|
||||
def get_reflected_plane(self):
|
||||
reflected_plane = self.plane.copy()
|
||||
reflected_plane.rotate(np.pi, UP)
|
||||
reflected_plane.move_to(self.z_to_point(1), RIGHT)
|
||||
reflected_plane.rotate(np.pi, UP, about_point = RIGHT)
|
||||
for mob in reflected_plane.family_members_with_points():
|
||||
mob.highlight(
|
||||
Color(rgb = 1-0.5*color_to_rgb(mob.get_color()))
|
||||
)
|
||||
reflected_plane.prepare_for_nonlinear_transform(
|
||||
self.num_anchors_in_extra_lines
|
||||
)
|
||||
reflected_plane.submobjects = list(reversed(
|
||||
reflected_plane.family_members_with_points()
|
||||
))
|
||||
return reflected_plane
|
||||
|
||||
def apply_zeta_function(self, **kwargs):
|
||||
@ -1730,14 +1736,17 @@ class ShowZetaOnHalfPlane(ZetaTransformationScene):
|
||||
self.play(ShowCreation(left_i_lines, run_time = 2))
|
||||
self.dither(2)
|
||||
self.restore_mobjects(self.plane, left_i_lines)
|
||||
self.add_transformable_mobjects(left_i_lines)
|
||||
self.play(Transform(self.plane, colored_plane))
|
||||
self.dither()
|
||||
self.left_i_lines = left_i_lines
|
||||
|
||||
def show_continuation(self):
|
||||
reflected_plane = self.get_reflected_plane()
|
||||
self.play(ShowCreation(reflected_plane, run_time = 5))
|
||||
|
||||
self.remove(self.left_i_lines)
|
||||
reflected_plane.prepare_for_nonlinear_transform(
|
||||
self.num_anchors_to_add_per_line
|
||||
)
|
||||
self.add_transformable_mobjects(reflected_plane)
|
||||
self.dither()
|
||||
self.apply_zeta_function()
|
||||
@ -1792,9 +1801,10 @@ class ShowConditionalDefinition(Scene):
|
||||
for s in ">", "\\le"
|
||||
])
|
||||
definitions = VGroup(sigma, something_else)
|
||||
definitions.arrange(DOWN, buff = MED_BUFF)
|
||||
conditions.arrange(DOWN, buff = MED_BUFF)
|
||||
conditions.next_to(definitions, RIGHT, buff = LARGE_BUFF)
|
||||
definitions.arrange_submobjects(DOWN, buff = 2*MED_BUFF, aligned_edge = LEFT)
|
||||
conditions.arrange_submobjects(DOWN, buff = LARGE_BUFF)
|
||||
definitions.shift(2*LEFT+2*UP)
|
||||
conditions.next_to(definitions, RIGHT, buff = LARGE_BUFF, aligned_edge = DOWN)
|
||||
brace = Brace(definitions, LEFT)
|
||||
zeta.next_to(brace, LEFT)
|
||||
|
||||
@ -1804,9 +1814,137 @@ class ShowConditionalDefinition(Scene):
|
||||
self.dither()
|
||||
self.play(
|
||||
sigma.restore,
|
||||
GrowFromCenter(brace)
|
||||
GrowFromCenter(brace),
|
||||
FadeIn(something_else)
|
||||
)
|
||||
self.play(*map(Write, [conditions, something_else]))
|
||||
self.play(Write(conditions))
|
||||
self.dither()
|
||||
|
||||
underbrace = Brace(something_else)
|
||||
question = underbrace.get_text("""
|
||||
What to put here?
|
||||
""")
|
||||
VGroup(underbrace, question).highlight(GREEN_B)
|
||||
|
||||
self.play(
|
||||
GrowFromCenter(underbrace),
|
||||
Write(question),
|
||||
something_else.highlight, GREEN_B
|
||||
)
|
||||
self.dither(2)
|
||||
|
||||
class SquiggleOnExtensions(ZetaTransformationScene):
|
||||
CONFIG = {
|
||||
"num_anchors_in_extra_lines" : 300,
|
||||
"x_min" : 1,
|
||||
"x_max" : int(SPACE_WIDTH+1),
|
||||
}
|
||||
def construct(self):
|
||||
self.show_negative_one()
|
||||
self.cycle_through_options()
|
||||
self.lock_into_place()
|
||||
|
||||
def show_negative_one(self):
|
||||
self.add_transformable_plane()
|
||||
self.add_extra_plane_lines_for_zeta()
|
||||
reflected_plane = self.get_reflected_plane()
|
||||
self.add(reflected_plane)
|
||||
|
||||
|
||||
dot = self.note_point(-1, "-1")
|
||||
self.add_transformable_mobjects(reflected_plane)
|
||||
self.apply_zeta_function(added_anims = [
|
||||
ApplyMethod(
|
||||
dot.move_to, self.z_to_point(-1./12),
|
||||
run_time = 5
|
||||
)
|
||||
])
|
||||
self.note_point(-1./12, "-\\frac{1}{12}")
|
||||
self.left_plane = reflected_plane
|
||||
self.dot = dot
|
||||
|
||||
def note_point(self, z, label_tex):
|
||||
dot = Dot(self.z_to_point(z))
|
||||
dot.highlight(YELLOW)
|
||||
label = TexMobject(label_tex)
|
||||
label.add_background_rectangle()
|
||||
label.next_to(dot, UP, buff = 1)
|
||||
label.shift(0.5*LEFT)
|
||||
arrow = Arrow(label, dot, buff = SMALL_BUFF)
|
||||
|
||||
self.play(Write(label, run_time = 1))
|
||||
self.play(*map(ShowCreation, [arrow, dot]))
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [arrow, label]))
|
||||
return dot
|
||||
|
||||
def cycle_through_options(self):
|
||||
gamma = np.euler_gamma
|
||||
def sinusoidal_func(point):
|
||||
x, y, z = point
|
||||
return np.array([
|
||||
x - abs(0.2*np.sin(np.pi*x/gamma)*np.cos(y)),
|
||||
y + 0.2*np.sin(np.pi*x/gamma),
|
||||
0
|
||||
])
|
||||
def mixed_scalar_func(point):
|
||||
x, y, z = point
|
||||
scalar = 1 + (gamma-x)/(gamma+SPACE_WIDTH)
|
||||
return np.array([
|
||||
(scalar**2)*x,
|
||||
(scalar**3)*y,
|
||||
0
|
||||
])
|
||||
def alt_sinusoidal_func(point):
|
||||
x, y, z = point
|
||||
freq = np.pi/gamma
|
||||
return np.array([
|
||||
x-0.2*np.sin(x*freq)*np.sin(x),
|
||||
y+0.2*np.sin(x*freq)*np.cos(y),
|
||||
0
|
||||
])
|
||||
|
||||
funcs = [sinusoidal_func, mixed_scalar_func, alt_sinusoidal_func]
|
||||
new_left_planes = [
|
||||
self.left_plane.copy().apply_function(func)
|
||||
for func in funcs
|
||||
]
|
||||
new_dots = [
|
||||
self.dot.copy().move_to(func(self.dot.get_center()))
|
||||
for func in funcs
|
||||
]
|
||||
self.left_plane.save_state()
|
||||
for plane, dot in zip(new_left_planes, new_dots):
|
||||
self.play(
|
||||
Transform(self.left_plane, plane),
|
||||
Transform(self.dot, new_dot),
|
||||
run_time = 3
|
||||
)
|
||||
self.dither()
|
||||
self.play(FadeOut(dot))
|
||||
|
||||
#Squiggle on example
|
||||
self.dither()
|
||||
self.play(FadeOut(self.left_plane))
|
||||
self.play(ShowCreation(
|
||||
self.left_plane,
|
||||
run_time = 5,
|
||||
rate_func = None
|
||||
))
|
||||
self.dither()
|
||||
|
||||
def lock_into_place(self):
|
||||
words = TextMobject("""
|
||||
If $\\zeta(s)$ is to have a
|
||||
\\emph{derivative} everywhere,
|
||||
there is only one possible extension
|
||||
""", alignment = "")
|
||||
words.to_corner(UP+LEFT)
|
||||
words.add_background_rectangle()
|
||||
|
||||
self.play(Write(words))
|
||||
self.add_foreground_mobjects(words)
|
||||
self.play(self.left_plane.restore)
|
||||
self.dither()
|
||||
|
||||
|
||||
@ -1836,8 +1974,6 @@ class ShowConditionalDefinition(Scene):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user