diff --git a/constants.py b/constants.py index 824f3e92..bb54c011 100644 --- a/constants.py +++ b/constants.py @@ -1,10 +1,15 @@ import os import numpy as np + +DEFAULT_HEIGHT = 1440 +DEFAULT_WIDTH = 2560 +DEFAULT_FRAME_DURATION = 0.04 + PRODUCTION_QUALITY_DISPLAY_CONFIG = { - "height" : 1440, - "width" : 2560, - "frame_duration" : 0.04, + "height" : DEFAULT_HEIGHT, + "width" : DEFAULT_WIDTH , + "frame_duration" : DEFAULT_FRAME_DURATION, } MEDIUM_QUALITY_DISPLAY_CONFIG = { @@ -26,8 +31,6 @@ DEFAULT_POINT_DENSITY_1D = 200 DEFAULT_POINT_THICKNESS = 3 #TODO, Make sure these are not needd -DEFAULT_HEIGHT = PRODUCTION_QUALITY_DISPLAY_CONFIG["height"] -DEFAULT_WIDTH = PRODUCTION_QUALITY_DISPLAY_CONFIG["width"] SPACE_HEIGHT = 4.0 SPACE_WIDTH = SPACE_HEIGHT * DEFAULT_WIDTH / DEFAULT_HEIGHT @@ -37,7 +40,6 @@ DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = 0.2 #All in seconds -DEFAULT_FRAME_DURATION = 0.04 DEFAULT_ANIMATION_RUN_TIME = 1.0 DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0 DEFAULT_DITHER_TIME = 1.0 @@ -56,14 +58,14 @@ BOTTOM = SPACE_HEIGHT*DOWN LEFT_SIDE = SPACE_WIDTH*LEFT RIGHT_SIDE = SPACE_WIDTH*RIGHT -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) -FILE_DIR = os.path.join(THIS_DIR, os.pardir, "animation_files") -IMAGE_DIR = os.path.join(FILE_DIR, "images") -GIF_DIR = os.path.join(FILE_DIR, "gifs") -MOVIE_DIR = os.path.join(FILE_DIR, "movies") -TEX_DIR = os.path.join(FILE_DIR, "Tex") -TEX_IMAGE_DIR = os.path.join(IMAGE_DIR, "Tex") -MOBJECT_DIR = os.path.join(FILE_DIR, "mobjects") +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) +FILE_DIR = os.path.join(THIS_DIR, os.pardir, "animation_files") +IMAGE_DIR = os.path.join(FILE_DIR, "images") +GIF_DIR = os.path.join(FILE_DIR, "gifs") +MOVIE_DIR = os.path.join(FILE_DIR, "movies") +TEX_DIR = os.path.join(FILE_DIR, "Tex") +TEX_IMAGE_DIR = os.path.join(IMAGE_DIR, "Tex") +MOBJECT_DIR = os.path.join(FILE_DIR, "mobjects") IMAGE_MOBJECT_DIR = os.path.join(MOBJECT_DIR, "image") for folder in [IMAGE_DIR, GIF_DIR, MOVIE_DIR, TEX_DIR, @@ -74,76 +76,67 @@ for folder in [IMAGE_DIR, GIF_DIR, MOVIE_DIR, TEX_DIR, PDF_DENSITY = 800 SIZE_TO_REPLACE = "SizeHere" TEX_TEXT_TO_REPLACE = "YourTextHere" -TEMPLATE_TEX_FILE = os.path.join(TEX_DIR, "template.tex") -TEMPLATE_TEXT_FILE = os.path.join(TEX_DIR, "text_template.tex") +TEMPLATE_TEX_FILE = os.path.join(THIS_DIR, "template.tex") +TEMPLATE_TEXT_FILE = os.path.join(THIS_DIR, "text_template.tex") MAX_LEN_FOR_HUGE_TEX_FONT = 25 LOGO_PATH = os.path.join(IMAGE_DIR, "logo.png") -PI_CREATURE_DIR = os.path.join(IMAGE_DIR, "PiCreature") -PI_CREATURE_PART_NAME_TO_DIR = lambda name : os.path.join(PI_CREATURE_DIR, "pi_creature_"+name) + ".png" -PI_CREATURE_SCALE_VAL = 0.5 -PI_CREATURE_MOUTH_TO_EYES_DISTANCE = 0.25 - - ### Colors ### COLOR_MAP = { - "DARK_BLUE" : "#236B8E", - "DARK_BROWN" : "#8B4513", + "DARK_BLUE" : "#236B8E", + "DARK_BROWN" : "#8B4513", "LIGHT_BROWN" : "#CD853F", - "BLUE_A" : "#1C758A", - "BLUE_B" : "#29ABCA", - "BLUE_C" : "#58C4DD", - "BLUE_D" : "#9CDCEB", - "BLUE_E" : "#C7E9F1", - "TEAL_A" : "#49A88F", - "TEAL_B" : "#55C1A7", - "TEAL_C" : "#5CD0B3", - "TEAL_D" : "#76DDC0", - "TEAL_E" : "#ACEAD7", - "GREEN_A" : "#699C52", - "GREEN_B" : "#77B05D", - "GREEN_C" : "#83C167", - "GREEN_D" : "#A6CF8C", - "GREEN_E" : "#C9E2AE", - "YELLOW_A" : "#E8C11C", - "YELLOW_B" : "#F4D345", - "YELLOW_C" : "#FCE15B", - "YELLOW_D" : "#FFEA94", - "YELLOW_E" : "#FFF1B6", - "GOLD_A" : "#C78D46", - "GOLD_B" : "#E1A158", - "GOLD_C" : "#F0AC5F", - "GOLD_D" : "#F9B775", - "GOLD_E" : "#F7C797", - "RED_A" : "#CF5044", - "RED_B" : "#E65A4C", - "RED_C" : "#FC6255", - "RED_D" : "#FF8080", - "RED_E" : "#F7A1A3", - "MAROON_A" : "#94424F", - "MAROON_B" : "#A24D61", - "MAROON_C" : "#C55F73", - "MAROON_D" : "#EC92AB", - "MAROON_E" : "#ECABC1", - "PURPLE_A" : "#644172", - "PURPLE_B" : "#715582", - "PURPLE_C" : "#9A72AC", - "PURPLE_D" : "#B189C6", - "PURPLE_E" : "#CAA3E8", - "WHITE" : "#FFFFFF", - "BLACK" : "#000000", + "BLUE_A" : "#1C758A", + "BLUE_B" : "#29ABCA", + "BLUE_C" : "#58C4DD", + "BLUE_D" : "#9CDCEB", + "BLUE_E" : "#C7E9F1", + "TEAL_A" : "#49A88F", + "TEAL_B" : "#55C1A7", + "TEAL_C" : "#5CD0B3", + "TEAL_D" : "#76DDC0", + "TEAL_E" : "#ACEAD7", + "GREEN_A" : "#699C52", + "GREEN_B" : "#77B05D", + "GREEN_C" : "#83C167", + "GREEN_D" : "#A6CF8C", + "GREEN_E" : "#C9E2AE", + "YELLOW_A" : "#E8C11C", + "YELLOW_B" : "#F4D345", + "YELLOW_C" : "#FCE15B", + "YELLOW_D" : "#FFEA94", + "YELLOW_E" : "#FFF1B6", + "GOLD_A" : "#C78D46", + "GOLD_B" : "#E1A158", + "GOLD_C" : "#F0AC5F", + "GOLD_D" : "#F9B775", + "GOLD_E" : "#F7C797", + "RED_A" : "#CF5044", + "RED_B" : "#E65A4C", + "RED_C" : "#FC6255", + "RED_D" : "#FF8080", + "RED_E" : "#F7A1A3", + "MAROON_A" : "#94424F", + "MAROON_B" : "#A24D61", + "MAROON_C" : "#C55F73", + "MAROON_D" : "#EC92AB", + "MAROON_E" : "#ECABC1", + "PURPLE_A" : "#644172", + "PURPLE_B" : "#715582", + "PURPLE_C" : "#9A72AC", + "PURPLE_D" : "#B189C6", + "PURPLE_E" : "#CAA3E8", + "WHITE" : "#FFFFFF", + "BLACK" : "#000000", } PALETTE = COLOR_MAP.values() -global_dict = globals() -global_dict.update(COLOR_MAP) -for name in ["BLUE", "TEAL", "GREEN", - "YELLOW", "GOLD", "RED", - "MAROON", "PURPLE"]: - global_dict[name] = global_dict[name + "_C"] +globals().update(COLOR_MAP) +for name in filter(lambda s : s.endswith("_C"), COLOR_MAP.keys()): + globals()[name.replace("_C", "")] = globals()[name] diff --git a/displayer.py b/displayer.py index 8d9606b3..1a62c398 100644 --- a/displayer.py +++ b/displayer.py @@ -139,10 +139,10 @@ def write_to_movie(scene, name): file_path = get_file_path(name, ".mp4") print "Writing to %s"%file_path - fps = int(1/scene.display_config["frame_duration"]) - dim = (scene.display_config["width"], scene.display_config["height"]) + fps = int(1/scene.frame_duration) + dim = (scene.width, scene.height) - command = [ + command = [ FFMPEG_BIN, '-y', # overwrite output file if it exists '-f', 'rawvideo', diff --git a/extract_scene.py b/extract_scene.py index 8081e307..7bc41abc 100644 --- a/extract_scene.py +++ b/extract_scene.py @@ -187,10 +187,8 @@ def main(): inspect.getmembers(module, is_scene) ) config["movie_prefix"] = config["module"] - scene_kwargs = { - "display_config" : config["display_config"], - "announce_construction" : True - } + scene_kwargs = config["display_config"] + scene_kwargs["announce_construction"] = True for SceneClass in get_scene_classes(scene_names_to_classes, config): for args in get_scene_args(SceneClass, config): scene_kwargs["construct_args"] = args diff --git a/generate_logo.py b/generate_logo.py new file mode 100644 index 00000000..a92d4e33 --- /dev/null +++ b/generate_logo.py @@ -0,0 +1,71 @@ + + + +from animation.transform import Transform +from mobject import Mobject +from mobject.tex_mobject import TextMobject +from topics.geometry import Circle +from topics.three_dimensions import Sphere +from scene import Scene + +from helpers import * + + +class LogoGeneration(Scene): + DEFAULT_CONFIG = { + "radius" : 1.5, + "inner_radius_ratio" : 0.55, + "circle_density" : 100, + "circle_blue" : "skyblue", + "circle_brown" : DARK_BROWN, + "circle_repeats" : 5, + "sphere_density" : 50, + "sphere_blue" : DARK_BLUE, + "sphere_brown" : LIGHT_BROWN, + "interpolation_factor" : 0.3, + "frame_duration" : 0.01, + } + + def construct(self): + digest_config(self, {}) + circle = Circle( + density = self.circle_density, + color = self.circle_blue + ) + circle.repeat(self.circle_repeats) + circle.scale(self.radius) + sphere = Sphere( + density = self.sphere_density, + color = self.sphere_blue + ) + sphere.scale(self.radius) + sphere.rotate(-np.pi / 7, [1, 0, 0]) + sphere.rotate(-np.pi / 7) + iris = Mobject() + Mobject.interpolate( + circle, sphere, iris, + self.interpolation_factor + ) + for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: + mob.highlight(color, lambda (x, y, z) : x < 0 and y > 0) + mob.highlight( + "black", + lambda point: np.linalg.norm(point) < \ + self.inner_radius_ratio*self.radius + ) + name = TextMobject("3Blue1Brown").center() + name.highlight("grey") + name.shift(2*DOWN) + + self.play(Transform( + circle, iris, + run_time = DEFAULT_ANIMATION_RUN_TIME + )) + self.frames = drag_pixels(self.frames) + self.set_frame_as_background() + self.save_image() + self.add(name) + self.dither() + print "Dragging pixels..." + + diff --git a/helpers.py b/helpers.py index 115a768f..245f3575 100644 --- a/helpers.py +++ b/helpers.py @@ -11,6 +11,12 @@ import re from constants import * +def list_update(l1, l2): + return filter(lambda e : e not in l2, l1) + l2 + +def all_elements_are_instances(iterable, Class): + return all(map(lambda e : isinstance(e, Class), iterable)) + def adjascent_pairs(objects): return zip(objects, list(objects[1:])+[objects[0]]) diff --git a/mobject/tex_mobject.py b/mobject/tex_mobject.py index 6059a2d2..d3ff0f0a 100644 --- a/mobject/tex_mobject.py +++ b/mobject/tex_mobject.py @@ -87,7 +87,7 @@ def generate_tex_file(expression, size, template_tex_file): def tex_to_dvi(tex_file): result = tex_file.replace(".tex", ".dvi") - if not os.path.exists(filestem + ".dvi"): + if not os.path.exists(result): commands = [ "latex", "-interaction=batchmode", @@ -122,7 +122,7 @@ def dvi_to_png(dvi_file, regen_if_exists = False): "convert", "-density", str(PDF_DENSITY), - path, + dvi_file, "-size", str(DEFAULT_WIDTH) + "x" + str(DEFAULT_HEIGHT), os.path.join(images_dir, name + ".png") diff --git a/old_projects/generate_logo.py b/old_projects/generate_logo.py deleted file mode 100644 index 1f361b81..00000000 --- a/old_projects/generate_logo.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python - -import numpy as np -import itertools as it -from copy import deepcopy -import sys - - -from animation import * -from mobject import * -from constants import * -from region import * -from scene import Scene - -class LogoGeneration(Scene): - LOGO_RADIUS = 1.5 - INNER_RADIUS_RATIO = 0.55 - CIRCLE_DENSITY = 100 - CIRCLE_BLUE = "skyblue" - SPHERE_DENSITY = 50 - SPHERE_BLUE = DARK_BLUE - CIRCLE_SPHERE_INTERPOLATION = 0.3 - FRAME_DURATION = 0.01 - - def construct(self): - self.frame_duration = FRAME_DURATION - circle = Circle( - density = self.CIRCLE_DENSITY, - color = self.CIRCLE_BLUE - ).repeat(5).scale(self.LOGO_RADIUS) - sphere = Sphere( - density = self.SPHERE_DENSITY, - color = self.SPHERE_BLUE - ).scale(self.LOGO_RADIUS) - sphere.rotate(-np.pi / 7, [1, 0, 0]) - sphere.rotate(-np.pi / 7) - alpha = 0.3 - iris = Mobject() - Mobject.interpolate( - circle, sphere, iris, - self.CIRCLE_SPHERE_INTERPOLATION - ) - for mob, color in [(iris, LIGHT_BROWN), (circle, DARK_BROWN)]: - mob.highlight(color, lambda (x, y, z) : x < 0 and y > 0) - mob.highlight( - "black", - lambda point: np.linalg.norm(point) < \ - self.INNER_RADIUS_RATIO*self.LOGO_RADIUS - ) - name = TextMobject("3Blue1Brown").center() - name.highlight("grey") - name.shift(2*DOWN) - - self.play(Transform( - circle, iris, - run_time = DEFAULT_ANIMATION_RUN_TIME - )) - self.add(name) - self.dither() - print "Dragging pixels..." - self.frames = drag_pixels(self.frames) - diff --git a/scene/scene.py b/scene/scene.py index f2d29185..17a0d858 100644 --- a/scene/scene.py +++ b/scene/scene.py @@ -14,33 +14,34 @@ from helpers import * import displayer as disp from tk_scene import TkSceneRoot from mobject import Mobject +from animation.transform import ApplyMethod class Scene(object): DEFAULT_CONFIG = { - "display_config" : PRODUCTION_QUALITY_DISPLAY_CONFIG, - "construct_args" : [], - "background" : None, - "start_dither_time" : DEFAULT_DITHER_TIME, + "height" : DEFAULT_HEIGHT, + "width" : DEFAULT_WIDTH , + "frame_duration" : DEFAULT_FRAME_DURATION, + "construct_args" : [], + "background" : None, + "start_dither_time" : DEFAULT_DITHER_TIME, "announce_construction" : False, } def __init__(self, **kwargs): digest_config(self, kwargs) if self.announce_construction: print "Constructing %s..."%str(self) - self.frame_duration = self.display_config["frame_duration"] - self.frames = [] - self.mobjects = [] if self.background: self.original_background = np.array(background) #TODO, Error checking? else: self.original_background = np.zeros( - (self.display_config["height"], self.display_config["width"], 3), + (self.height, self.width, 3), dtype = 'uint8' ) - self.background = self.original_background - self.shape = self.background.shape[:2] - #TODO, space shape + self.background = self.original_background + self.frames = [self.background] + self.mobjects = [] + self.construct(*self.construct_args) def construct(self): @@ -56,18 +57,23 @@ class Scene(object): self.name = name return self + def get_frame(self): + return self.frames[-1] + + def set_frame(self, frame): + self.frames[-1] = frame + return self + def add(self, *mobjects): """ Mobjects will be displayed, from background to foreground, in the order with which they are entered. """ - for mobject in mobjects: - if not isinstance(mobject, Mobject): - raise Exception("Adding something which is not a mobject") - #In case it's already in there, it should - #now be closer to the foreground. - self.remove(mobject) - self.mobjects.append(mobject) + if not all_elements_are_instances(mobjects, Mobject): + raise Exception("Adding something which is not a mobject") + self.set_frame(disp.paint_mobjects(mobjects, self.get_frame())) + old_mobjects = filter(lambda m : m not in mobjects, self.mobjects) + self.mobjects = old_mobjects + list(mobjects) return self def add_local_mobjects(self): @@ -81,11 +87,13 @@ class Scene(object): )) def remove(self, *mobjects): - for mobject in mobjects: - if not isinstance(mobject, Mobject): - raise Exception("Removing something which is not a mobject") - while mobject in self.mobjects: - self.mobjects.remove(mobject) + if not all_elements_are_instances(mobjects, Mobject): + raise Exception("Removing something which is not a mobject") + mobjects = filter(lambda m : m in self.mobjects, mobjects) + if len(mobjects): + return + self.mobjects = filter(lambda m : m not in mobjects, self.mobjects) + self.repaint_mojects() return self def bring_to_front(self, mobject): @@ -95,11 +103,13 @@ class Scene(object): def bring_to_back(self, mobject): self.remove(mobject) self.mobjects = [mobject] + self.mobjects + self.repaint_mojects() return self def clear(self): self.reset_background() - self.remove(*self.mobjects) + self.mobjects = [] + self.set_frame(self.background) return self def highlight_region(self, region, color = None): @@ -108,6 +118,7 @@ class Scene(object): image_array = self.background, color = color, ) + self.repaint_mojects() return self def highlight_region_over_time_range(self, region, time_range = None, color = "black"): @@ -128,6 +139,10 @@ class Scene(object): self.background = self.original_background return self + def repaint_mojects(self): + self.set_frame(disp.paint_mobjects(self.mobjects, self.background)) + return self + def paint_into_background(self, *mobjects): #This way current mobjects don't have to be redrawn with #every change, and one can later call "apply" without worrying @@ -135,6 +150,9 @@ class Scene(object): self.background = disp.paint_mobjects(mobjects, self.background) return self + def set_frame_as_background(self): + self.background = self.get_frame() + def play(self, *animations, **kwargs): if "run_time" in kwargs: run_time = kwargs["run_time"] @@ -188,9 +206,6 @@ class Scene(object): def apply(self, mobject_method, *args, **kwargs): self.play(ApplyMethod(mobject_method, *args, **kwargs)) - def get_frame(self): - return disp.paint_mobjects(self.mobjects, self.background) - def dither(self, duration = DEFAULT_DITHER_TIME): self.frames += [self.get_frame()]*int(duration / self.frame_duration) return self diff --git a/topics/characters.py b/topics/characters.py index 52fa992d..a8e9375b 100644 --- a/topics/characters.py +++ b/topics/characters.py @@ -3,6 +3,11 @@ from helpers import * from mobject import Mobject, CompoundMobject from image_mobject import ImageMobject +PI_CREATURE_DIR = os.path.join(IMAGE_DIR, "PiCreature") +PI_CREATURE_PART_NAME_TO_DIR = lambda name : os.path.join(PI_CREATURE_DIR, "pi_creature_"+name) + ".png" +PI_CREATURE_SCALE_VAL = 0.5 +PI_CREATURE_MOUTH_TO_EYES_DISTANCE = 0.25 + class PiCreature(CompoundMobject): DEFAULT_COLOR = BLUE PART_NAMES = [ diff --git a/topics/complex_numbers.py b/topics/complex_numbers.py index 1c21fbbc..360d8b93 100644 --- a/topics/complex_numbers.py +++ b/topics/complex_numbers.py @@ -11,22 +11,23 @@ def complex_string(complex_num): class ComplexPlane(NumberPlane): DEFAULT_CONFIG = { - "color" : GREEN, + "color" : GREEN, "unit_to_spatial_width" : 1, - "line_frequency" : 1, - "faded_line_frequency" : 0.5, - "number_at_center" : complex(0), + "line_frequency" : 1, + "faded_line_frequency" : 0.5, + "number_at_center" : complex(0), } def __init__(self, **kwargs): digest_config(self, kwargs) kwargs.update({ - "x_unit_to_spatial_width" : self.unit_to_spatial_width, + "x_unit_to_spatial_width" : self.unit_to_spatial_width, "y_uint_to_spatial_height" : self.unit_to_spatial_width, - "x_line_frequency" : self.line_frequency, - "x_faded_line_frequency" : self.faded_line_frequency, - "y_line_frequency" : self.line_frequency, - "y_faded_line_frequency" : self.faded_line_frequency, - "num_pair_at_center" : (self.number_at_center.real, self.number_at_center.imag), + "x_line_frequency" : self.line_frequency, + "x_faded_line_frequency" : self.faded_line_frequency, + "y_line_frequency" : self.line_frequency, + "y_faded_line_frequency" : self.faded_line_frequency, + "num_pair_at_center" : (self.number_at_center.real, + self.number_at_center.imag), }) NumberPlane.__init__(self, **kwargs) @@ -88,23 +89,15 @@ class ComplexFunction(ApplyPointwiseFunction): ) class ComplexHomotopy(Homotopy): - def __init__(self, complex_homotopy, **kwargs): + def __init__(self, complex_homotopy, mobject = ComplexPlane, **kwargs): """ - Complex Hootopy a function (z, t) to z' + Complex Hootopy a function Cx[0, 1] to C """ def homotopy((x, y, z, t)): c = complex_homotopy((complex(x, y), t)) return (c.real, c.imag, z) - if len(args) > 0: - args = list(args) - mobject = args.pop(0) - elif "mobject" in kwargs: - mobject = kwargs["mobject"] - else: - mobject = Grid() Homotopy.__init__(self, homotopy, mobject, *args, **kwargs) - self.name = "ComplexHomotopy" + \ - to_cammel_case(complex_homotopy.__name__) + class ComplexMultiplication(Scene): @staticmethod diff --git a/topics/geometry.py b/topics/geometry.py index 4ed58bb1..bc4146a4 100644 --- a/topics/geometry.py +++ b/topics/geometry.py @@ -21,7 +21,7 @@ class Dot(Mobject1D): #Use 1D density, even though 2D class Cross(Mobject1D): DEFAULT_CONFIG = { - "color" : YELLOW, + "color" : YELLOW, "radius" : 0.3 } def __init__(self, center_point = ORIGIN, **kwargs): @@ -76,7 +76,7 @@ class Line(Mobject1D): class Arrow(Line): DEFAULT_CONFIG = { - "color" : WHITE, + "color" : WHITE, "tip_length" : 0.25 } def __init__(self, *args, **kwargs): @@ -132,8 +132,8 @@ class CurvedLine(Line): class PartialCircle(Mobject1D): DEFAULT_CONFIG = { - "radius" : 1.0, - "start_angle" : 0 + "radius" : 1.0, + "start_angle" : 0, } def __init__(self, angle, **kwargs): digest_locals(self) @@ -159,7 +159,7 @@ class Circle(PartialCircle): class Polygon(Mobject1D): DEFAULT_CONFIG = { - "color" : GREEN_D, + "color" : GREEN_D, "edge_colors" : None } def __init__(self, *points, **kwargs): @@ -184,9 +184,9 @@ class Polygon(Mobject1D): class Rectangle(Mobject1D): DEFAULT_CONFIG = { - "color" : YELLOW, + "color" : YELLOW, "height" : 2.0, - "width" : 4.0 + "width" : 4.0 } def generate_points(self): wh = [self.width/2.0, self.height/2.0] diff --git a/topics/number_line.py b/topics/number_line.py index c492af97..677dac45 100644 --- a/topics/number_line.py +++ b/topics/number_line.py @@ -5,15 +5,15 @@ from scene import Scene class NumberLine(Mobject1D): DEFAULT_CONFIG = { - "color" : BLUE, - "numerical_radius" : SPACE_WIDTH, + "color" : BLUE, + "numerical_radius" : SPACE_WIDTH, "unit_length_to_spatial_width" : 1, - "tick_size" : 0.1, - "tick_frequency" : 0.5, - "leftmost_tick" : None, - "number_at_center" : 0, + "tick_size" : 0.1, + "tick_frequency" : 0.5, + "leftmost_tick" : None, + "number_at_center" : 0, "numbers_with_elongated_ticks" : [0], - "longer_tick_multiple" : 2, + "longer_tick_multiple" : 2, } def __init__(self, **kwargs): digest_config(self, kwargs) @@ -100,29 +100,29 @@ class NumberLine(Mobject1D): class UnitInterval(NumberLine): DEFAULT_CONFIG = { - "numerical_radius" : 0.5, + "numerical_radius" : 0.5, "unit_length_to_spatial_width" : 2*(SPACE_WIDTH-1), - "tick_frequency" : 0.1, - "leftmost_tick" : 0, - "number_at_center" : 0.5, + "tick_frequency" : 0.1, + "leftmost_tick" : 0, + "number_at_center" : 0.5, "numbers_with_elongated_ticks" : [0, 1], } class NumberPlane(Mobject1D): DEFAULT_CONFIG = { - "color" : BLUE, - "x_radius" : SPACE_WIDTH, - "y_radius" : SPACE_HEIGHT, - "x_unit_to_spatial_width" : 1, + "color" : BLUE, + "x_radius" : SPACE_WIDTH, + "y_radius" : SPACE_HEIGHT, + "x_unit_to_spatial_width" : 1, "y_uint_to_spatial_height" : 1, - "x_line_frequency" : 1, - "x_faded_line_frequency" : 0.5, - "y_line_frequency" : 1, - "y_faded_line_frequency" : 0.5, - "fade_factor" : 0.3, - "number_scale_factor" : 0.25, - "num_pair_at_center" : np.array((0, 0)), + "x_line_frequency" : 1, + "x_faded_line_frequency" : 0.5, + "y_line_frequency" : 1, + "y_faded_line_frequency" : 0.5, + "fade_factor" : 0.3, + "number_scale_factor" : 0.25, + "num_pair_at_center" : np.array((0, 0)), } def generate_points(self):