mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 22:03:01 +08:00
End of fractal_dimension project
This commit is contained in:
167
fractal_charm.py
Normal file
167
fractal_charm.py
Normal file
@ -0,0 +1,167 @@
|
||||
from helpers import *
|
||||
|
||||
from mobject.tex_mobject import TexMobject
|
||||
from mobject import Mobject
|
||||
from mobject.image_mobject import ImageMobject
|
||||
from mobject.vectorized_mobject import *
|
||||
|
||||
from animation.animation import Animation
|
||||
from animation.transform import *
|
||||
from animation.simple_animations import *
|
||||
from animation.playground import *
|
||||
from topics.geometry import *
|
||||
from topics.characters import *
|
||||
from topics.functions import *
|
||||
from topics.fractals import *
|
||||
from topics.number_line import *
|
||||
from topics.combinatorics import *
|
||||
from topics.numerals import *
|
||||
from topics.three_dimensions import *
|
||||
from scene import Scene
|
||||
from camera import Camera
|
||||
from mobject.svg_mobject import *
|
||||
from mobject.tex_mobject import *
|
||||
|
||||
class FractalCreation(Scene):
|
||||
CONFIG = {
|
||||
"fractal_class" : PentagonalFractal,
|
||||
"max_order" : 5,
|
||||
"transform_kwargs" : {
|
||||
"path_arc" : np.pi/6,
|
||||
"submobject_mode" : "lagged_start",
|
||||
"run_time" : 2,
|
||||
},
|
||||
"fractal_kwargs" : {},
|
||||
"modify_stroke_width" : True,
|
||||
}
|
||||
def construct(self):
|
||||
fractal = self.fractal_class(order = 0, **self.fractal_kwargs)
|
||||
self.play(FadeIn(fractal))
|
||||
for order in range(1, self.max_order+1):
|
||||
new_fractal = self.fractal_class(
|
||||
order = order,
|
||||
**self.fractal_kwargs
|
||||
)
|
||||
if self.modify_stroke_width:
|
||||
smallest = new_fractal.family_members_with_points()[0]
|
||||
if smallest.get_width() < 0.25:
|
||||
new_fractal.set_stroke(width = 2)
|
||||
if smallest.get_width() < 0.1:
|
||||
new_fractal.set_stroke(width = 1)
|
||||
self.play(Transform(
|
||||
fractal, new_fractal,
|
||||
**self.transform_kwargs
|
||||
))
|
||||
self.dither()
|
||||
self.dither()
|
||||
self.fractal = fractal
|
||||
|
||||
class PentagonalFractalCreation(FractalCreation):
|
||||
pass
|
||||
|
||||
class DiamondFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : DiamondFractal,
|
||||
"max_order" : 6,
|
||||
"fractal_kwargs" : {"height" : 6}
|
||||
}
|
||||
|
||||
|
||||
class PiCreatureFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : PiCreatureFractal,
|
||||
"max_order" : 5,
|
||||
"fractal_kwargs" : {"height" : 6},
|
||||
"transform_kwargs" : {
|
||||
"submobject_mode" : "all_at_once",
|
||||
"run_time" : 2,
|
||||
},
|
||||
}
|
||||
def construct(self):
|
||||
FractalCreation.construct(self)
|
||||
fractal = self.fractal
|
||||
smallest_pi = fractal[0][0]
|
||||
zoom_factor = 0.1/smallest_pi.get_height()
|
||||
fractal.generate_target()
|
||||
fractal.target.shift(-smallest_pi.get_corner(UP+LEFT))
|
||||
fractal.target.scale(zoom_factor)
|
||||
self.play(MoveToTarget(fractal, run_time = 10))
|
||||
self.dither()
|
||||
|
||||
class QuadraticKochFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : QuadraticKoch,
|
||||
"max_order" : 5,
|
||||
"fractal_kwargs" : {"radius" : 10},
|
||||
# "transform_kwargs" : {
|
||||
# "submobject_mode" : "all_at_once",
|
||||
# "run_time" : 2,
|
||||
# },
|
||||
}
|
||||
|
||||
class KochSnowFlakeFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : KochSnowFlake,
|
||||
"max_order" : 5,
|
||||
"fractal_kwargs" : {"radius" : 6},
|
||||
"transform_kwargs" : {
|
||||
"submobject_mode" : "lagged_start",
|
||||
"path_arc" : np.pi/6,
|
||||
"run_time" : 2,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class WonkyHexagonFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : WonkyHexagonFractal,
|
||||
"max_order" : 5,
|
||||
"fractal_kwargs" : {"height" : 6},
|
||||
"transform_kwargs" : {
|
||||
"submobject_mode" : "lagged_start",
|
||||
"path_arc" : np.pi/6,
|
||||
"run_time" : 2,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from helpers import *
|
||||
|
||||
from mobject.tex_mobject import TexMobject
|
||||
@ -24,6 +22,8 @@ from camera import Camera
|
||||
from mobject.svg_mobject import *
|
||||
from mobject.tex_mobject import *
|
||||
|
||||
from fractal_charm import FractalCreation
|
||||
|
||||
from eoc.graph_scene import GraphScene
|
||||
from eoc.chapter1 import PatreonThanks
|
||||
|
||||
@ -82,26 +82,7 @@ class SierpinskiTest(Scene):
|
||||
# self.play(sierp.scale, 2, sierp.get_top())
|
||||
# self.dither(3)
|
||||
|
||||
class FractalCreation(Scene):
|
||||
CONFIG = {
|
||||
"fractal_class" : PentagonalFractal,
|
||||
"max_order" : 5,
|
||||
"path_arc" : np.pi/6,
|
||||
"submobject_mode" : "lagged_start"
|
||||
}
|
||||
def construct(self):
|
||||
fractal = self.fractal_class(order = 0)
|
||||
self.play(FadeIn(fractal))
|
||||
for order in range(1, self.max_order+1):
|
||||
new_fractal = self.fractal_class(order = order)
|
||||
self.play(Transform(
|
||||
fractal, new_fractal,
|
||||
path_arc = self.path_arc,
|
||||
submobject_mode = self.submobject_mode,
|
||||
run_time = 2
|
||||
))
|
||||
self.dither()
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
###################################
|
||||
@ -2312,7 +2293,7 @@ class IntroduceLogLogPlot(GraphScene):
|
||||
class ManyBritainCounts(BoxCountingWithBritain):
|
||||
CONFIG = {
|
||||
"box_width" : 0.1,
|
||||
"num_boundary_check_points" : 5000,
|
||||
"num_boundary_check_points" : 10000,
|
||||
"corner_rect_left_extension" : 1,
|
||||
}
|
||||
def construct(self):
|
||||
@ -2325,8 +2306,8 @@ class ManyBritainCounts(BoxCountingWithBritain):
|
||||
self.add(self.get_grid())
|
||||
self.add(britain)
|
||||
|
||||
for width in range(1, 6):
|
||||
self.play(britain.scale_to_fit_width, width)
|
||||
for x in range(5):
|
||||
self.play(britain.scale, 2, britain.point_from_proportion(0.8))
|
||||
boxes = self.get_highlighted_boxes(britain)
|
||||
self.play(ShowCreation(boxes))
|
||||
self.dither()
|
||||
@ -2360,6 +2341,49 @@ class DefineFractal(TeacherStudentsScene):
|
||||
])
|
||||
self.dither(3)
|
||||
|
||||
class RoughnessAndFractionalDimension(Scene):
|
||||
def construct(self):
|
||||
title = TextMobject(
|
||||
"Non-integer dimension $\\Leftrightarrow$ Roughness"
|
||||
)
|
||||
title.to_edge(UP)
|
||||
self.add(title)
|
||||
|
||||
randy = Randolph().scale(2)
|
||||
randy.to_corner(DOWN+RIGHT)
|
||||
self.add(randy)
|
||||
|
||||
target = randy.copy()
|
||||
target.change_mode("hooray")
|
||||
ponder_target = randy.copy()
|
||||
ponder_target.change_mode("pondering")
|
||||
for mob in target, ponder_target:
|
||||
fractalify(mob, order = 2)
|
||||
|
||||
dimension_label = TextMobject("Boundary dimension = ", "1")
|
||||
dimension_label.to_edge(LEFT)
|
||||
one = dimension_label[1]
|
||||
one.highlight(BLUE)
|
||||
new_dim = TexMobject("1.2")
|
||||
new_dim.move_to(one, DOWN+LEFT)
|
||||
new_dim.highlight(one.get_color())
|
||||
self.add(dimension_label)
|
||||
|
||||
self.play(Blink(randy))
|
||||
self.play(
|
||||
Transform(randy, target, run_time = 2),
|
||||
Transform(one, new_dim)
|
||||
)
|
||||
self.dither()
|
||||
self.play(Blink(randy))
|
||||
self.play(randy.look, DOWN+RIGHT)
|
||||
self.dither()
|
||||
self.play(randy.look, DOWN+LEFT)
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
self.play(Transform(randy, ponder_target))
|
||||
self.dither()
|
||||
|
||||
class DifferentSlopesAtDifferentScales(IntroduceLogLogPlot):
|
||||
def construct(self):
|
||||
self.setup_axes(animate = False)
|
||||
@ -2401,14 +2425,53 @@ class DifferentSlopesAtDifferentScales(IntroduceLogLogPlot):
|
||||
|
||||
class HoldUpCoilExample(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
point = UP+RIGHT
|
||||
self.play(
|
||||
self.get_teacher().change_mode, "raise_right_hand",
|
||||
self.get_teacher().look, UP+LEFT
|
||||
self.get_teacher().look_at, point
|
||||
)
|
||||
self.play(*[
|
||||
ApplyMethod(pi.look_at, point)
|
||||
for pi in self.get_students()
|
||||
])
|
||||
self.dither(5)
|
||||
self.change_student_modes(*["thinking"]*3)
|
||||
self.play(*[
|
||||
ApplyMethod(pi.look_at, point)
|
||||
for pi in self.get_students()
|
||||
])
|
||||
self.dither(5)
|
||||
|
||||
class SmoothHilbertZoom(Scene):
|
||||
def construct(self):
|
||||
hilbert = HilbertCurve(
|
||||
order = 7,
|
||||
color = MAROON_B,
|
||||
monochromatic = True
|
||||
)
|
||||
hilbert.make_smooth()
|
||||
self.add(hilbert)
|
||||
|
||||
two_d_title = TextMobject("2D at a distance...")
|
||||
one_d_title = TextMobject("1D up close")
|
||||
for title in two_d_title, one_d_title:
|
||||
title.to_edge(UP)
|
||||
|
||||
self.add(two_d_title)
|
||||
self.dither()
|
||||
self.play(
|
||||
ApplyMethod(
|
||||
hilbert.scale, 100,
|
||||
hilbert.point_from_proportion(0.3),
|
||||
),
|
||||
Transform(
|
||||
two_d_title, one_d_title,
|
||||
rate_func = squish_rate_func(smooth)
|
||||
),
|
||||
run_time = 3
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class ListDimensionTypes(PiCreatureScene):
|
||||
CONFIG = {
|
||||
"use_morty" : False,
|
||||
@ -2777,7 +2840,7 @@ class FractalNonFractalFlowChart(Scene):
|
||||
|
||||
class ShowPiCreatureFractalCreation(FractalCreation):
|
||||
CONFIG = {
|
||||
"fractal_class" : PiCreatureFractal,
|
||||
"fractal_class" : PentagonalPiCreatureFractal,
|
||||
"max_order" : 4,
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,17 @@ class PiCreature(SVGMobject):
|
||||
return self
|
||||
|
||||
|
||||
def get_all_pi_creature_modes():
|
||||
result = []
|
||||
prefix = "PiCreatures_"
|
||||
suffix = ".svg"
|
||||
for file in os.listdir(PI_CREATURE_DIR):
|
||||
if file.startswith(prefix) and file.endswith(suffix):
|
||||
result.append(
|
||||
file[len(prefix):-len(suffix)]
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
class Randolph(PiCreature):
|
||||
pass #Nothing more than an alternative name
|
||||
|
@ -3,8 +3,8 @@ from mobject.vectorized_mobject import VMobject, VGroup, VectorizedPoint
|
||||
from scene import Scene
|
||||
from animation.transform import Transform
|
||||
from animation.simple_animations import ShowCreation
|
||||
from topics.geometry import Line, Polygon, RegularPolygon
|
||||
from characters import PiCreature, Randolph
|
||||
from topics.geometry import Line, Polygon, RegularPolygon, Square
|
||||
from characters import PiCreature, Randolph, get_all_pi_creature_modes
|
||||
|
||||
from helpers import *
|
||||
|
||||
@ -20,10 +20,7 @@ def fractalify(vmobject, order = 3, *args, **kwargs):
|
||||
fractalification_iteration(vmobject)
|
||||
return vmobject
|
||||
|
||||
def fractalification_iteration(vmobject,
|
||||
dimension = 1.05,
|
||||
num_inserted_anchors_range = range(1, 4)
|
||||
):
|
||||
def fractalification_iteration(vmobject, dimension = 1.05, num_inserted_anchors_range = range(1, 4)):
|
||||
num_points = vmobject.get_num_points()
|
||||
if num_points > 0:
|
||||
# original_anchors = vmobject.get_anchors()
|
||||
@ -147,7 +144,7 @@ class PentagonalFractal(SelfSimilarFractal):
|
||||
part.shift(0.95*part.get_height()*UP)
|
||||
part.rotate(2*np.pi*x/5)
|
||||
|
||||
class PiCreatureFractal(PentagonalFractal):
|
||||
class PentagonalPiCreatureFractal(PentagonalFractal):
|
||||
def init_colors(self):
|
||||
SelfSimilarFractal.init_colors(self)
|
||||
internal_pis = [
|
||||
@ -170,6 +167,88 @@ class PiCreatureFractal(PentagonalFractal):
|
||||
PentagonalFractal.arrange_subparts(self, *subparts)
|
||||
|
||||
|
||||
class PiCreatureFractal(VMobject):
|
||||
CONFIG = {
|
||||
"order" : 7,
|
||||
"scale_val" : 1.7,
|
||||
"start_mode" : "hooray",
|
||||
"height" : 6,
|
||||
"colors" : [
|
||||
BLUE_D, BLUE_B, MAROON_B, MAROON_D, GREY,
|
||||
YELLOW, RED, GREY_BROWN, RED, RED_E,
|
||||
],
|
||||
"random_seed" : 0,
|
||||
"stroke_width" : 0,
|
||||
}
|
||||
def init_colors(self):
|
||||
VMobject.init_colors(self)
|
||||
internal_pis = [
|
||||
pi
|
||||
for pi in self.submobject_family()
|
||||
if isinstance(pi, PiCreature)
|
||||
]
|
||||
random.seed(self.random_seed)
|
||||
for pi in reversed(internal_pis):
|
||||
color = random.choice(self.colors)
|
||||
pi.highlight(color)
|
||||
pi.set_stroke(color, width = 0)
|
||||
|
||||
|
||||
def generate_points(self):
|
||||
random.seed(self.random_seed)
|
||||
modes = get_all_pi_creature_modes()
|
||||
seed = PiCreature(mode = self.start_mode)
|
||||
seed.scale_to_fit_height(self.height)
|
||||
seed.to_edge(DOWN)
|
||||
creatures = [seed]
|
||||
self.add(seed)
|
||||
for x in range(self.order):
|
||||
new_creatures = []
|
||||
for creature in creatures:
|
||||
for eye in creature.eyes:
|
||||
new_creature = PiCreature(
|
||||
mode = random.choice(modes)
|
||||
)
|
||||
new_creature.replace(eye)
|
||||
new_creature.scale(
|
||||
self.scale_val,
|
||||
about_point = new_creature.get_bottom()
|
||||
)
|
||||
new_creatures.append(new_creature)
|
||||
creature.blink()
|
||||
self.add_to_back(VGroup(*new_creatures))
|
||||
creatures = new_creatures
|
||||
|
||||
# def init_colors(self):
|
||||
# VMobject.init_colors(self)
|
||||
# self.gradient_highlight(*self.colors)
|
||||
|
||||
|
||||
class WonkyHexagonFractal(SelfSimilarFractal):
|
||||
CONFIG = {
|
||||
"num_subparts" : 7
|
||||
}
|
||||
def get_seed_shape(self):
|
||||
return RegularPolygon(n=6)
|
||||
|
||||
def arrange_subparts(self, *subparts):
|
||||
for i, piece in enumerate(subparts):
|
||||
piece.rotate(i*np.pi/12)
|
||||
p1, p2, p3, p4, p5, p6, p7 = subparts
|
||||
center_row = VGroup(p1, p4, p7)
|
||||
center_row.arrange_submobjects(RIGHT, buff = 0)
|
||||
for p in p2, p3, p5, p6:
|
||||
p.scale_to_fit_width(p1.get_width())
|
||||
p2.move_to(p1.get_top(), DOWN+LEFT)
|
||||
p3.move_to(p1.get_bottom(), UP+LEFT)
|
||||
p5.move_to(p4.get_top(), DOWN+LEFT)
|
||||
p6.move_to(p4.get_bottom(), UP+LEFT)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
######## Space filling curves ############
|
||||
|
||||
class FractalCurve(VMobject):
|
||||
|
Reference in New Issue
Block a user