Merge pull request #271 from 3b1b/simple-improvements

Simple improvements
This commit is contained in:
Grant Sanderson
2018-08-20 15:52:20 -07:00
committed by GitHub
10 changed files with 89 additions and 52 deletions

View File

@@ -49,7 +49,6 @@ class Camera(object):
"image_mode": "RGBA",
"n_channels": 4,
"pixel_array_dtype": 'uint8',
"use_z_coordinate_for_display_order": False,
# z_buff_func is only used if the flag above is set to True.
# round z coordinate to nearest hundredth when comparring
"z_buff_func": lambda m: np.round(m.get_center()[2], 2),
@@ -231,16 +230,7 @@ class Camera(object):
excluded_mobjects
)
mobjects = list_difference_update(mobjects, all_excluded)
if self.use_z_coordinate_for_display_order:
# Should perhaps think about what happens here when include_submobjects is False,
# (for now, the onus is then on the caller to ensure this is handled correctly by
# passing us an appropriately pre-flattened list of mobjects if need be)
return sorted(
mobjects,
lambda a, b: cmp(self.z_buff_func(a), self.z_buff_func(b))
)
else:
return mobjects
return mobjects
def is_in_frame(self, mobject):
fc = self.get_frame_center()

View File

@@ -11,6 +11,7 @@ from mobject.number_line import NumberLine
from mobject.svg.tex_mobject import TexMobject
from mobject.types.vectorized_mobject import VGroup
from mobject.types.vectorized_mobject import VMobject
from mobject.three_dimensions import ThreeDVMobject
from utils.config_ops import digest_config
from utils.space_ops import angle_of_vector
@@ -29,14 +30,10 @@ class Axes(VGroup):
"y_axis_config": {
"label_direction": LEFT,
},
"z_axis_config": {},
"x_min": -FRAME_X_RADIUS,
"x_max": FRAME_X_RADIUS,
"y_min": -FRAME_Y_RADIUS,
"y_max": FRAME_Y_RADIUS,
"z_min": -3.5,
"z_max": 3.5,
"z_normal": DOWN,
"default_num_graph_points": 100,
}
@@ -46,15 +43,6 @@ class Axes(VGroup):
self.y_axis = self.get_axis(self.y_min, self.y_max, self.y_axis_config)
self.y_axis.rotate(np.pi / 2, about_point=ORIGIN)
self.add(self.x_axis, self.y_axis)
if self.three_d:
self.z_axis = self.get_axis(
self.z_min, self.z_max, self.z_axis_config)
self.z_axis.rotate(-np.pi / 2, UP, about_point=ORIGIN)
self.z_axis.rotate(
angle_of_vector(self.z_normal), OUT,
about_point=ORIGIN
)
self.add(self.z_axis)
def get_axis(self, min_val, max_val, extra_config):
config = dict(self.number_line_config)
@@ -68,10 +56,10 @@ class Axes(VGroup):
return x_axis_projection + y_axis_projection - origin
def point_to_coords(self, point):
return (
self.x_axis.point_to_number(point),
self.y_axis.point_to_number(point),
)
return tuple([
axis.point_to_number(point)
for axis in self
])
def get_graph(
self, function, num_graph_points=None,
@@ -123,11 +111,56 @@ class ThreeDAxes(Axes):
CONFIG = {
"x_min": -5.5,
"x_max": 5.5,
"y_min": -4.5,
"y_max": 4.5,
"three_d": True,
"y_min": -5.5,
"y_max": 5.5,
"z_axis_config": {},
"z_min": -3.5,
"z_max": 3.5,
"z_normal": DOWN,
"num_axis_pieces": 20,
"light_source": 9 * DOWN + 7 * LEFT + 10 * OUT,
}
def __init__(self, **kwargs):
Axes.__init__(self, **kwargs)
z_axis = self.z_axis = self.get_axis(
self.z_min, self.z_max, self.z_axis_config
)
z_axis.rotate(-np.pi / 2, UP, about_point=ORIGIN)
z_axis.rotate(
angle_of_vector(self.z_normal), OUT,
about_point=ORIGIN
)
self.add(z_axis)
self.add_3d_pieces()
self.set_axis_shading()
def add_3d_pieces(self):
for attr in "x_axis", "y_axis", "z_axis":
axis = getattr(self, attr)
axis.add(VGroup(
*axis.main_line.get_pieces(self.num_axis_pieces)
))
axis.main_line.set_stroke(width=0, family=False)
axis_3d = ThreeDVMobject(axis)
self.remove(axis)
self.add(axis_3d)
setattr(self, attr, axis_3d)
def set_axis_shading(self):
def make_func(axis):
vect = self.light_source
return lambda: (
axis.get_edge_center(-vect),
axis.get_edge_center(vect),
)
for axis in self:
for submob in axis.family_members_with_points():
submob.get_gradient_start_and_end_points = make_func(axis)
submob.get_unit_normal = lambda a: np.ones(3)
submob.set_sheen(0.2)
class NumberPlane(VMobject):
CONFIG = {

View File

@@ -47,14 +47,14 @@ class Mobject(Container):
if self.name is None:
self.name = self.__class__.__name__
self.updaters = []
self.init_points()
self.reset_points()
self.generate_points()
self.init_colors()
def __str__(self):
return str(self.name)
def init_points(self):
def reset_points(self):
self.points = np.zeros((0, self.dim))
def init_colors(self):
@@ -773,6 +773,17 @@ class Mobject(Container):
def point_from_proportion(self, alpha):
raise Exception("Not implemented")
def get_pieces(self, n_pieces):
template = self.copy()
template.submobjects = []
alphas = np.linspace(0, 1, n_pieces + 1)
return Group(*[
template.copy().pointwise_become_partial(
self, a1, a2
)
for a1, a2 in zip(alphas[:-1], alphas[1:])
])
# Family matters
def __getitem__(self, value):
@@ -909,7 +920,7 @@ class Mobject(Container):
def push_self_into_submobjects(self):
copy = self.copy()
copy.submobjects = []
self.init_points()
self.reset_points()
self.add(copy)
return self

View File

@@ -145,6 +145,7 @@ class NumberLine(VMobject):
vect = (end - start) / get_norm(end - start)
arrow = Arrow(start, end + MED_SMALL_BUFF * vect, buff=0)
tip = arrow.tip
tip.set_stroke(width=self.get_stroke_width())
tip.set_color(self.color)
self.tip = tip
self.add(tip)

View File

@@ -21,10 +21,11 @@ class ThreeDVMobject(VMobject):
VMobject.__init__(self, **kwargs)
if vmobject is not None:
self.points = np.array(vmobject.points)
self.match_style(vmobject)
self.submobjects = map(
ThreeDVMobject, vmobject.submobjects
)
self.match_style(vmobject, family=False)
self.submobjects = [
ThreeDVMobject(submob, **kwargs)
for submob in vmobject.submobjects
]
def get_gradient_start_and_end_points(self):
return self.get_start_corner(), self.get_end_corner()

View File

@@ -30,7 +30,7 @@ class AbstractImageMobject(Mobject):
# Likely to be implemented in subclasses, but no obgligation
pass
def init_points(self):
def reset_points(self):
# Corresponding corners of image are fixed to these 3 points
self.points = np.array([
UP + LEFT,

View File

@@ -17,7 +17,7 @@ class PMobject(Mobject):
"stroke_width": DEFAULT_STROKE_WIDTH,
}
def init_points(self):
def reset_points(self):
self.rgbas = np.zeros((0, 4))
self.points = np.zeros((0, 3))
return self

View File

@@ -158,21 +158,22 @@ class VMobject(Mobject):
self.set_stroke(color, family=family)
return self
def match_style(self, vmobject):
def match_style(self, vmobject, family=True):
for a_name in ["fill_rgbas", "stroke_rgbas", "background_stroke_rgbas"]:
setattr(self, a_name, np.array(getattr(vmobject, a_name)))
self.stroke_width = vmobject.stroke_width
self.background_stroke_width = vmobject.background_stroke_width
# Does its best to match up submobject lists, and
# match styles accordingly
submobs1, submobs2 = self.submobjects, vmobject.submobjects
if len(submobs1) == 0:
return self
elif len(submobs2) == 0:
submobs2 = [vmobject]
for sm1, sm2 in zip(*make_even(submobs1, submobs2)):
sm1.match_style(sm2)
if family:
# Does its best to match up submobject lists, and
# match styles accordingly
submobs1, submobs2 = self.submobjects, vmobject.submobjects
if len(submobs1) == 0:
return self
elif len(submobs2) == 0:
submobs2 = [vmobject]
for sm1, sm2 in zip(*make_even(submobs1, submobs2)):
sm1.match_style(sm2)
return self
def fade_no_recurse(self, darkness):

View File

@@ -144,7 +144,7 @@ class Vibrate(Animation):
Animation.__init__(self, Mobject1D(color = self.color), **kwargs)
def update_mobject(self, alpha):
self.mobject.init_points()
self.mobject.reset_points()
epsilon = self.mobject.epsilon
self.mobject.add_points([
[x*self.radius, self.func(x, alpha*self.run_time)+y, 0]

View File

@@ -1,6 +1,5 @@
import itertools as it
import numpy as np
from functools import reduce
def remove_list_redundancies(l):
@@ -108,6 +107,7 @@ def make_even_by_cycling(iterable_1, iterable_2):
def remove_nones(sequence):
return [x for x in sequence if x]
# Note this is redundant with it.chain