Random changes during starty of inventing math

This commit is contained in:
Grant Sanderson
2015-08-01 11:34:33 -07:00
parent 400aa0aada
commit 89a84134e4
10 changed files with 151 additions and 69 deletions

View File

@@ -12,7 +12,7 @@ class Rotating(Animation):
def __init__(self,
mobject,
axis = None,
axes = [[0, 0, 1], [0, 1, 0]],
axes = [RIGHT, UP],
radians = 2 * np.pi,
run_time = 20.0,
alpha_func = None,
@@ -35,7 +35,7 @@ class Rotating(Animation):
)
class RotationAsTransform(Rotating):
def __init__(self, mobject, radians, axis = (0, 0, 1), axes = None,
def __init__(self, mobject, radians, axis = IN, axes = None,
run_time = DEFAULT_ANIMATION_RUN_TIME,
alpha_func = high_inflection_0_to_1,
*args, **kwargs):

View File

@@ -119,7 +119,7 @@ class ApplyMethod(Transform):
)
class ApplyFunction(Transform):
def __init__(self, function, mobject, run_time = DEFAULT_ANIMATION_RUN_TIME,
def __init__(self, mobject, function, run_time = DEFAULT_ANIMATION_RUN_TIME,
*args, **kwargs):
map_image = copy.deepcopy(mobject)
map_image.points = np.array(map(function, map_image.points))

View File

@@ -49,10 +49,10 @@ def paint_mobject(mobject, image_array = None):
#Flips y-axis
points[:,1] *= -1
#Removes points out of space
points = points[
(abs(points[:,0]) < SPACE_WIDTH) &
(abs(points[:,1]) < SPACE_HEIGHT)
]
to_remove = (abs(points[:,0]) < SPACE_WIDTH) & \
(abs(points[:,1]) < SPACE_HEIGHT)
points = points[to_remove]
rgbs = rgbs[to_remove]
#Map points to pixel space, then create pixel array first in terms
#of its flattened version
try:

View File

@@ -116,10 +116,10 @@ def high_inflection_0_to_1(t, inflection = 10.0):
return (sigmoid(inflection*(t - 0.5)) - error) / (1 - 2*error)
def rush_into(t):
return 2*high_inflection_0_to_1(t/2)
return 2*high_inflection_0_to_1(t/2.0)
def rush_from(t):
return 2*high_inflection_0_to_1(t/2+0.5) - 1
return 2*high_inflection_0_to_1(t/2.0+0.5) - 1
def there_and_back(t, inflection = 10.0):
new_t = 2*t if t < 0.5 else 2*(1 - t)

View File

@@ -18,7 +18,7 @@ class PiCreature(Mobject):
'arm',
'body',
'left_eye',
'right_eye',
'right_eye',
'left_leg',
'right_leg',
'mouth',
@@ -70,6 +70,7 @@ class PiCreature(Mobject):
self.rewire_part_attributes(self_from_parts = True)
def highlight(self, color, condition = None):
self.rewire_part_attributes()
if condition is not None:
Mobject.highlight(self, color, condition)
return self

View File

@@ -2,6 +2,7 @@ import numpy as np
import itertools as it
from mobject import Mobject, Mobject1D, Mobject2D, CompoundMobject
from image_mobject import tex_mobject
from constants import *
from helpers import *
@@ -91,10 +92,10 @@ class Grid(Mobject1D):
class NumberLine(Mobject1D):
def __init__(self,
radius = SPACE_WIDTH,
radius = SPACE_WIDTH+1,
interval_size = 0.5, tick_size = 0.1,
*args, **kwargs):
self.radius = int(radius) + 1
self.radius = int(radius)
self.interval_size = interval_size
self.tick_size = tick_size
Mobject1D.__init__(self, *args, **kwargs)
@@ -104,15 +105,34 @@ class NumberLine(Mobject1D):
(x, 0, 0)
for x in np.arange(-self.radius, self.radius, self.epsilon)
])
self.add_points([
(0, y, 0)
for y in np.arange(-2*self.tick_size, 2*self.tick_size, self.epsilon)
])
self.add_points([
(x, y, 0)
for x in np.arange(-self.radius, self.radius, self.interval_size)
for y in np.arange(-self.tick_size, self.tick_size, self.epsilon)
])
self.elongate_tick_at(0)
def elongate_tick_at(self, x, multiple = 2):
self.add_points([
[x, y, 0]
for y in np.arange(
-multiple*self.tick_size,
multiple*self.tick_size,
self.epsilon
)
])
return self
def add_numbers(self, intervals_per_number = 2):
max_val = int(self.radius/self.interval_size/intervals_per_number)
for x in range(-max_val, max_val+1):
num = tex_mobject(str(x)).scale(0.5)
num.shift(
DOWN*4*self.tick_size + \
RIGHT*x*self.interval_size*intervals_per_number
)
self.add(num)
return self
class Axes(CompoundMobject):
def __init__(self, *args, **kwargs):

