More hilbert work, including simple new Grid mobject

This commit is contained in:
Grant Sanderson
2015-12-19 13:06:09 -08:00
parent 32fe2e9373
commit d5c70fe0cb
8 changed files with 109 additions and 21 deletions

View File

@ -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):

View File

@ -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)
################################################ ################################################

View File

@ -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):

View File

@ -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)

View File

@ -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]

View File

@ -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
) )

View File

@ -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):

View File

@ -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):