diff --git a/mobject/mobject.py b/mobject/mobject.py index 6e135c95..c8bfc5d3 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -316,14 +316,29 @@ class Mobject(object): self.shift(target_point - point_to_align + buff*direction) return self - def align_to(self, mobject_or_point, direction = UP): + def align_to(self, mobject_or_point, direction = ORIGIN, alignment_vect = UP): + """ + Examples: + mob1.align_to(mob2, UP) moves mob1 vertically so that its + top edge lines ups with mob2's top edge. + + mob1.align_to(mob2, alignment_vector = RIGHT) moves mob1 + horizontally so that it's center is directly above/below + the center of mob2 + """ if isinstance(mobject_or_point, Mobject): mob = mobject_or_point - point = mob.get_edge_center(direction) + target_point = mob.get_critical_point(direction) else: - point = mobject_or_point - diff = point - self.get_edge_center(direction) - self.shift(direction*np.dot(diff, direction)) + target_point = mobject_or_point + direction_norm = np.linalg.norm(direction) + if direction_norm > 0: + alignment_vect = np.array(direction)/direction_norm + reference_point = self.get_critical_point(direction) + else: + reference_point = self.get_center() + diff = target_point - reference_point + self.shift(alignment_vect*np.dot(diff, alignment_vect)) return self def shift_onto_screen(self, **kwargs): diff --git a/mobject/vectorized_mobject.py b/mobject/vectorized_mobject.py index 21194a71..264181fd 100644 --- a/mobject/vectorized_mobject.py +++ b/mobject/vectorized_mobject.py @@ -92,9 +92,15 @@ class VMobject(Mobject): fill_opacity = vmobject.get_fill_opacity(), family = False ) - #TODO: This behaviro may not be optimal when submobject - #lists dont' have the same length - for sm1, sm2 in zip(self.submobjects, vmobject.submobjects): + + #Does its best to match up submobject lists, and + #match styles accordingly + submobs1, submobs2 = self.submobjects, vmobject.submobjects + if len(submobs1) == 0: + return + elif len(submobs2) == 0: + submobs2 = [vmobject] + for sm1, sm2 in zip(*make_even(submobs1, submobs2)): sm1.match_style(sm2) return diff --git a/scene/scene.py b/scene/scene.py index fb4ba6ca..fbf2d2ff 100644 --- a/scene/scene.py +++ b/scene/scene.py @@ -482,7 +482,7 @@ class Scene(object): def preview(self): TkSceneRoot(self) - + def get_image_file_path(self, name = None, dont_update = False): folder = "images" if dont_update: @@ -540,7 +540,6 @@ class Scene(object): '-loglevel', 'error', temp_file_path, ] - # self.writing_process = sp.Popen(command, stdin=sp.PIPE, shell=True) self.writing_process = sp.Popen(command, stdin=sp.PIPE) diff --git a/topics/geometry.py b/topics/geometry.py index 0ef70f20..bbbd12a5 100644 --- a/topics/geometry.py +++ b/topics/geometry.py @@ -172,18 +172,12 @@ class AnnularSector(VMobject): arc_center = first_point - self.inner_radius * radial_unit_vector return arc_center -<<<<<<< HEAD def move_arc_center_to(self,point): v = point - self.get_arc_center() self.shift(v) return self - - -======= ->>>>>>> master class Sector(AnnularSector): - CONFIG = { "outer_radius" : 1, "inner_radius" : 0 diff --git a/topics/numerals.py b/topics/numerals.py index 8125436b..d5a9bae3 100644 --- a/topics/numerals.py +++ b/topics/numerals.py @@ -3,6 +3,7 @@ from mobject.vectorized_mobject import VMobject, VGroup, VectorizedPoint from mobject.tex_mobject import TexMobject from animation import Animation from animation.continual_animation import ContinualAnimation +from topics.geometry import BackgroundRectangle from scene import Scene from helpers import * @@ -12,18 +13,31 @@ class DecimalNumber(VMobject): "digit_to_digit_buff" : 0.05, "show_ellipsis" : False, "unit" : None, + "include_background_rectangle" : False, } def __init__(self, number, **kwargs): - digest_config(self, kwargs, locals()) - num_string = '%.*f'%(self.num_decimal_points, number) - negative_zero_string = "-%.*f"%(self.num_decimal_points, 0.) - if num_string == negative_zero_string: - num_string = num_string[1:] - VMobject.__init__(self, *[ - TexMobject(char) - for char in num_string - ], **kwargs) + VMobject.__init__(self, **kwargs) + self.number = number + ndp = self.num_decimal_points + #Build number string + if isinstance(number, complex): + num_string = '%.*f%s%.*fi'%( + ndp, number.real, + "-" if number.imag < 0 else "+", + ndp, abs(number.imag) + ) + else: + num_string = '%.*f'%(ndp, number) + negative_zero_string = "-%.*f"%(ndp, 0.) + if num_string == negative_zero_string: + num_string = num_string[1:] + self.add(*[ + TexMobject(char, **kwargs) + for char in num_string + ]) + + #Add non-numerical bits if self.show_ellipsis: self.add(TexMobject("\\dots")) @@ -35,6 +49,7 @@ class DecimalNumber(VMobject): aligned_edge = DOWN ) +<<<<<<< HEAD if num_string.startswith("-"): minus = self.submobjects[0] minus.next_to( @@ -55,18 +70,29 @@ class DecimalNumber(VMobject): class Integer(VGroup): +======= + #Handle alignment of parts that should be aligned + #to the bottom + for i, c in enumerate(num_string): + if c == "-" and len(num_string) > i+1: + self[i].align_to(self[i+1], alignment_vect = UP) + if self.unit == "\\circ": + self[-1].align_to(self, UP) + # + if self.include_background_rectangle: + #TODO, is this the best way to handle + #background rectangles? + self.background_rectangle = BackgroundRectangle(self) + self.submobjects = [ + self.background_rectangle, + VGroup(*self.submobjects) + ] + +class Integer(DecimalNumber): +>>>>>>> master CONFIG = { - "digit_buff" : 0.8*SMALL_BUFF + "num_decimal_points" : 0, } - def __init__(self, integer, **kwargs): - self.number = integer - num_str = str(integer) - VGroup.__init__(self, *map(TexMobject, num_str), **kwargs) - self.arrange_submobjects( - RIGHT, buff = self.digit_buff, aligned_edge = DOWN - ) - if num_str[0] == "-": - self[0].next_to(self[1], LEFT, buff = SMALL_BUFF) class ChangingDecimal(Animation): CONFIG = {