mirror of
https://github.com/3b1b/manim.git
synced 2026-04-26 03:00:23 -04:00
Random changes during starty of inventing math
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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 ###
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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":
|
||||
|
||||
Reference in New Issue
Block a user