From a69a28c71808875c276a36b8ec37fb1a53e82f59 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 7 May 2018 13:43:39 -0700 Subject: [PATCH 1/6] Small scoping on alt_calc --- active_projects/alt_calc.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/active_projects/alt_calc.py b/active_projects/alt_calc.py index 3458b49a..d6804c5c 100644 --- a/active_projects/alt_calc.py +++ b/active_projects/alt_calc.py @@ -47,19 +47,18 @@ class WriteOpeningWords(Scene): class StartingCalc101(PiCreatureScene): CONFIG = { - # "default_pi_creature_kwargs": { - # "color": BLUE, - # "flip_at_start": False, - # }, } def construct(self): randy = self.pi_creature - deriv_string = "\\frac{df}{dx}(x) = \\lim(\\delta x \\to \\infty)" + \ - "{f(x + \\delta x) - f(x) \\over \\delta x}" - equations = VGroup( - TexMobject(*break_up_string_by_terms(deriv_string, "\\delta x")) + deriv_equation = TexMobject( + "\\frac{df}{dx}(x) = \\lim(\\Delta x \\to \\infty)" + + "{f(x + \\Delta x) - f(x) \\over \\Delta x}", + tex_to_color_map={"\\Delta x": BLUE} ) + self.add(deriv_equation) + equations = VGroup(deriv_equation) + title = TextMobject("Calculus 101") title.to_edge(UP) h_line = Line(LEFT, RIGHT) From 0247224e0799c22951c961566e271825ffd618cc Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Tue, 8 May 2018 16:15:28 -0700 Subject: [PATCH 2/6] Fixes and refactoring for TexMobject --- mobject/mobject.py | 5 +- mobject/svg/tex_mobject.py | 122 +++++++------------------------------ utils/tex_file_writing.py | 81 ++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 102 deletions(-) create mode 100644 utils/tex_file_writing.py diff --git a/mobject/mobject.py b/mobject/mobject.py index 72cfd33a..4c5721f9 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -467,6 +467,8 @@ class Mobject(Container): # Background rectangle def add_background_rectangle(self, color=BLACK, opacity=0.75, **kwargs): + # TODO, this does not behave well when the mobject has points, + # since it gets displayed on top from mobject.shape_matchers import BackgroundRectangle self.background_rectangle = BackgroundRectangle( self, color=color, @@ -742,8 +744,7 @@ class Mobject(Container): def submobject_family(self): sub_families = map(Mobject.submobject_family, self.submobjects) - # all_mobjects = [self] + list(it.chain(*sub_families)) - all_mobjects = list(it.chain(*sub_families)) + [self] + all_mobjects = [self] + list(it.chain(*sub_families)) return remove_list_redundancies(all_mobjects) def family_members_with_points(self): diff --git a/mobject/svg/tex_mobject.py b/mobject/svg/tex_mobject.py index 06c6df13..642d1a61 100644 --- a/mobject/svg/tex_mobject.py +++ b/mobject/svg/tex_mobject.py @@ -4,14 +4,12 @@ from svg_mobject import SVGMobject from svg_mobject import VMobjectFromSVGPathstring from utils.config_ops import digest_config from utils.strings import split_string_list_to_isolate_substring +from utils.tex_file_writing import tex_to_svg_file from mobject.types.vectorized_mobject import VGroup from mobject.types.vectorized_mobject import VectorizedPoint import operator as op -# TODO list -# - Make sure if "color" is passed into TexMobject, it behaves as expected - TEX_MOB_SCALE_FACTOR = 0.05 @@ -67,11 +65,20 @@ class SingleStringTexMobject(SVGMobject): def modify_special_strings(self, tex): tex = self.remove_stray_braces(tex) - if tex in ["\\over", "\\overline"]: - # fraction line needs something to be over - tex += "\\," - if tex == "\\sqrt": - tex += "{\\quad}" + should_add_filler = reduce(op.or_, [ + # Fraction line needs something to be over + tex == "\\over", + tex == "\\overline", + # Makesure sqrt has overbar + tex == "\\sqrt", + # Need to add blank subscript or superscript + tex.endswith("_"), + tex.endswith("^"), + ]) + if should_add_filler: + filler = "{\\quad}" + tex += filler + if tex == "\\substack": tex = "" for t1, t2 in ("\\left", "\\right"), ("\\right", "\\left"): @@ -95,10 +102,9 @@ class SingleStringTexMobject(SVGMobject): for char in "{}" ] if num_rights > num_lefts: - backwards = tex[::-1].replace("}", "", num_rights - num_lefts) - tex = backwards[::-1] + tex = "{" + tex elif num_lefts > num_rights: - tex = tex.replace("{", "", num_lefts - num_rights) + tex = tex + "}" return tex def get_tex_string(self): @@ -273,98 +279,14 @@ class BulletedList(TextMobject): class TexMobjectFromPresetString(TexMobject): + CONFIG = { + # To be filled by subclasses + "tex": None, + "color": None, + } def __init__(self, **kwargs): digest_config(self, kwargs) TexMobject.__init__(self, self.tex, **kwargs) self.set_color(self.color) -########## - - -def tex_hash(expression, template_tex_file): - return str(hash(expression + template_tex_file)) - - -def tex_to_svg_file(expression, template_tex_file): - image_dir = os.path.join( - TEX_IMAGE_DIR, - tex_hash(expression, template_tex_file) - ) - if os.path.exists(image_dir): - return get_sorted_image_list(image_dir) - tex_file = generate_tex_file(expression, template_tex_file) - dvi_file = tex_to_dvi(tex_file) - return dvi_to_svg(dvi_file) - - -def generate_tex_file(expression, template_tex_file): - result = os.path.join( - TEX_DIR, - tex_hash(expression, template_tex_file) - ) + ".tex" - if not os.path.exists(result): - print("Writing \"%s\" to %s" % ( - "".join(expression), result - )) - with open(template_tex_file, "r") as infile: - body = infile.read() - body = body.replace(TEX_TEXT_TO_REPLACE, expression) - with open(result, "w") as outfile: - outfile.write(body) - return result - - -def get_null(): - if os.name == "nt": - return "NUL" - return "/dev/null" - - -def tex_to_dvi(tex_file): - result = tex_file.replace(".tex", ".dvi") - if not os.path.exists(result): - commands = [ - "latex", - "-interaction=batchmode", - "-halt-on-error", - "-output-directory=" + TEX_DIR, - tex_file, - ">", - get_null() - ] - exit_code = os.system(" ".join(commands)) - if exit_code != 0: - latex_output = '' - log_file = tex_file.replace(".tex", ".log") - if os.path.exists(log_file): - with open(log_file, 'r') as f: - latex_output = f.read() - raise Exception( - "Latex error converting to dvi. " - "See log output above or the log file: %s" % log_file) - return result - - -def dvi_to_svg(dvi_file, regen_if_exists=False): - """ - Converts a dvi, which potentially has multiple slides, into a - directory full of enumerated pngs corresponding with these slides. - Returns a list of PIL Image objects for these images sorted as they - where in the dvi - """ - result = dvi_file.replace(".dvi", ".svg") - if not os.path.exists(result): - commands = [ - "dvisvgm", - dvi_file, - "-n", - "-v", - "0", - "-o", - result, - ">", - get_null() - ] - os.system(" ".join(commands)) - return result diff --git a/utils/tex_file_writing.py b/utils/tex_file_writing.py new file mode 100644 index 00000000..892b6fbe --- /dev/null +++ b/utils/tex_file_writing.py @@ -0,0 +1,81 @@ +import os +from constants import TEX_DIR +from constants import TEX_TEXT_TO_REPLACE + + +def tex_hash(expression, template_tex_file): + return str(hash(expression + template_tex_file)) + + +def tex_to_svg_file(expression, template_tex_file): + tex_file = generate_tex_file(expression, template_tex_file) + dvi_file = tex_to_dvi(tex_file) + return dvi_to_svg(dvi_file) + + +def generate_tex_file(expression, template_tex_file): + result = os.path.join( + TEX_DIR, + tex_hash(expression, template_tex_file) + ) + ".tex" + if not os.path.exists(result): + print("Writing \"%s\" to %s" % ( + "".join(expression), result + )) + with open(template_tex_file, "r") as infile: + body = infile.read() + body = body.replace(TEX_TEXT_TO_REPLACE, expression) + with open(result, "w") as outfile: + outfile.write(body) + return result + + +def get_null(): + if os.name == "nt": + return "NUL" + return "/dev/null" + + +def tex_to_dvi(tex_file): + result = tex_file.replace(".tex", ".dvi") + if not os.path.exists(result): + commands = [ + "latex", + "-interaction=batchmode", + "-halt-on-error", + "-output-directory=" + TEX_DIR, + tex_file, + ">", + get_null() + ] + exit_code = os.system(" ".join(commands)) + if exit_code != 0: + log_file = tex_file.replace(".tex", ".log") + raise Exception( + "Latex error converting to dvi. " + "See log output above or the log file: %s" % log_file) + return result + + +def dvi_to_svg(dvi_file, regen_if_exists=False): + """ + Converts a dvi, which potentially has multiple slides, into a + directory full of enumerated pngs corresponding with these slides. + Returns a list of PIL Image objects for these images sorted as they + where in the dvi + """ + result = dvi_file.replace(".dvi", ".svg") + if not os.path.exists(result): + commands = [ + "dvisvgm", + dvi_file, + "-n", + "-v", + "0", + "-o", + result, + ">", + get_null() + ] + os.system(" ".join(commands)) + return result From fb9ce5f518a880fc9b7acb0d9a648a4880941f86 Mon Sep 17 00:00:00 2001 From: Ben Hambrecht Date: Wed, 9 May 2018 16:34:09 +0200 Subject: [PATCH 3/6] made extract_scene play nice with Sublime build --- extract_scene.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extract_scene.py b/extract_scene.py index ae52be31..d609b7ce 100644 --- a/extract_scene.py +++ b/extract_scene.py @@ -151,11 +151,12 @@ def handle_scene(scene, **config): if config["show_file_in_finder"]: commands.append("-R") - # + if config["show_last_frame"]: commands.append(scene.get_image_file_path()) else: commands.append(scene.get_movie_file_path()) + #commands.append("-g") FNULL = open(os.devnull, 'w') sp.call(commands, stdout=FNULL, stderr=sp.STDOUT) FNULL.close() @@ -223,14 +224,18 @@ def get_module_posix(file_name): module_name = file_name.replace(".py", "") last_module = imp.load_module(".", *imp.find_module(".")) for part in module_name.split(os.sep): - load_args = imp.find_module(part, last_module.__path__) - last_module = imp.load_module(part, *load_args) + try: + load_args = imp.find_module(part, last_module.__path__) + last_module = imp.load_module(part, *load_args) + except ImportError: + continue return last_module def get_module(file_name): if os.name == 'nt': return get_module_windows(file_name) + print "file_name =", file_name return get_module_posix(file_name) From 90504e24e7df4b525865b0bf3084e0788cf2bfdb Mon Sep 17 00:00:00 2001 From: Ben Hambrecht Date: Wed, 9 May 2018 16:35:06 +0200 Subject: [PATCH 4/6] fixed bug for reduce_across_dim for mobs with empty submobs --- mobject/mobject.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mobject/mobject.py b/mobject/mobject.py index c9a2affa..56c87c51 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -623,13 +623,17 @@ class Mobject(Container): values = [] values += [ mob.reduce_across_dimension(points_func, reduce_func, dim) - for mob in self.submobjects + for mob in self.nonempty_submobjects() ] try: return reduce_func(values) except: return 0 + def nonempty_submobjects(self): + return [submob for submob in self.submobjects + if len(submob.submobjects) != 0 or len(submob.points) != 0] + def get_merged_array(self, array_attr): result = None for mob in self.family_members_with_points(): @@ -745,10 +749,7 @@ class Mobject(Container): def submobject_family(self): sub_families = map(Mobject.submobject_family, self.submobjects) all_mobjects = [self] + list(it.chain(*sub_families)) -<<<<<<< HEAD #all_mobjects = list(it.chain(*sub_families)) + [self] -======= ->>>>>>> master return remove_list_redundancies(all_mobjects) def family_members_with_points(self): From 7219ff95f752de413d0739235eec58ad09003198 Mon Sep 17 00:00:00 2001 From: Ben Hambrecht Date: Wed, 9 May 2018 16:36:00 +0200 Subject: [PATCH 5/6] made brick row scene reusable for brick wall --- .../eop/chapter1/brick_row_scene.py | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/active_projects/eop/chapter1/brick_row_scene.py b/active_projects/eop/chapter1/brick_row_scene.py index 49365c6e..b11a66ca 100644 --- a/active_projects/eop/chapter1/brick_row_scene.py +++ b/active_projects/eop/chapter1/brick_row_scene.py @@ -5,7 +5,7 @@ from active_projects.eop.reusable_imports import * class BrickRowScene(PiCreatureScene): - def split_tallies(self, direction = DOWN): + def split_tallies(self, row, direction = DOWN): # Split all tally symbols at once and move the copies # either horizontally on top of the brick row # or diagonally into the bricks @@ -15,12 +15,12 @@ class BrickRowScene(PiCreatureScene): tally_targets_left = [ rect.get_center() + 0.25 * rect.get_width() * LEFT - for rect in self.row.rects + for rect in row.rects ] tally_targets_right = [ rect.get_center() + 0.25 * rect.get_width() * RIGHT - for rect in self.row.rects + for rect in row.rects ] if np.all(direction == LEFT) or np.all(direction == RIGHT): @@ -63,7 +63,7 @@ class BrickRowScene(PiCreatureScene): - def tally_split_animations(self, direction = DOWN): + def tally_split_animations(self, row, direction = DOWN): # Just creates the animations and returns them # Execution can be timed afterwards # Returns two lists: first all those going left, then those to the right @@ -73,12 +73,12 @@ class BrickRowScene(PiCreatureScene): tally_targets_left = [ rect.get_center() + 0.25 * rect.get_width() * LEFT - for rect in self.row.rects + for rect in row.rects ] tally_targets_right = [ rect.get_center() + 0.25 * rect.get_width() * RIGHT - for rect in self.row.rects + for rect in row.rects ] if np.all(direction == LEFT) or np.all(direction == RIGHT): @@ -122,13 +122,14 @@ class BrickRowScene(PiCreatureScene): return anims1, anims2 - def split_tallies_at_once(self, direction = DOWN): - anims1, anims2 = self.tally_split_animations(direction = direction) + + def split_tallies_at_once(self, row, direction = DOWN): + anims1, anims2 = self.tally_split_animations(row, direction = direction) self.play(*(anims1 + anims2)) - def split_tallies_in_two_steps(self, direction = DOWN): + def split_tallies_in_two_steps(self, row, direction = DOWN): # First all those to the left, then those to the right - anims1, anims2 = self.tally_split_animations(direction = direction) + anims1, anims2 = self.tally_split_animations(row, direction = direction) self.play(*anims1) self.wait(0.3) self.play(*anims2) @@ -136,31 +137,31 @@ class BrickRowScene(PiCreatureScene): - def merge_rects_by_subdiv(self): + def merge_rects_by_subdiv(self, row): - half_merged_row = self.row.copy() + half_merged_row = row.copy() half_merged_row.subdiv_level += 1 half_merged_row.generate_points() - half_merged_row.move_to(self.row) + half_merged_row.move_to(row) self.play(FadeIn(half_merged_row)) - self.remove(self.row) - self.row = half_merged_row + self.remove(row) + return half_merged_row - def merge_tallies(self, target_pos = UP): + def merge_tallies(self, row, target_pos = UP): - r = self.row.subdiv_level + r = row.subdiv_level if np.all(target_pos == DOWN): tally_targets = [ rect.get_center() - for rect in self.row.get_rects_for_level(r) + for rect in row.get_rects_for_level(r) ] elif np.all(target_pos == UP): - y_pos = self.row.get_center()[1] + 1.2 * 0.5 * self.row.get_height() + y_pos = row.get_center()[1] + 1.2 * 0.5 * row.get_height() for target in tally_targets: target[1] = y_pos else: @@ -186,25 +187,25 @@ class BrickRowScene(PiCreatureScene): self.tallies.add(self.tallies_copy[-1]) - def merge_rects_by_coloring(self): + def merge_rects_by_coloring(self, row): - merged_row = self.row.copy() + merged_row = row.copy() merged_row.coloring_level += 1 merged_row.generate_points() - merged_row.move_to(self.row) + merged_row.move_to(row) self.play(FadeIn(merged_row)) - self.remove(self.row) - self.row = merged_row + self.remove(row) + return merged_row - def move_tallies_on_top(self): + def move_tallies_on_top(self, row): self.play( - self.tallies.shift, 1.2 * 0.5 * self.row.height * UP + self.tallies.shift, 1.2 * 0.5 * row.height * UP ) for tally in self.tallies: - tally.anchor += 1.2 * 0.5 * self.row.height * UP + tally.anchor += 1.2 * 0.5 * row.height * UP def create_pi_creature(self): randy = CoinFlippingPiCreature(color = MAROON_E) @@ -256,12 +257,11 @@ class BrickRowScene(PiCreatureScene): # # # # # # # # - self.play(FlipCoin(randy)) self.play(SplitRectsInBrickWall(self.row)) - self.merge_rects_by_subdiv() - self.merge_rects_by_coloring() + self.row = self.merge_rects_by_subdiv(self.row) + self.row = self.merge_rects_by_coloring(self.row) # # put tallies on top @@ -312,7 +312,6 @@ class BrickRowScene(PiCreatureScene): new_tails[i].shift(COIN_SEQUENCE_SPACING * DOWN) self.play(FadeIn(new_tails)) - decimal_tallies = VGroup() # introduce notion of tallies for (i, rect) in enumerate(self.row.get_rects_for_level(2)): @@ -347,6 +346,7 @@ class BrickRowScene(PiCreatureScene): ) self.wait() + self.tallies = VGroup() for (i, rect) in enumerate(self.row.get_rects_for_level(2)): tally = TallyStack(2-i, i, show_decimals = False) @@ -357,6 +357,7 @@ class BrickRowScene(PiCreatureScene): self.play(FadeIn(self.tallies)) self.wait() + anims = [] for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies): anims.append(ApplyFunction( @@ -366,6 +367,7 @@ class BrickRowScene(PiCreatureScene): self.play(*anims) self.wait() + # replace the original decimal tallies with # the ones that belong to the TallyStacks for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies): @@ -374,9 +376,9 @@ class BrickRowScene(PiCreatureScene): tally_stack.add(tally_stack.decimal_tally) self.add_foreground_mobject(self.tallies) - self.merge_rects_by_subdiv() + self.row = self.merge_rects_by_subdiv(self.row) self.wait() - self.merge_rects_by_coloring() + self.row = self.merge_rects_by_coloring(self.row) self.wait() @@ -494,7 +496,7 @@ class BrickRowScene(PiCreatureScene): ) self.wait() - self.split_tallies_in_two_steps() + self.split_tallies_in_two_steps(self.row) self.wait() self.add_foreground_mobject(self.tallies) @@ -554,7 +556,7 @@ class BrickRowScene(PiCreatureScene): # self.wait() - # self.merge_rects_by_subdiv() + # self.row = self.merge_rects_by_subdiv(self.row) # self.wait() # self.play( @@ -575,9 +577,9 @@ class BrickRowScene(PiCreatureScene): # self.wait() - # self.merge_tallies(target_pos = DOWN) + # self.merge_tallies(self.row, target_pos = DOWN) # self.add_foreground_mobject(self.tallies) - # self.merge_rects_by_coloring() + # self.row = self.merge_rects_by_coloring(self.row) # self.wait() @@ -645,7 +647,7 @@ class BrickRowScene(PiCreatureScene): self.wait() - self.merge_rects_by_subdiv() + self.row = self.merge_rects_by_subdiv(self.row) self.wait() self.play( @@ -666,9 +668,9 @@ class BrickRowScene(PiCreatureScene): self.wait() - self.merge_tallies(target_pos = DOWN) + self.merge_tallies(self.row, target_pos = DOWN) self.add_foreground_mobject(self.tallies) - self.merge_rects_by_coloring() + self.row = self.merge_rects_by_coloring(self.row) self.wait() @@ -759,7 +761,7 @@ class BrickRowScene(PiCreatureScene): ) self.wait() - self.merge_rects_by_subdiv() + self.row = self.merge_rects_by_subdiv(self.row) self.wait() @@ -876,7 +878,7 @@ class BrickRowScene(PiCreatureScene): FadeOut(self.tallies), ) - self.merge_rects_by_coloring() + self.row = self.merge_rects_by_coloring(self.row) self.play( FadeIn(new_tallies[0]), @@ -886,9 +888,9 @@ class BrickRowScene(PiCreatureScene): - # # # # # # # # - # FIFTH FLIP # - # # # # # # # # + # # # # # # # # # # + # EVEN MORE FLIPS # + # # # # # # # # # # self.play(FadeOut(new_tallies)) self.clear() @@ -909,9 +911,9 @@ class BrickRowScene(PiCreatureScene): SplitRectsInBrickWall(self.row) ) self.wait() - self.merge_rects_by_subdiv() + self.row = self.merge_rects_by_subdiv(self.row) self.wait() - self.merge_rects_by_coloring() + self.row = self.merge_rects_by_coloring(self.row) self.wait() self.play(FadeOut(previous_row)) From 84c025aac6179b0acfefcb6df934cef91baa53db Mon Sep 17 00:00:00 2001 From: Ben Hambrecht Date: Wed, 9 May 2018 16:36:14 +0200 Subject: [PATCH 6/6] added animation steps for brick wall --- .../eop/chapter1/entire_brick_wall.py | 27 ++++++++++++++----- active_projects/eop/reusables/brick_row.py | 2 ++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/active_projects/eop/chapter1/entire_brick_wall.py b/active_projects/eop/chapter1/entire_brick_wall.py index 31d07ec1..f716d760 100644 --- a/active_projects/eop/chapter1/entire_brick_wall.py +++ b/active_projects/eop/chapter1/entire_brick_wall.py @@ -1,29 +1,30 @@ from big_ol_pile_of_manim_imports import * from active_projects.eop.reusable_imports import * +from active_projects.eop.chapter1.brick_row_scene import BrickRowScene - -class EntireBrickWall(Scene): +class EntireBrickWall(BrickRowScene): def construct(self): + self.remove(self.get_primary_pi_creature()) + row_height = 0.3 nb_rows = 20 start_point = 3 * UP + 1 * LEFT rows = VMobject() rows.add(BrickRow(0, height = row_height)) - rows[0].move_to(start_point) + rows.move_to(start_point) self.add(rows) - + zero_counter = Integer(0).next_to(start_point + 0.5 * rows[0].width * RIGHT) nb_flips_text = TextMobject("\# of flips") nb_flips_text.next_to(zero_counter, RIGHT, buff = LARGE_BUFF) self.add(zero_counter, nb_flips_text) - for i in range(1,nb_rows + 1): - rows.add(BrickRow(i, height = row_height)) - rows[-1].move_to(start_point + (i - 1) * row_height * DOWN) + for i in range(1, nb_rows + 1): + rows.add(rows[-1].copy()) self.bring_to_back(rows[-1]) anims = [ rows[-1].shift, row_height * DOWN, @@ -37,6 +38,12 @@ class EntireBrickWall(Scene): self.play(*anims) + self.play(SplitRectsInBrickWall(rows[-1])) + rows.submobjects[-1] = self.merge_rects_by_subdiv(rows[-1]) + rows.submobjects[-1] = self.merge_rects_by_coloring(rows[-1]) + + + # draw indices under the last row for the number of tails tails_counters = VGroup() for (i, rect) in enumerate(rows[-1].rects): @@ -62,6 +69,12 @@ class EntireBrickWall(Scene): FadeIn(nb_tails_text) ) + # remove any hidden brick rows + hidden_brick_rows = VGroup(*[mob for mob in self.mobjects + if isinstance(mob, BrickRow) and not mob in rows + ]) + self.remove(hidden_brick_rows) + special_brick_copy = rows[-1].rects[13].copy() self.play( rows.fade, 0.9, diff --git a/active_projects/eop/reusables/brick_row.py b/active_projects/eop/reusables/brick_row.py index 92ca15f7..875d8920 100644 --- a/active_projects/eop/reusables/brick_row.py +++ b/active_projects/eop/reusables/brick_row.py @@ -184,6 +184,7 @@ class SplitRectsInBrickWall(AnimationGroup): def __init__(self, mobject, **kwargs): + #print mobject.height, mobject.get_height() r = self.subdiv_level = mobject.subdiv_level + 1 subdivs = VGroup() @@ -196,6 +197,7 @@ class SplitRectsInBrickWall(AnimationGroup): subdiv = DashedLine( mobject.get_top() + x * RIGHT, mobject.get_bottom() + x * RIGHT, + dashed_segment_length = 0.02 ) subdivs.add(subdiv) anims.append(ShowCreation(subdiv))