Files
manim/mobject/creatures.py
2015-06-19 08:31:02 -07:00

136 lines
4.1 KiB
Python

import numpy as np
import itertools as it
import os
from image_mobject import *
from mobject import *
from simple_mobjects import *
class PiCreature(Mobject):
DEFAULT_COLOR = "blue"
def __init__(self, color = DEFAULT_COLOR, **kwargs):
Mobject.__init__(self, color = color, **kwargs)
scale_val = 0.5
mouth_to_eyes_distance = 0.25
part_names = [
'arm',
'body',
'left_eye',
'right_eye',
'left_leg',
'right_leg',
'mouth',
]
white_part_names = ['left_eye', 'right_eye', 'mouth']
directory = os.path.join(IMAGE_DIR, "PiCreature")
parts = []
self.white_parts = []
for part_name in part_names:
path = os.path.join(directory, "pi_creature_"+part_name)
path += ".png"
mob = ImageMobject(path)
mob.scale(scale_val)
if part_name in white_part_names:
self.white_parts.append(mob)
else:
mob.highlight(color)
setattr(self, part_name, mob)
parts.append(mob)
self.mouth.center().shift(
self.left_eye.get_center()/2 +
self.right_eye.get_center()/2 -
(0, mouth_to_eyes_distance, 0)
)
for part in parts:
self.add(part)
self.parts = parts
def rewire_part_attributes(self, self_from_parts = False):
if self_from_parts:
total_num_points = sum(map(Mobject.get_num_points, self.parts))
self.points = np.zeros((total_num_points, Mobject.DIM))
self.rgbs = np.zeros((total_num_points, Mobject.DIM))
curr = 0
for part in self.parts:
n_points = part.get_num_points()
if self_from_parts:
self.points[curr:curr+n_points,:] = part.points
self.rgbs[curr:curr+n_points,:] = part.rgbs
else:
part.points = self.points[curr:curr+n_points,:]
part.rgbs = self.rgbs[curr:curr+n_points,:]
curr += n_points
def highlight(self, color):
for part in set(self.parts).difference(self.white_parts):
part.highlight(color)
self.rewire_part_attributes(self_from_parts = True)
return self
def move_to(self, destination):
bottom = np.array((
np.mean(self.points[:,0]),
min(self.points[:,1]),
0
))
self.shift(destination-bottom)
return self
def give_frown(self):
center = self.mouth.get_center()
self.mouth.center()
self.mouth.apply_function(lambda (x, y, z) : (x, -y, z))
self.mouth.shift(center)
self.rewire_part_attributes(self_from_parts = True)
return self
def give_straight_face(self):
center = self.mouth.get_center()
self.mouth.center()
new_mouth = tex_mobject("-").scale(0.5)
new_mouth.center().shift(self.mouth.get_center())
new_mouth.shift(center)
self.parts[self.parts.index(self.mouth)] = new_mouth
self.white_parts[self.white_parts.index(self.mouth)] = new_mouth
self.mouth = new_mouth
self.rewire_part_attributes(self_from_parts = True)
return self
def get_step_intermediate(self, pi_creature):
vect = pi_creature.get_center() - self.get_center()
result = deepcopy(self).shift(vect / 2.0)
result.rewire_part_attributes()
if vect[0] < 0:
result.right_leg.wag(-vect/2.0, DOWN)
result.left_leg.wag(vect/2.0, DOWN)
else:
result.left_leg.wag(-vect/2.0, DOWN)
result.right_leg.wag(vect/2.0, DOWN)
return result
class Randolph(PiCreature):
pass #Nothing more than an alternative name
class Mortimer(PiCreature):
def __init__(self, *args, **kwargs):
PiCreature.__init__(self, *args, **kwargs)
self.highlight(DARK_BROWN)
self.give_straight_face()
self.rotate(np.pi, UP)
self.rewire_part_attributes()