mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Initial zoom in on diamond fractal
This commit is contained in:
@ -6,7 +6,8 @@ DEFAULT_WIDTH = 1920
|
||||
|
||||
LOW_QUALITY_FRAME_DURATION = 1./20
|
||||
MEDIUM_QUALITY_FRAME_DURATION = 1./30
|
||||
PRODUCTION_QUALITY_FRAME_DURATION = 1./60
|
||||
# PRODUCTION_QUALITY_FRAME_DURATION = 1./60
|
||||
PRODUCTION_QUALITY_FRAME_DURATION = 1./30
|
||||
|
||||
#There might be other configuration than pixel_shape later...
|
||||
PRODUCTION_QUALITY_CAMERA_CONFIG = {
|
||||
|
@ -57,70 +57,111 @@ class SierpinskiTest(Scene):
|
||||
class ZoomInOnFractal(PiCreatureScene):
|
||||
CONFIG = {
|
||||
"fractal_order" : 6,
|
||||
"num_zooms" : 4,
|
||||
"fractal_class" : Sierpinski,
|
||||
"num_zooms" : 5,
|
||||
"fractal_class" : DiamondFractal,
|
||||
"index_to_replace" : 0,
|
||||
}
|
||||
def construct(self):
|
||||
morty = self.pi_creature
|
||||
fractal = self.get_zoomable_fractal()
|
||||
|
||||
fractal.show()
|
||||
|
||||
self.play(
|
||||
ShowCreation(
|
||||
fractal,
|
||||
run_time = 4,
|
||||
rate_func = rush_from
|
||||
),
|
||||
morty.change_mode, "hooray",
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
ApplyMethod(
|
||||
fractal.scale, 2**self.num_zooms,
|
||||
self.zoom_in_about_point,
|
||||
run_time = 8
|
||||
),
|
||||
morty.change_mode, "thinking",
|
||||
morty.look_at, fractal.get_corner(self.zoom_in_about_point),
|
||||
)
|
||||
self.play(Blink(morty))
|
||||
self.dither()
|
||||
|
||||
def get_zoomable_fractal(self):
|
||||
fractal = self.fractal_class(order = self.fractal_order)
|
||||
fractal.show()
|
||||
|
||||
to_be_tweaked = fractal
|
||||
for x in range(self.num_zooms):
|
||||
new_corner = self.fractal_class(order = self.fractal_order)
|
||||
new_corner.replace(to_be_tweaked[self.index_to_replace])
|
||||
self.tweak_subpart(new_corner)
|
||||
to_be_tweaked.submobjects[self.index_to_replace] = new_corner
|
||||
to_be_tweaked = new_corner
|
||||
self.zoom_in_about_point = to_be_tweaked.get_center()
|
||||
fractal = self.introduce_fractal()
|
||||
self.change_mode("thinking")
|
||||
self.blink()
|
||||
self.zoom_in(fractal)
|
||||
|
||||
|
||||
def introduce_fractal(self):
|
||||
fractal = self.fractal_class(order = 0)
|
||||
self.play(FadeIn(fractal))
|
||||
for order in range(1, self.fractal_order+1):
|
||||
new_fractal = self.fractal_class(order = order)
|
||||
self.play(
|
||||
Transform(fractal, new_fractal, run_time = 2),
|
||||
self.pi_creature.change_mode, "hooray"
|
||||
)
|
||||
return fractal
|
||||
|
||||
def tweak_subpart(self, subpart):
|
||||
pass
|
||||
def zoom_in(self, fractal):
|
||||
grower = fractal[self.index_to_replace]
|
||||
grower_target = fractal.copy()
|
||||
|
||||
for x in range(self.num_zooms):
|
||||
self.tweak_fractal_subpart(grower_target)
|
||||
grower_family = grower.family_members_with_points()
|
||||
everything = VGroup(*[
|
||||
submob
|
||||
for submob in fractal.family_members_with_points()
|
||||
if not submob.is_off_screen()
|
||||
if submob not in grower_family
|
||||
])
|
||||
everything.generate_target()
|
||||
everything.target.shift(
|
||||
grower_target.get_center()-grower.get_center()
|
||||
)
|
||||
everything.target.scale(
|
||||
grower_target.get_height()/grower.get_height()
|
||||
)
|
||||
|
||||
self.play(
|
||||
Transform(grower, grower_target),
|
||||
MoveToTarget(everything),
|
||||
self.pi_creature.change_mode, "thinking",
|
||||
run_time = 2
|
||||
)
|
||||
self.dither()
|
||||
grower_target = grower.copy()
|
||||
grower = grower[self.index_to_replace]
|
||||
|
||||
|
||||
class ZoomInOnDiamondFractal(ZoomInOnFractal):
|
||||
CONFIG = {
|
||||
"fractal_order" : 5,
|
||||
"fractal_class" : DiamondFractal,
|
||||
}
|
||||
def tweak_fractal_subpart(self, subpart):
|
||||
subpart.rotate_in_place(np.pi/4)
|
||||
|
||||
class WhatAreFractals(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
high_res_fractal = self.fractal_class(order = self.fractal_order)
|
||||
low_res_fractal = self.fractal_class(order = self.fractal_order-1)
|
||||
|
||||
high_res_fractal.scale(3, high_res_fractal.get_top())
|
||||
|
||||
self.add(low_res_fractal)
|
||||
self.student_says(
|
||||
"But what \\emph{is} a fractal",
|
||||
student_index = 2,
|
||||
width = 6
|
||||
)
|
||||
self.change_student_modes("thinking", "pondering", None)
|
||||
self.dither()
|
||||
self.play(Transform(low_res_fractal, high_res_fractal))
|
||||
self.dither(3)
|
||||
|
||||
name = TextMobject("Benoit Mandelbrot")
|
||||
name.to_corner(UP+LEFT)
|
||||
# picture = Rectangle(height = 4, width = 3)
|
||||
picture = ImageMobject("Mandelbrot")
|
||||
picture.scale_to_fit_height(4)
|
||||
picture.next_to(name, DOWN)
|
||||
self.play(
|
||||
Write(name, run_time = 2),
|
||||
FadeIn(picture),
|
||||
*[
|
||||
ApplyMethod(pi.look_at, name)
|
||||
for pi in self.get_everyone()
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
question = TextMobject("Aren't they", "self-similar", "shapes?")
|
||||
question.highlight_by_tex("self-similar", YELLOW)
|
||||
self.student_says(question)
|
||||
self.play(self.get_teacher().change_mode, "happy")
|
||||
self.dither(2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -116,6 +116,8 @@ def color_to_int_rgb(color):
|
||||
return (255*color_to_rgb(color)).astype('uint8')
|
||||
|
||||
def color_gradient(reference_colors, length_of_output):
|
||||
if length_of_output == 0:
|
||||
return reference_colors[0]
|
||||
rgbs = map(color_to_rgb, reference_colors)
|
||||
alphas = np.linspace(0, (len(rgbs) - 1), length_of_output)
|
||||
floors = alphas.astype('int')
|
||||
|
@ -270,6 +270,17 @@ class Mobject(object):
|
||||
self.to_edge(vect, **kwargs)
|
||||
return self
|
||||
|
||||
def is_off_screen(self):
|
||||
if self.get_left()[0] > SPACE_WIDTH:
|
||||
return True
|
||||
if self.get_right()[0] < -SPACE_WIDTH:
|
||||
return True
|
||||
if self.get_bottom()[1] > SPACE_HEIGHT:
|
||||
return True
|
||||
if self.get_top()[1] < -SPACE_HEIGHT:
|
||||
return True
|
||||
return False
|
||||
|
||||
def stretch_in_place(self, factor, dim):
|
||||
self.do_in_place(self.stretch, factor, dim)
|
||||
return self
|
||||
|
@ -30,7 +30,12 @@ class SelfSimilarFractal(VMobject):
|
||||
self.gradient_highlight(*self.colors)
|
||||
|
||||
def generate_points(self):
|
||||
self.submobjects = self.get_order_n_self(self.order).submobjects
|
||||
order_n_self = self.get_order_n_self(self.order)
|
||||
if self.order == 0:
|
||||
self.submobjects = [order_n_self]
|
||||
else:
|
||||
self.submobjects = order_n_self.submobjects
|
||||
return self
|
||||
|
||||
def get_order_n_self(self, order):
|
||||
if order == 0:
|
||||
@ -69,7 +74,8 @@ class Sierpinski(SelfSimilarFractal):
|
||||
class DiamondFractal(SelfSimilarFractal):
|
||||
CONFIG = {
|
||||
"num_subparts" : 4,
|
||||
"height" : 6,
|
||||
"height" : 4,
|
||||
"colors" : [GREEN_E, YELLOW],
|
||||
}
|
||||
def get_seed_shape(self):
|
||||
return RegularPolygon(n = 4)
|
||||
|
Reference in New Issue
Block a user