From ff134b7903a4e189428f4c9482fa4fe548d6d21b Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:48:50 -0700 Subject: [PATCH 1/8] Remove z_coordinate display ordering --- camera/camera.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/camera/camera.py b/camera/camera.py index e92d7ed7..ede6aae6 100644 --- a/camera/camera.py +++ b/camera/camera.py @@ -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() From 7ab432f419967168b61b7923e20653d5387a48ce Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:49:07 -0700 Subject: [PATCH 2/8] Added better 3d axes --- mobject/coordinate_systems.py | 73 +++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/mobject/coordinate_systems.py b/mobject/coordinate_systems.py index 8bc823ba..8115fc83 100644 --- a/mobject/coordinate_systems.py +++ b/mobject/coordinate_systems.py @@ -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 = { From 1c348cbe957dbe4ed52e0b946d0990b044822750 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:49:31 -0700 Subject: [PATCH 3/8] Added Mobject.get_pieces --- mobject/mobject.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/mobject/mobject.py b/mobject/mobject.py index 1bba3f61..42392d4b 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -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 From cba0c78cf76f15c5e1b50bc48e5095c893609b88 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:49:59 -0700 Subject: [PATCH 4/8] Numberline arrowhead should share strokewidth of numberline --- mobject/number_line.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mobject/number_line.py b/mobject/number_line.py index c28868b9..b7d8d336 100644 --- a/mobject/number_line.py +++ b/mobject/number_line.py @@ -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) From 32da0771995d491a8dfed403931232f820063c29 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:50:23 -0700 Subject: [PATCH 5/8] Fixed bug associated with ThreeDVMobject --- mobject/three_dimensions.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mobject/three_dimensions.py b/mobject/three_dimensions.py index 61335c29..3785140c 100644 --- a/mobject/three_dimensions.py +++ b/mobject/three_dimensions.py @@ -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() From 4a71577bcc8458add62823e80d984b6b16933218 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:50:52 -0700 Subject: [PATCH 6/8] Tiny formating change --- utils/iterables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/iterables.py b/utils/iterables.py index 5706d3cc..6912c2c4 100644 --- a/utils/iterables.py +++ b/utils/iterables.py @@ -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 From da792ef2d9104c9ab2711b6322a177f75b2829dd Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:51:12 -0700 Subject: [PATCH 7/8] Add family option to match_style --- mobject/types/vectorized_mobject.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/mobject/types/vectorized_mobject.py b/mobject/types/vectorized_mobject.py index 029a1a60..2cf19528 100644 --- a/mobject/types/vectorized_mobject.py +++ b/mobject/types/vectorized_mobject.py @@ -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): From eeff8605882e2d13a26b40590c3588d377a902d8 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 20 Aug 2018 15:51:43 -0700 Subject: [PATCH 8/8] init_point -> reset_points --- mobject/types/image_mobject.py | 2 +- mobject/types/point_cloud_mobject.py | 2 +- old_projects/music_and_measure.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobject/types/image_mobject.py b/mobject/types/image_mobject.py index 45560723..2cfdc6c8 100644 --- a/mobject/types/image_mobject.py +++ b/mobject/types/image_mobject.py @@ -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, diff --git a/mobject/types/point_cloud_mobject.py b/mobject/types/point_cloud_mobject.py index 148dd940..1a413ba9 100644 --- a/mobject/types/point_cloud_mobject.py +++ b/mobject/types/point_cloud_mobject.py @@ -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 diff --git a/old_projects/music_and_measure.py b/old_projects/music_and_measure.py index f074979c..853d6187 100644 --- a/old_projects/music_and_measure.py +++ b/old_projects/music_and_measure.py @@ -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]