View File

@@ -66,50 +66,6 @@ class ImageMobject(Mobject2D):
# potentially changed in subclasses
return False
class SpeechBubble(ImageMobject):
def __init__(self, direction = LEFT, *args, **kwargs):
ImageMobject.__init__(self, "speech_bubble", *args, **kwargs)
self.direction = direction
self.scale(0.4)
self.center()
if direction[0] > 0:
self.rotate(np.pi, UP)
self.reload_tip()
def reload_tip(self):
#TODO, perhaps make this resiliant to different point orderings
self.tip = self.points[-1]
def speak_from(self, mobject):
dest = mobject.get_center()
dest += self.direction * mobject.get_width()/2
dest += UP * mobject.get_height()/2
self.shift(dest - self.tip)
self.reload_tip()
return self
def write(self, text):
smidgeon = 0.1*UP + 0.2*self.direction
self.clear()
self.text = text_mobject(text)
self.text.scale(0.75*self.get_width() / self.text.get_width())
self.text.shift(self.get_center() + smidgeon)
self.add(self.text)
def clear(self):
if not hasattr(self, "text"):
return
num_text_points = self.text.points.shape[0]
self.points = self.points[:num_text_points]
self.rgbs = self.rgbs[:num_text_points]
self.text = Mobject()
class ThoughtBubble(ImageMobject):
def __init__(self, *args, **kwargs):
ImageMobject.__init__(self, "thought_bubble", *args, **kwargs)
self.scale(0.5)
self.center()
class Face(ImageMobject):
def __init__(self, mode = "simple", *args, **kwargs):
"""

View File

@@ -26,6 +26,7 @@ class Mobject(object):
color = None,
name = None,
center = None,
**kwargs
):
self.color = Color(color) if color else Color(self.DEFAULT_COLOR)
if not hasattr(self, "name"):
@@ -64,7 +65,8 @@ class Mobject(object):
else:
if rgbs.shape != points.shape:
raise Exception("points and rgbs must have same shape")
self.rgbs = np.append(self.rgbs, rgbs).reshape(self.points.shape)
self.rgbs = np.append(self.rgbs, rgbs)
self.rgbs = self.rgbs.reshape((self.rgbs.size / 3, 3))
if self.has_normals:
self.unit_normals = np.append(
self.unit_normals,
@@ -111,7 +113,7 @@ class Mobject(object):
self.shift(-self.get_center())
return self
#To wrapper functions for better naming
#Wrapper functions for better naming
def to_corner(self, corner = (-1, 1, 0), buff = 0.5):
return self.align_on_border(corner, buff)
@@ -144,6 +146,20 @@ class Mobject(object):
center = self.get_center()
return self.center().scale(scale_factor).shift(center)
def stretch_to_fit(self, length, dim):
center = self.get_center()
old_length = max(self.points[:,dim]) - min(self.points[:,dim])
self.center()
self.points[:,dim] *= length/old_length
self.shift(center)
return self
def stretch_to_fit_width(self, width):
return self.stretch_to_fit(width, 0)
def stretch_to_fit_height(self, height):
return self.stretch_to_fit(height, 1)
def add(self, *mobjects):
for mobject in mobjects:
self.add_points(mobject.points, mobject.rgbs)
@@ -161,6 +177,11 @@ class Mobject(object):
self.rotate(np.pi / 7, [1, 0, 0])
return self
def replace(self, other_mobject):
self.scale(other_mobject.get_width()/self.get_width())
self.center().shift(other_mobject.get_center())
return self
def apply_function(self, function):
self.points = np.apply_along_axis(function, 1, self.points)
return self
@@ -201,6 +222,7 @@ class Mobject(object):
self.points,
lambda *points : cmp(*map(function, points))
))
return self
### Getters ###

View File

@@ -13,10 +13,15 @@ class Point(Mobject):
class Arrow(Mobject1D):
DEFAULT_COLOR = "white"
NUNGE_DISTANCE = 0.1
def __init__(self, point = (0, 0, 0), direction = (-1, 1, 0),
tail = None, length = 1, tip_length = 0.25,
normal = (0, 0, 1), *args, **kwargs):
DEFAULT_NUDGE_DISTANCE = 0.1
def __init__(self,
point = (0, 0, 0),
direction = (-1, 1, 0),
tail = None,
length = 1,
tip_length = 0.25,
normal = (0, 0, 1),
*args, **kwargs):
self.point = np.array(point)
if tail is not None:
direction = self.point - tail
@@ -41,8 +46,10 @@ class Arrow(Mobject1D):
for i in [0, 1]
])
def nudge(self):
return self.shift(-self.direction * self.NUNGE_DISTANCE)
def nudge(self, distance = None):
if distance is None:
distance = self.DEFAULT_NUDGE_DISTANCE
return self.shift(-self.direction * distance)
class Vector(Arrow):
def __init__(self, point = (1, 0, 0), *args, **kwargs):
@@ -131,6 +138,82 @@ class Circle(Mobject1D):
])
class Bubble(Mobject):
def __init__(self, direction = LEFT, index_of_tip = -1, center = ORIGIN):
self.direction = direction
self.content = Mobject()
self.index_of_tip = index_of_tip
self.center_offset = center - Mobject.get_center(self)
if direction[0] > 0:
self.rotate(np.pi, UP)
def get_tip(self):
return self.points[self.index_of_tip]
def get_bubble_center(self):
return Mobject.get_center(self)+self.center_offset
def move_tip_to(self, point):
self.shift(point - self.get_tip())
return self
def pin_to(self, mobject):
self.move_tip_to(sum([
mobject.get_center(),
-self.direction * mobject.get_width()/2,
UP * mobject.get_height()/2,
]))
return self
def add_content(self, mobject):
mobject.scale(0.75*self.get_width() / mobject.get_width())
mobject.shift(self.get_bubble_center())
self.content = CompoundMobject(self.content, mobject)
self.add(self.content)
return self
def write(self, text):
self.add_content(text_mobject(text))
return self
def clear(self):
num_content_points = self.content.points.shape[0]
self.points = self.points[:-num_content_points]
self.rgbs = self.rgbs[:-num_content_points]
self.contents = Mobject()
return self
class SpeechBubble(Bubble):
def __init__(self, *args, **kwargs):
#TODO
pass
class ThoughtBubble(Bubble):
NUM_BULGES = 7
INITIAL_INNER_RADIUS = 1.8
INITIAL_WIDTH = 6
def __init__(self, *args, **kwargs):
Mobject.__init__(self, *args, **kwargs)
self.add(Circle().scale(0.15).shift(2.5*DOWN+2*LEFT))
self.add(Circle().scale(0.3).shift(2*DOWN+1.5*LEFT))
for n in range(self.NUM_BULGES):
theta = 2*np.pi*n/self.NUM_BULGES
self.add(Circle().shift((np.cos(theta), np.sin(theta), 0)))
self.filter_out(lambda p : np.linalg.norm(p) < self.INITIAL_INNER_RADIUS)
self.stretch_to_fit_width(self.INITIAL_WIDTH)
self.highlight("white")
Bubble.__init__(
self,
index_of_tip = np.argmin(self.points[:,1]),
**kwargs
)

View File

@@ -108,7 +108,7 @@ def command_line_create_scene(movie_prefix = ""):
print "Constructing %s..."%name
scene = SceneClass(*args, display_config = display_config)
if action == "write":
scene.write_to_movie(movie_prefix + name)
scene.write_to_movie(os.path.join(movie_prefix, name))
elif action == "preview":
scene.preview()
elif action == "save_image":