from manim import *
class KochCurve(VMobject):
def __init__(
self,
level=0,
length=config.frame_width * 3 / 4,
point=ORIGIN,
group=True,
**kwargs
):
super().__init__(**kwargs)
self.level = 0 if level < 0 else level
self.length = length
self.kwargs = kwargs
self._koch_curve(self.level, self.length, point, group=group)
def _koch_curve(self, level, length, point, group=True):
l = length / (3**level)
points = [LEFT * l / 2, RIGHT * l / 2]
self.set_points_as_corners(points)
vmob = self.copy()
for _ in range(level):
new_vmob = VGroup()
for i in (0, PI / 3, -PI / 3, 0):
new_vmob.add(vmob.copy().rotate(i))
new_vmob.arrange(RIGHT, buff=0, aligned_edge=DOWN)
vmob.become(new_vmob)
vmob.move_to(point)
if group:
points = vmob.get_all_points()
self.set_points(points)
else:
self.become(vmob)
def new_level(self, level=None, length=None, point=None, **kwargs):
level = self.level if level is None else level
length = self.length if length is None else length
point = self.get_center() if point is None else point
self.kwargs.update(kwargs)
kwargs = self.kwargs
self.__init__(level, length, point, **kwargs)
def next_level(self, **kwargs):
level = self.level + 1
self.new_level(level, **kwargs)
def prev_level(self, **kwargs):
level = self.level - 1
self.new_level(level, **kwargs)
class KochSnowflake(KochCurve):
def __init__(
self,
level=0,
length=config.frame_width / 3,
point=ORIGIN,
invert=False,
fill_opacity=1,
stroke_width=0,
color=BLUE,
**kwargs
):
kwargs.update(
{
"fill_opacity": fill_opacity,
"stroke_width": stroke_width,
"color": color,
}
)
super().__init__(**kwargs)
self.level = 0 if level < 0 else level
self.length = length
kwargs.update({"invert": invert})
self.kwargs = kwargs
self._koch_snowflake(self.level, self.length, point, invert)
def _koch_snowflake(self, level, length, point, invert):
self._koch_curve(level, length, point, group=True)
if invert:
self.rotate(PI).reverse_direction()
kc2 = self.copy().rotate(PI, about_point=self.get_top())
else:
kc2 = self.copy().rotate(PI, about_point=self.get_bottom())
kc1 = self.copy().rotate(-PI / 3, about_point=self.get_end())
kc3 = self.copy().rotate(PI / 3, about_point=self.get_start())
ks = VGroup(kc1, kc2, kc3).move_to(point)
points = ks.get_all_points()
self.sides = ks.set_style(fill_opacity=0, stroke_width=4)
self.set_points_as_corners(points)