mirror of
https://github.com/3b1b/manim.git
synced 2025-07-29 04:53:34 +08:00
More hilbert work, including simple new Grid mobject
This commit is contained in:
@ -78,12 +78,19 @@ class CounterclockwiseTransform(Transform):
|
|||||||
"interpolation_function" : counterclockwise_path()
|
"interpolation_function" : counterclockwise_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpinInFromNothing(Transform):
|
class GrowFromCenter(Transform):
|
||||||
|
def __init__(self, mobject, **kwargs):
|
||||||
|
Transform.__init__(
|
||||||
|
self,
|
||||||
|
Point(mobject.get_center()),
|
||||||
|
mobject,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
class SpinInFromNothing(GrowFromCenter):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"interpolation_function" : counterclockwise_path()
|
"interpolation_function" : counterclockwise_path()
|
||||||
}
|
}
|
||||||
def __init__(self, mob, **kwargs):
|
|
||||||
Transform.__init__(self, Point(mob.get_center()), mob, **kwargs)
|
|
||||||
|
|
||||||
class ApplyMethod(Transform):
|
class ApplyMethod(Transform):
|
||||||
def __init__(self, method, *args, **kwargs):
|
def __init__(self, method, *args, **kwargs):
|
||||||
|
@ -170,10 +170,10 @@ def path_along_arc(arc_angle):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
def clockwise_path():
|
def clockwise_path():
|
||||||
return path_along_arc(np.pi)
|
return path_along_arc(-np.pi)
|
||||||
|
|
||||||
def counterclockwise_path():
|
def counterclockwise_path():
|
||||||
return path_along_arc(-np.pi)
|
return path_along_arc(np.pi)
|
||||||
|
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
|
@ -31,6 +31,7 @@ class SpaceFillingCurve(Mobject1D):
|
|||||||
def get_anchor_points(self):
|
def get_anchor_points(self):
|
||||||
raise Exception("Not implemented")
|
raise Exception("Not implemented")
|
||||||
|
|
||||||
|
|
||||||
class LindenmayerCurve(SpaceFillingCurve):
|
class LindenmayerCurve(SpaceFillingCurve):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"axiom" : "A",
|
"axiom" : "A",
|
||||||
@ -112,6 +113,9 @@ class SelfSimilarSpaceFillingCurve(SpaceFillingCurve):
|
|||||||
points = self.refine_into_subparts(points)
|
points = self.refine_into_subparts(points)
|
||||||
return points
|
return points
|
||||||
|
|
||||||
|
def generate_grid(self):
|
||||||
|
raise Exception("Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HilbertCurve(SelfSimilarSpaceFillingCurve):
|
class HilbertCurve(SelfSimilarSpaceFillingCurve):
|
||||||
|
@ -5,13 +5,15 @@ from mobject.image_mobject import ImageMobject
|
|||||||
from scene import Scene
|
from scene import Scene
|
||||||
|
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from animation.transform import Transform, CounterclockwiseTransform, ApplyMethod
|
from animation.transform import Transform, CounterclockwiseTransform, \
|
||||||
|
ApplyMethod, GrowFromCenter
|
||||||
from animation.simple_animations import ShowCreation, ShimmerIn
|
from animation.simple_animations import ShowCreation, ShimmerIn
|
||||||
from animation.meta_animations import DelayByOrder, TransformAnimations
|
from animation.meta_animations import DelayByOrder, TransformAnimations
|
||||||
from animation.playground import VibratingString
|
from animation.playground import VibratingString
|
||||||
|
|
||||||
from topics.geometry import Line
|
from topics.geometry import Line, Dot, Arrow
|
||||||
from topics.characters import ThoughtBubble
|
from topics.characters import ThoughtBubble
|
||||||
|
from topics.number_line import UnitInterval
|
||||||
|
|
||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
@ -178,10 +180,12 @@ class ImageDataIsTwoDimensional(Scene):
|
|||||||
class SoundDataIsOneDimensional(Scene):
|
class SoundDataIsOneDimensional(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
overtones = 5
|
overtones = 5
|
||||||
|
floor = 2*DOWN
|
||||||
main_string = VibratingString(color = BLUE_D)
|
main_string = VibratingString(color = BLUE_D)
|
||||||
component_strings = [
|
component_strings = [
|
||||||
VibratingString(
|
VibratingString(
|
||||||
num_periods = k+1,
|
num_periods = k+1,
|
||||||
|
overtones = 2,
|
||||||
color = color,
|
color = color,
|
||||||
center = 2*DOWN + UP*k
|
center = 2*DOWN + UP*k
|
||||||
)
|
)
|
||||||
@ -190,17 +194,53 @@ class SoundDataIsOneDimensional(Scene):
|
|||||||
Color(BLUE_E).range_to(WHITE, overtones)
|
Color(BLUE_E).range_to(WHITE, overtones)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
dots = [
|
||||||
|
Dot(
|
||||||
|
string.mobject.get_center(),
|
||||||
|
color = string.mobject.get_color()
|
||||||
|
)
|
||||||
|
for string in component_strings
|
||||||
|
]
|
||||||
|
|
||||||
|
freq_line = UnitInterval()
|
||||||
|
freq_line.shift(floor)
|
||||||
|
freq_line.sort_points(np.linalg.norm)
|
||||||
|
brace = Brace(freq_line, UP)
|
||||||
|
words = TextMobject("Range of frequency values")
|
||||||
|
words.next_to(brace, UP)
|
||||||
|
|
||||||
|
|
||||||
self.play(main_string)
|
|
||||||
self.remove(main_string.mobject)
|
|
||||||
self.play(*[
|
self.play(*[
|
||||||
TransformAnimations(
|
TransformAnimations(
|
||||||
main_string.copy(),
|
main_string.copy(),
|
||||||
string
|
string,
|
||||||
|
run_time = 5
|
||||||
)
|
)
|
||||||
for string in component_strings
|
for string in component_strings
|
||||||
])
|
])
|
||||||
|
self.clear()
|
||||||
|
self.play(*[
|
||||||
|
TransformAnimations(
|
||||||
|
string,
|
||||||
|
Animation(dot)
|
||||||
|
)
|
||||||
|
for string, dot in zip(component_strings, dots)
|
||||||
|
])
|
||||||
|
self.clear()
|
||||||
|
self.play(
|
||||||
|
ShowCreation(freq_line),
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
ShimmerIn(words),
|
||||||
|
*[
|
||||||
|
Transform(
|
||||||
|
dot,
|
||||||
|
dot.copy().scale(2).rotate(-np.pi/2).shift(floor),
|
||||||
|
interpolation_function = path_along_arc(np.pi/3)
|
||||||
|
)
|
||||||
|
for dot in dots
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.dither(0.5)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -500,6 +500,7 @@ class Mobject1D(Mobject):
|
|||||||
|
|
||||||
|
|
||||||
def add_line(self, start, end, color = None):
|
def add_line(self, start, end, color = None):
|
||||||
|
start, end = map(np.array, [start, end])
|
||||||
length = np.linalg.norm(end - start)
|
length = np.linalg.norm(end - start)
|
||||||
if length == 0:
|
if length == 0:
|
||||||
points = [start]
|
points = [start]
|
||||||
|
@ -209,7 +209,7 @@ class DrawComplexAngleAndMagnitude(Scene):
|
|||||||
|
|
||||||
|
|
||||||
def add_angle_label(self, number):
|
def add_angle_label(self, number):
|
||||||
arc = PartialCircle(
|
arc = Arc(
|
||||||
np.log(number).imag,
|
np.log(number).imag,
|
||||||
radius = 0.2
|
radius = 0.2
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,11 @@ class Cross(Mobject1D):
|
|||||||
|
|
||||||
|
|
||||||
class Line(Mobject1D):
|
class Line(Mobject1D):
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
"buffer" : 0
|
||||||
|
}
|
||||||
def __init__(self, start, end, **kwargs):
|
def __init__(self, start, end, **kwargs):
|
||||||
|
digest_config(self, kwargs)
|
||||||
self.set_start_and_end(start, end)
|
self.set_start_and_end(start, end)
|
||||||
Mobject1D.__init__(self, **kwargs)
|
Mobject1D.__init__(self, **kwargs)
|
||||||
|
|
||||||
@ -58,6 +62,10 @@ class Line(Mobject1D):
|
|||||||
else np.array(arg)
|
else np.array(arg)
|
||||||
for arg, unit in zip([start, end], [1, -1])
|
for arg, unit in zip([start, end], [1, -1])
|
||||||
]
|
]
|
||||||
|
start_to_end = self.end - self.start
|
||||||
|
start_to_end /= np.linalg.norm(start_to_end)
|
||||||
|
self.start += self.buffer*start_to_end
|
||||||
|
self.end += self.buffer*(-start_to_end)
|
||||||
|
|
||||||
def generate_points(self):
|
def generate_points(self):
|
||||||
self.add_line(self.start, self.end)
|
self.add_line(self.start, self.end)
|
||||||
@ -75,7 +83,8 @@ class Line(Mobject1D):
|
|||||||
class Arrow(Line):
|
class Arrow(Line):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"color" : WHITE,
|
"color" : WHITE,
|
||||||
"tip_length" : 0.25
|
"tip_length" : 0.25,
|
||||||
|
"buffer" : 0.3,
|
||||||
}
|
}
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
Line.__init__(self, *args, **kwargs)
|
Line.__init__(self, *args, **kwargs)
|
||||||
@ -127,8 +136,7 @@ class CurvedLine(Line):
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class Arc(Mobject1D):
|
||||||
class PartialCircle(Mobject1D):
|
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"radius" : 1.0,
|
"radius" : 1.0,
|
||||||
"start_angle" : 0,
|
"start_angle" : 0,
|
||||||
@ -148,12 +156,12 @@ class PartialCircle(Mobject1D):
|
|||||||
)
|
)
|
||||||
])
|
])
|
||||||
|
|
||||||
class Circle(PartialCircle):
|
class Circle(Arc):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"color" : RED,
|
"color" : RED,
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
PartialCircle.__init__(self, angle = 2*np.pi, **kwargs)
|
Arc.__init__(self, angle = 2*np.pi, **kwargs)
|
||||||
|
|
||||||
class Polygon(Mobject1D):
|
class Polygon(Mobject1D):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
@ -180,12 +188,40 @@ class Polygon(Mobject1D):
|
|||||||
return self.points[self.indices_of_vertices]
|
return self.points[self.indices_of_vertices]
|
||||||
|
|
||||||
|
|
||||||
class Rectangle(Mobject1D):
|
|
||||||
|
class Grid(Mobject1D):
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
"height" : 6.0,
|
||||||
|
"width" : 6.0,
|
||||||
|
}
|
||||||
|
def __init__(self, rows, columns, **kwargs):
|
||||||
|
digest_config(self, kwargs, locals())
|
||||||
|
Mobject1D.__init__(self, **kwargs)
|
||||||
|
|
||||||
|
def generate_points(self):
|
||||||
|
x_step = self.width / self.columns
|
||||||
|
y_step = self.height / self.rows
|
||||||
|
|
||||||
|
for x in np.arange(0, self.width+x_step, x_step):
|
||||||
|
self.add_line(
|
||||||
|
[x-self.width/2., -self.height/2., 0],
|
||||||
|
[x-self.width/2., self.height/2., 0],
|
||||||
|
)
|
||||||
|
for y in np.arange(0, self.height+y_step, y_step):
|
||||||
|
self.add_line(
|
||||||
|
[-self.width/2., y-self.height/2., 0],
|
||||||
|
[self.width/2., y-self.height/2., 0]
|
||||||
|
)
|
||||||
|
|
||||||
|
class Rectangle(Grid):
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"color" : YELLOW,
|
"color" : YELLOW,
|
||||||
"height" : 2.0,
|
"height" : 2.0,
|
||||||
"width" : 4.0
|
"width" : 4.0,
|
||||||
}
|
}
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
Grid.__init__(self, 1, 1, **kwargs)
|
||||||
|
|
||||||
def generate_points(self):
|
def generate_points(self):
|
||||||
wh = [self.width/2.0, self.height/2.0]
|
wh = [self.width/2.0, self.height/2.0]
|
||||||
self.add_points([
|
self.add_points([
|
||||||
@ -209,4 +245,3 @@ class Square(Rectangle):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
from mobject import Mobject1D, TexMobject
|
from mobject import Mobject1D
|
||||||
|
from mobject.tex_mobject import TexMobject
|
||||||
from scene import Scene
|
from scene import Scene
|
||||||
|
|
||||||
class NumberLine(Mobject1D):
|
class NumberLine(Mobject1D):
|
||||||
|
Reference in New Issue
Block a user