This commit is contained in:
ddxtanx 2017-11-22 19:06:23 -06:00
commit 80dda4eb28
20 changed files with 7962 additions and 4428 deletions

View file

@ -82,12 +82,10 @@ class Write(ShowCreation):
def establish_run_time(self, mobject):
num_subs = len(mobject.family_members_with_points())
if num_subs < 5:
if num_subs < 15:
self.run_time = 1
elif num_subs < 15:
self.run_time = 2
else:
self.run_time = 3
self.run_time = 2
class DrawBorderThenFill(Animation):
CONFIG = {
@ -330,9 +328,9 @@ class LaggedStart(Animation):
anim.update(alpha)
return self
# def clean_up(self, *args, **kwargs):
# for anim in self.subanimations:
# anim.clean_up(*args, **kwargs)
def clean_up(self, *args, **kwargs):
for anim in self.subanimations:
anim.clean_up(*args, **kwargs)
class DelayByOrder(Animation):
"""

View file

@ -59,7 +59,8 @@ class Transform(Animation):
Animation.clean_up(self, surrounding_scene)
if self.replace_mobject_with_target_in_scene and surrounding_scene is not None:
surrounding_scene.remove(self.mobject)
surrounding_scene.add(self.original_target_mobject)
if not self.remover:
surrounding_scene.add(self.original_target_mobject)
class ReplacementTransform(Transform):
CONFIG = {

View file

@ -141,15 +141,21 @@ class Camera(object):
def get_pen_and_fill(self, vmobject):
pen = aggdraw.Pen(
self.get_stroke_color(vmobject).get_hex_l(),
self.color_to_hex_l(self.get_stroke_color(vmobject)),
max(vmobject.stroke_width, 0)
)
fill = aggdraw.Brush(
self.get_fill_color(vmobject).get_hex_l(),
self.color_to_hex_l(self.get_fill_color(vmobject)),
opacity = int(255*vmobject.get_fill_opacity())
)
return (pen, fill)
def color_to_hex_l(self, color):
try:
return color.get_hex_l()
except:
return Color(BLACK).get_hex_l()
def get_stroke_color(self, vmobject):
return vmobject.get_stroke_color()

View file

@ -6,8 +6,7 @@ DEFAULT_WIDTH = 1920
LOW_QUALITY_FRAME_DURATION = 1./15
MEDIUM_QUALITY_FRAME_DURATION = 1./30
# PRODUCTION_QUALITY_FRAME_DURATION = 1./60
PRODUCTION_QUALITY_FRAME_DURATION = 1./30
PRODUCTION_QUALITY_FRAME_DURATION = 1./60
#There might be other configuration than pixel_shape later...
PRODUCTION_QUALITY_CAMERA_CONFIG = {

View file

@ -37,7 +37,6 @@ def play_chord(*nums):
def play_error_sound():
play_chord(11, 8, 6, 1)
def play_finish_sound():
play_chord(12, 9, 5, 2)
@ -422,7 +421,7 @@ def get_full_image_path(image_file_name):
for path in possible_paths:
if os.path.exists(path):
return path
raise IOError("File not Found")
raise IOError("File %s not Found"%image_file_name)
def drag_pixels(frames):
curr = frames[0]

View file

@ -399,11 +399,17 @@ class Mobject(object):
## Color functions
def highlight(self, color = YELLOW_C, family = True, condition = None):
def highlight(self, color = YELLOW_C, family = True):
"""
Condition is function which takes in one arguments, (x, y, z).
Here it just recurses to submobjects, but in subclasses this
should be further implemented based on the the inner workings
of color
"""
raise Exception("Not implemented")
if family:
for submob in self.submobjects:
submob.highlight(color, family = family)
return self
def gradient_highlight(self, *colors):
self.submobject_gradient_highlight(*colors)
@ -446,11 +452,14 @@ class Mobject(object):
return self.color
##
def save_state(self):
def save_state(self, use_deepcopy = False):
if hasattr(self, "saved_state"):
#Prevent exponential growth of data
self.saved_state = None
self.saved_state = self.copy()
if use_deepcopy:
self.saved_state = self.deepcopy()
else:
self.saved_state = self.copy()
return self
def restore(self):

View file

@ -30,15 +30,11 @@ class PMobject(Mobject):
self.rgbas = np.append(self.rgbas, rgbas, axis = 0)
return self
def highlight(self, color = YELLOW_C, family = True, condition = None):
def highlight(self, color = YELLOW_C, family = True):
rgba = color_to_rgba(color)
mobs = self.family_members_with_points() if family else [self]
for mob in mobs:
if condition:
to_change = np.apply_along_axis(condition, 1, mob.points)
mob.rgbas[to_change, :] = rgba
else:
mob.rgbas[:,:] = rgba
mob.rgbas[:,:] = rgba
return self
def gradient_highlight(self, start_color, end_color):

View file

@ -26,7 +26,6 @@ class TexSymbol(VMobjectFromSVGPathstring):
self.set_stroke(width = added_width + mobject.get_stroke_width())
self.set_fill(opacity = opacity)
class TexMobject(SVGMobject):
CONFIG = {
"template_tex_file" : TEMPLATE_TEX_FILE,
@ -264,6 +263,43 @@ class Brace(TexMobject):
vect = self.get_tip() - self.get_center()
return vect/np.linalg.norm(vect)
class BulletedList(TextMobject):
CONFIG = {
"buff" : MED_LARGE_BUFF,
"dot_scale_factor" : 2,
#Have to include because of handle_multiple_args implementation
"template_tex_file" : TEMPLATE_TEXT_FILE,
"alignment" : "",
}
def __init__(self, *items, **kwargs):
line_separated_items = [s + "\\\\" for s in items]
TextMobject.__init__(self, *line_separated_items, **kwargs)
for part in self:
dot = TexMobject("\\cdot").scale(self.dot_scale_factor)
dot.next_to(part[0], LEFT, SMALL_BUFF)
part.add_to_back(dot)
self.arrange_submobjects(
DOWN,
aligned_edge = LEFT,
buff = self.buff
)
def fade_all_but(self, index_or_string, opacity = 0.5):
arg = index_or_string
if isinstance(arg, str):
part = self.get_part_by_tex(arg)
elif isinstance(arg, int):
part = self.submobjects[arg]
else:
raise Exception("Expected int or string, got {0}".format(arg))
for other_part in self.submobjects:
if other_part is part:
other_part.set_fill(opacity = 1)
else:
other_part.set_fill(opacity = opacity)
##########
def tex_hash(expression, template_tex_file):
return str(hash(expression + template_tex_file))

View file

@ -97,13 +97,13 @@ class VMobject(Mobject):
def get_fill_color(self):
try:
self.fill_rgb = np.clip(self.fill_rgb, 0, 1)
self.fill_rgb = np.clip(self.fill_rgb, 0.0, 1.0)
return Color(rgb = self.fill_rgb)
except:
return Color(WHITE)
def get_fill_opacity(self):
return self.fill_opacity
return np.clip(self.fill_opacity, 0, 1)
def get_stroke_color(self):
try:
@ -113,7 +113,7 @@ class VMobject(Mobject):
return Color(WHITE)
def get_stroke_width(self):
return self.stroke_width
return max(0, self.stroke_width)
def get_color(self):
if self.fill_opacity == 0:

View file

@ -21,12 +21,12 @@ import cPickle
from nn.mnist_loader import load_data_wrapper
NN_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
# PRETRAINED_DATA_FILE = os.path.join(NN_DIRECTORY, "pretrained_weights_and_biases_36")
# PRETRAINED_DATA_FILE = os.path.join(NN_DIRECTORY, "pretrained_weights_and_biases_80")
# PRETRAINED_DATA_FILE = os.path.join(NN_DIRECTORY, "pretrained_weights_and_biases_ReLU")
PRETRAINED_DATA_FILE = os.path.join(NN_DIRECTORY, "pretrained_weights_and_biases")
IMAGE_MAP_DATA_FILE = os.path.join(NN_DIRECTORY, "image_map")
# PRETRAINED_DATA_FILE = "/Users/grant/cs/manim/nn/pretrained_weights_and_biases_on_zero"
# DEFAULT_LAYER_SIZES = [28**2, 36, 10]
# DEFAULT_LAYER_SIZES = [28**2, 80, 10]
DEFAULT_LAYER_SIZES = [28**2, 16, 16, 10]
class Network(object):

View file

@ -122,7 +122,7 @@ class NetworkMobject(VGroup):
"neuron_fill_color" : GREEN,
"edge_color" : LIGHT_GREY,
"edge_stroke_width" : 2,
"edge_propogation_color" : GREEN,
"edge_propogation_color" : YELLOW,
"edge_propogation_time" : 1,
"max_shown_neurons" : 16,
"brace_for_large_layers" : True,
@ -196,21 +196,28 @@ class NetworkMobject(VGroup):
for l1, l2 in zip(self.layers[:-1], self.layers[1:]):
edge_group = VGroup()
for n1, n2 in it.product(l1.neurons, l2.neurons):
edge = Line(
n1.get_center(),
n2.get_center(),
buff = self.neuron_radius,
stroke_color = self.edge_color,
stroke_width = self.edge_stroke_width,
)
edge = self.get_edge(n1, n2)
edge_group.add(edge)
n1.edges_out.add(edge)
n2.edges_in.add(edge)
self.edge_groups.add(edge_group)
self.add_to_back(self.edge_groups)
def get_edge(self, neuron1, neuron2):
return Line(
neuron1.get_center(),
neuron2.get_center(),
buff = self.neuron_radius,
stroke_color = self.edge_color,
stroke_width = self.edge_stroke_width,
)
def get_active_layer(self, layer_index, activation_vector):
layer = self.layers[layer_index].deepcopy()
self.activate_layer(layer, activation_vector)
return layer
def activate_layer(self, layer, activation_vector):
n_neurons = len(layer.neurons)
av = activation_vector
def arr_to_num(arr):
@ -238,6 +245,11 @@ class NetworkMobject(VGroup):
)
return layer
def activate_layers(self, input_vector):
activations = self.neural_network.get_activation_of_all_layers(input_vector)
for activation, layer in zip(activations, self.layers):
self.activate_layer(layer, activation)
def deactivate_layers(self):
all_neurons = VGroup(*it.chain(*[
layer.neurons
@ -2980,6 +2992,7 @@ class ContinualEdgeUpdate(ContinualAnimation):
"max_stroke_width" : 3,
"stroke_width_exp" : 7,
"n_cycles" : 5,
"colors" : [GREEN, GREEN, GREEN, RED],
}
def __init__(self, network_mob, **kwargs):
digest_config(self, kwargs)
@ -2988,7 +3001,7 @@ class ContinualEdgeUpdate(ContinualAnimation):
self.move_to_targets = []
for edge in edges:
edge.colors = [
random.choice([GREEN, GREEN, GREEN, RED])
random.choice(self.colors)
for x in range(n_cycles)
]
msw = self.max_stroke_width

File diff suppressed because it is too large Load diff

4519
nn/part3.py Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -61,6 +61,10 @@ class Scene(object):
"""
pass
def setup_bases(self):
for base in self.__class__.__bases__:
base.setup(self)
def construct(self):
pass #To be implemented in subclasses
@ -71,20 +75,24 @@ class Scene(object):
self.name = name
return self
def update_shared_locals(self, *keys):
def set_variables_as_attrs(self, *objects, **newly_named_objects):
"""
Often in constructing a scene, it's nice to refer to
what was a local variable from a previous subroutine,
so a dict of shared_locals is recorded, and it can be updated
by passing in the objects directly.
This method is slightly hacky, making it a little easier
for certain methods (typically subroutines of construct)
to share local variables.
"""
caller_locals = inspect.currentframe().f_back.f_locals
self.shared_locals.update(dict([
(key, caller_locals[key])
for key in keys
]))
for key, value in caller_locals.items():
for o in objects:
if value is o:
setattr(self, key, value)
for key, value in newly_named_objects.items():
setattr(self, key, value)
return self
def get_attrs(self, *keys):
return [getattr(self, key) for key in keys]
### Only these methods should touch the camera
def set_camera(self, camera):
@ -341,7 +349,7 @@ class Scene(object):
animations.pop()
#method should already have target then.
else:
mobject.target = mobject.deepcopy()
mobject.target = mobject.copy()
state["curr_method"].im_func(
mobject.target, *state["method_args"]
)
@ -479,14 +487,14 @@ class Scene(object):
command = [
FFMPEG_BIN,
'-y', # overwrite output file if it exists
'-y', # overwrite output file if it exists
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-s', '%dx%d'%(width, height), # size of one frame
'-pix_fmt', 'rgba',
'-r', str(fps), # frames per second
'-i', '-', # The imput comes from a pipe
'-an', # Tells FFMPEG not to expect any audio
'-i', '-', # The imput comes from a pipe
'-an', # Tells FFMPEG not to expect any audio
'-vcodec', 'mpeg',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',

View file

@ -276,7 +276,7 @@ class Eyes(VMobject):
pi = Randolph(mode = mode)
eyes = VGroup(pi.eyes, pi.pupils)
eyes.scale_to_fit_height(self.height)
pi.scale(self.height/eyes.get_height())
if self.submobjects:
eyes.move_to(self, DOWN)
else:
@ -526,18 +526,17 @@ class PiCreatureScene(Scene):
lambda anim : pi_creature in anim.mobject.submobject_family(),
animations
)
if anims_with_pi_creature:
for anim in anims_with_pi_creature:
if isinstance(anim, Transform):
index = anim.mobject.submobject_family().index(pi_creature)
target_family = anim.target_mobject.submobject_family()
target = target_family[index]
if isinstance(target, PiCreature):
target.look_at(point_of_interest)
continue
animations.append(
ApplyMethod(pi_creature.look_at, point_of_interest)
)
for anim in anims_with_pi_creature:
if isinstance(anim, Transform):
index = anim.mobject.submobject_family().index(pi_creature)
target_family = anim.target_mobject.submobject_family()
target = target_family[index]
if isinstance(target, PiCreature):
target.look_at(point_of_interest)
if not anims_with_pi_creature:
animations.append(
ApplyMethod(pi_creature.look_at, point_of_interest)
)
return animations
def blink(self):

View file

@ -61,36 +61,7 @@ class OpeningQuote(Scene):
class PatreonThanks(Scene):
CONFIG = {
"specific_patrons" : [
"Ali Yahya",
"Meshal Alshammari",
"CrypticSwarm ",
"Justin Helps",
"Ankit Agarwal",
"Yu Jun",
"Shelby Doolittle",
"Dave Nicponski",
"Damion Kistler",
"Juan Benet",
"Othman Alikhan",
"Markus Persson",
"Dan Buchoff",
"Derek Dai",
"Joseph John Cox",
"Luc Ritchie",
"Nils Schneider",
"Mathew Bramson",
"Guido Gambardella",
"Jerry Ling",
"Mark Govea",
"Vecht",
"Shimin Kuang",
"Rish Kundalia",
"Achille Brighton",
"Kirk Werklund",
"Ripta Pasay",
"Felipe Diniz",
],
"specific_patrons" : [],
"max_patron_group_size" : 20,
"patron_scale_val" : 0.8,

View file

@ -155,6 +155,7 @@ class Line(VMobject):
def put_start_and_end_on(self, new_start, new_end):
self.start = new_start
self.end = new_end
self.buff = 0
self.generate_points()
return
@ -242,9 +243,13 @@ class Arrow(Line):
if len(args) == 1:
args = (points[0]+UP+LEFT, points[0])
Line.__init__(self, *args, **kwargs)
self.add_tip()
self.init_tip()
if self.use_rectangular_stem and not hasattr(self, "rect"):
self.add_rectangular_stem()
self.init_colors()
def init_tip(self):
self.tip = self.add_tip()
def add_tip(self, add_at_end = True):
tip = VMobject(
@ -253,11 +258,11 @@ class Arrow(Line):
fill_color = self.color,
fill_opacity = 1,
stroke_color = self.color,
stroke_width = 0,
)
self.set_tip_points(tip, add_at_end, preserve_normal = False)
self.tip = tip
self.add(self.tip)
self.init_colors()
self.add(tip)
return tip
def add_rectangular_stem(self):
self.rect = Rectangle(
@ -283,6 +288,10 @@ class Arrow(Line):
self.rectangular_stem_width,
self.max_stem_width_to_tip_width_ratio*tip_base_width,
)
if hasattr(self, "second_tip"):
start = center_of_mass(
self.second_tip.get_anchors()[1:]
)
self.rect.set_points_as_corners([
tip_base + perp_vect*width/2,
start + perp_vect*width/2,
@ -310,7 +319,7 @@ class Arrow(Line):
indices = (-2, -1) if add_at_end else (1, 0)
pre_end_point, end_point = [
self.points[index]
self.get_anchors()[index]
for index in indices
]
vect = end_point - pre_end_point
@ -319,7 +328,6 @@ class Arrow(Line):
if np.linalg.norm(v) == 0:
v[0] = 1
v *= tip_length/np.linalg.norm(v)
ratio = self.tip_width_to_length_ratio
tip.set_points_as_corners([
end_point,
@ -360,7 +368,8 @@ class Arrow(Line):
Line.scale(self, scale_factor, **kwargs)
if self.preserve_tip_size_when_scaling:
self.set_tip_points(self.tip)
self.set_rectangular_stem_points()
if self.use_rectangular_stem:
self.set_rectangular_stem_points()
return self
class Vector(Arrow):
@ -374,9 +383,9 @@ class Vector(Arrow):
Arrow.__init__(self, ORIGIN, direction, **kwargs)
class DoubleArrow(Arrow):
def __init__(self, *args, **kwargs):
Arrow.__init__(self, *args, **kwargs)
self.add_tip(add_at_end = False)
def init_tip(self):
self.tip = self.add_tip()
self.second_tip = self.add_tip(add_at_end = False)
class CubicBezier(VMobject):
def __init__(self, points, **kwargs):

View file

@ -11,9 +11,9 @@ class DecimalNumber(VMobject):
"num_decimal_points" : 2,
"digit_to_digit_buff" : 0.05
}
def __init__(self, float_num, **kwargs):
digest_config(self, kwargs)
num_string = '%.*f'%(self.num_decimal_points, float_num)
def __init__(self, number, **kwargs):
digest_config(self, kwargs, locals())
num_string = '%.*f'%(self.num_decimal_points, number)
VMobject.__init__(self, *[
TexMobject(char)
for char in num_string
@ -22,7 +22,7 @@ class DecimalNumber(VMobject):
buff = self.digit_to_digit_buff,
aligned_edge = DOWN
)
if float_num < 0:
if number < 0:
minus = self.submobjects[0]
minus.next_to(
self.submobjects[1], LEFT,
@ -46,13 +46,15 @@ class Integer(VGroup):
class ChangingDecimal(Animation):
CONFIG = {
"num_decimal_points" : 2,
"num_decimal_points" : None,
"spare_parts" : 2,
"position_update_func" : None,
"tracked_mobject" : None,
}
def __init__(self, decimal_number, number_update_func, **kwargs):
digest_config(self, kwargs, locals())
if self.num_decimal_points is None:
self.num_decimal_points = decimal_number.num_decimal_points
decimal_number.add(*[
VectorizedPoint(decimal_number.get_corner(DOWN+LEFT))
for x in range(self.spare_parts)]
@ -65,9 +67,9 @@ class ChangingDecimal(Animation):
def update_number(self, alpha):
decimal = self.decimal_number
new_number = self.number_update_func(alpha)
new_decimal = DecimalNumber(
self.number_update_func(alpha),
num_decimal_points = self.num_decimal_points
new_number, num_decimal_points = self.num_decimal_points
)
new_decimal.replace(decimal, dim_to_match = 1)
new_decimal.highlight(decimal.get_color())
@ -78,6 +80,7 @@ class ChangingDecimal(Animation):
]
for sm1, sm2 in zip(*families):
sm1.interpolate(sm1, sm2, 1)
self.mobject.number = new_number
def update_position(self):
if self.position_update_func is not None: