def get_riemann_rectangles( self, graph, x_min = None, x_max = None, dx = 0.1, input_sample_type = "left", stroke_width = 1, start_color = BLUE, end_color = GREEN): x_min = x_min if x_min is not None else self.x_min x_max = x_max if x_max is not None else self.x_max rectangles = VGroup() for x in np.arange(x_min, x_max, dx): if input_sample_type == "left": sample_input = x elif input_sample_type == "right": sample_input = x+dx else: raise Exception("Invalid input sample type") graph_point = self.input_to_graph_point(sample_input, graph) points = VGroup(*map(VectorizedPoint, [ self.coords_to_point(x, 0), self.coords_to_point(x+dx, 0), graph_point ])) rect = Rectangle() rect.replace(points, stretch = True) rect.set_fill(opacity = 1) rectangles.add(rect) rectangles.gradient_highlight(start_color, end_color) rectangles.set_stroke(BLACK, width = stroke_width) return rectangles
def generate_big_rectangle(self): height, width = self.zoomed_canvas_space_shape self.big_rectangle = Rectangle(height=height, width=width, color=self.square_color) if self.zoomed_canvas_center is not None: self.big_rectangle.shift(self.zoomed_canvas_center) elif self.zoomed_canvas_corner is not None: self.big_rectangle.to_corner(self.zoomed_canvas_corner) self.add(self.big_rectangle)
def rect_to_mobject(self, rect_element): if rect_element.hasAttribute("fill"): if Color(str(rect_element.getAttribute("fill"))) == Color(WHITE): return mob = Rectangle( width = float(rect_element.getAttribute("width")), height = float(rect_element.getAttribute("height")), stroke_width = 0, fill_color = WHITE, fill_opacity = 1.0 ) mob.shift(mob.get_center()-mob.get_corner(UP+LEFT)) return mob
def scroll_through_patrons(self): logo_box = Square(side_length=2.5) logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF) total_width = SPACE_WIDTH - logo_box.get_right()[0] black_rect = Rectangle(fill_color=BLACK, fill_opacity=1, stroke_width=0, width=2 * SPACE_WIDTH, height=1.1 * SPACE_HEIGHT) black_rect.to_edge(UP, buff=0) line = DashedLine(SPACE_WIDTH * LEFT, SPACE_WIDTH * RIGHT) line.move_to(black_rect, DOWN) line.shift(SMALL_BUFF * SMALL_BUFF * DOWN) self.add(line) patrons = VGroup(*map(TextMobject, self.specific_patrons)) patrons.scale(self.patron_scale_val) for patron in patrons: if patron.get_width() > self.max_patron_width: patron.scale_to_fit_width(self.max_patron_width) columns = VGroup(*[ VGroup(*patrons[i::self.n_patron_columns]).arrange_submobjects( DOWN, buff=MED_SMALL_BUFF) for i in range(self.n_patron_columns) ]) columns.arrange_submobjects( RIGHT, buff=LARGE_BUFF, aligned_edge=UP, ) columns.scale_to_fit_width(total_width - 1) columns.next_to(black_rect, DOWN, 3 * LARGE_BUFF) columns.to_edge(RIGHT) self.play( columns.next_to, SPACE_HEIGHT * DOWN, UP, LARGE_BUFF, columns.to_edge, RIGHT, Animation(black_rect), rate_func=None, run_time=self.run_time, )
def generate_points(self): body = Cube(side_length = 1) for dim, scale_factor in enumerate(self.body_dimensions): body.stretch(scale_factor, dim = dim) body.scale_to_fit_width(self.width) body.set_fill(self.shaded_body_color, opacity = 1) body.sort_submobjects(lambda p : p[2]) body[-1].set_fill(self.body_color) keyboard = VGroup(*[ VGroup(*[ Square(**self.key_color_kwargs) for x in range(12-y%2) ]).arrange_submobjects(RIGHT, buff = SMALL_BUFF) for y in range(4) ]).arrange_submobjects(DOWN, buff = MED_SMALL_BUFF) keyboard.stretch_to_fit_width( self.keyboard_width_to_body_width*body.get_width(), ) keyboard.stretch_to_fit_height( self.keyboard_height_to_body_height*body.get_height(), ) keyboard.next_to(body, OUT, buff = 0.1*SMALL_BUFF) keyboard.shift(MED_SMALL_BUFF*UP) body.add(keyboard) screen_plate = body.copy() screen_plate.stretch(self.screen_thickness/self.body_dimensions[2], dim = 2) screen = Rectangle( stroke_width = 0, fill_color = BLACK, fill_opacity = 1, ) screen.replace(screen_plate, stretch = True) screen.scale_in_place(self.screen_width_to_screen_plate_width) screen.next_to(screen_plate, OUT, buff = 0.1*SMALL_BUFF) screen_plate.add(screen) screen_plate.next_to(body, UP, buff = 0) screen_plate.rotate( self.open_angle, RIGHT, about_point = screen_plate.get_bottom() ) self.screen_plate = screen_plate self.screen = screen axis = Line( body.get_corner(UP+LEFT+OUT), body.get_corner(UP+RIGHT+OUT), color = BLACK, stroke_width = 2 ) self.axis = axis self.add(body, screen_plate, axis) self.rotate(5*np.pi/12, LEFT) self.rotate(np.pi/6, DOWN)
def get_face_card_design(self, value, symbol): from topics.characters import PiCreature sub_rect = Rectangle( stroke_color = BLACK, fill_opacity = 0, height = 0.9*self.get_height(), width = 0.6*self.get_width(), ) sub_rect.move_to(self) # pi_color = average_color(symbol.get_color(), GREY) pi_color = symbol.get_color() pi_mode = { "J" : "plain", "Q" : "thinking", "K" : "hooray" }[value] pi_creature = PiCreature( mode = pi_mode, color = pi_color, ) pi_creature.scale_to_fit_width(0.8*sub_rect.get_width()) if value in ["Q", "K"]: prefix = "king" if value == "K" else "queen" crown = SVGMobject(file_name = prefix + "_crown") crown.set_stroke(width = 0) crown.set_fill(YELLOW, 1) crown.stretch_to_fit_width(0.5*sub_rect.get_width()) crown.stretch_to_fit_height(0.17*sub_rect.get_height()) crown.move_to(pi_creature.eyes.get_center(), DOWN) pi_creature.add_to_back(crown) to_top_buff = 0 else: to_top_buff = SMALL_BUFF*sub_rect.get_height() pi_creature.next_to(sub_rect.get_top(), DOWN, to_top_buff) # pi_creature.shift(0.05*sub_rect.get_width()*RIGHT) pi_copy = pi_creature.copy() pi_copy.rotate(np.pi, about_point = sub_rect.get_center()) return VGroup(sub_rect, pi_creature, pi_copy)
def generate_big_rectangle(self): height, width = self.zoomed_canvas_space_shape self.big_rectangle = Rectangle( height = height, width = width, color = self.square_color ) if self.zoomed_canvas_center is not None: self.big_rectangle.shift(self.zoomed_canvas_center) elif self.zoomed_canvas_corner is not None: self.big_rectangle.to_corner(self.zoomed_canvas_corner) self.add(self.big_rectangle)
def get_riemann_rectangles( self, graph, x_min = None, x_max = None, dx = 0.1, input_sample_type = "left", stroke_width = 1, stroke_color = BLACK, fill_opacity = 1, start_color = None, end_color = None, show_signed_area = True, width_scale_factor = 1.001 ): x_min = x_min if x_min is not None else self.x_min x_max = x_max if x_max is not None else self.x_max if start_color is None: start_color = self.default_riemann_start_color if end_color is None: end_color = self.default_riemann_end_color rectangles = VGroup() x_range = np.arange(x_min, x_max, dx) colors = color_gradient([start_color, end_color], len(x_range)) for x, color in zip(x_range, colors): if input_sample_type == "left": sample_input = x elif input_sample_type == "right": sample_input = x+dx else: raise Exception("Invalid input sample type") graph_point = self.input_to_graph_point(sample_input, graph) points = VGroup(*map(VectorizedPoint, [ self.coords_to_point(x, 0), self.coords_to_point(x+width_scale_factor*dx, 0), graph_point ])) rect = Rectangle() rect.replace(points, stretch = True) if graph_point[1] < self.graph_origin[1] and show_signed_area: fill_color = invert_color(color) else: fill_color = color rect.set_fill(fill_color, opacity = fill_opacity) rect.set_stroke(stroke_color, width = stroke_width) rectangles.add(rect) return rectangles
def get_riemann_rectangles(self, x_min = None, x_max = None, dx = 0.1, stroke_width = 1, start_color = BLUE, end_color = GREEN): assert(hasattr(self, "func")) x_min = x_min if x_min is not None else self.x_min x_max = x_max if x_max is not None else self.x_max rectangles = VGroup() for x in np.arange(x_min, x_max, dx): points = VGroup(*map(VectorizedPoint, [ self.coords_to_point(x, 0), self.coords_to_point(x+dx, self.func(x+dx)), ])) rect = Rectangle() rect.replace(points, stretch = True) rect.set_fill(opacity = 1) rectangles.add(rect) rectangles.gradient_highlight(start_color, end_color) rectangles.set_stroke(BLACK, width = stroke_width) return rectangles
def add_bars(self, values): buff = float(self.width) / (2*len(values) + 1) bars = VGroup() for i, value in enumerate(values): bar = Rectangle( height = (value/self.max_value)*self.height, width = buff, stroke_width = self.bar_stroke_width, fill_opacity = self.bar_fill_opacity, ) bar.move_to((2*i+1)*buff*RIGHT, DOWN+LEFT) bars.add(bar) bars.gradient_highlight(*self.bar_colors) bar_labels = VGroup() for bar, name in zip(bars, self.bar_names): label = TexMobject(str(name)) label.scale(self.bar_label_scale_val) label.next_to(bar, DOWN, SMALL_BUFF) bar_labels.add(label) self.add(bars, bar_labels) self.bars = bars self.bar_labels = bar_labels
def generate_points(self): self.add( Rectangle( height=self.height, width=self.height / self.height_to_width, stroke_color=WHITE, stroke_width=2, fill_color=self.color, fill_opacity=1, )) value = self.get_value() symbol = self.get_symbol() design = self.get_design(value, symbol) corner_numbers = self.get_corner_numbers(value, symbol) self.add(design, corner_numbers)
def rect_to_mobject(self, rect_element): if rect_element.hasAttribute("fill"): if Color(str(rect_element.getAttribute("fill"))) == Color(WHITE): return mob = Rectangle(width=float(rect_element.getAttribute("width")), height=float(rect_element.getAttribute("height")), stroke_width=0, fill_color=WHITE, fill_opacity=1.0) mob.shift(mob.get_center() - mob.get_corner(UP + LEFT)) return mob
def generate_points(self): self.add(Rectangle( height = self.height, width = self.height/self.height_to_width, stroke_color = WHITE, stroke_width = 2, fill_color = self.color, fill_opacity = 1, )) if self.turned_over: self.set_fill(DARK_GREY) self.set_stroke(LIGHT_GREY) contents = VectorizedPoint(self.get_center()) else: value = self.get_value() symbol = self.get_symbol() design = self.get_design(value, symbol) corner_numbers = self.get_corner_numbers(value, symbol) contents = VGroup(design, corner_numbers) self.design = design self.corner_numbers = corner_numbers self.add(contents)
def get_riemann_rectangles(self, x_min=None, x_max=None, dx=0.1, stroke_width=1, start_color=BLUE, end_color=GREEN): assert (hasattr(self, "func")) x_min = x_min if x_min is not None else self.x_min x_max = x_max if x_max is not None else self.x_max rectangles = VGroup() for x in np.arange(x_min, x_max, dx): points = VGroup(*map(VectorizedPoint, [ self.coords_to_point(x, 0), self.coords_to_point(x + dx, self.func(x + dx)), ])) rect = Rectangle() rect.replace(points, stretch=True) rect.set_fill(opacity=1) rectangles.add(rect) rectangles.gradient_highlight(start_color, end_color) rectangles.set_stroke(BLACK, width=stroke_width) return rectangles
def __init__(self, **kwargs): VGroup.__init__(self, **kwargs) full_space = Rectangle(**self.full_space_config) self.full_space = full_space self.add(full_space)
class ZoomedScene(Scene): """ Move around self.little_rectangle to determine which part of the screen is zoomed in on. """ CONFIG = { "zoomed_canvas_space_shape": (3, 3), "zoomed_canvas_center": None, "zoomed_canvas_corner": UP + RIGHT, "zoomed_canvas_corner_buff": DEFAULT_MOBJECT_TO_EDGE_BUFFER, "zoomed_camera_background": None, "little_rectangle_start_position": ORIGIN, "zoom_factor": 6, "square_color": WHITE, "zoom_activated": False, } def activate_zooming(self): self.generate_big_rectangle() self.setup_zoomed_canvas() self.setup_zoomed_camera() self.zoom_activated = True def animate_activate_zooming(self): self.activate_zooming() self.play(*map(FadeIn, [self.little_rectangle, self.big_rectangle])) def disactivate_zooming(self): self.remove(self.big_rectangle, self.little_rectangle) self.zoom_activated = False def get_zoomed_camera_mobject(self): return self.little_rectangle def get_zoomed_screen(self): return self.big_rectangle def generate_big_rectangle(self): height, width = self.zoomed_canvas_space_shape self.big_rectangle = Rectangle(height=height, width=width, color=self.square_color) if self.zoomed_canvas_center is not None: self.big_rectangle.shift(self.zoomed_canvas_center) elif self.zoomed_canvas_corner is not None: self.big_rectangle.to_corner(self.zoomed_canvas_corner, buff=self.zoomed_canvas_corner_buff) self.add(self.big_rectangle) def setup_zoomed_canvas(self): upper_left = self.big_rectangle.get_corner(UP + LEFT) lower_right = self.big_rectangle.get_corner(DOWN + RIGHT) pixel_coords = self.camera.points_to_pixel_coords( np.array([upper_left, lower_right])) self.zoomed_canvas_pixel_indices = pixel_coords (up, left), (down, right) = pixel_coords self.zoomed_canvas_pixel_shape = ( right - left, down - up, ) def setup_zoomed_camera(self): self.little_rectangle = self.big_rectangle.copy() self.little_rectangle.scale(1. / self.zoom_factor) self.little_rectangle.move_to(self.little_rectangle_start_position) self.zoomed_camera = MovingCamera( self.little_rectangle, pixel_shape=self.zoomed_canvas_pixel_shape, background=self.zoomed_camera_background) self.add(self.little_rectangle) #TODO, is there a better way to hanld this? self.zoomed_camera.adjusted_thickness = lambda x: x def get_frame(self): frame = Scene.get_frame(self) if self.zoom_activated: (up, left), (down, right) = self.zoomed_canvas_pixel_indices frame[left:right, up:down, :] = self.zoomed_camera.get_image() return frame def set_camera_pixel_array(self, pixel_array): self.camera.set_pixel_array(pixel_array) if self.zoom_activated: (up, left), (down, right) = self.zoomed_canvas_pixel_indices self.zoomed_camera.set_pixel_array(pixel_array[left:right, up:down]) def set_camera_background(self, background): self.set_camera_pixel_array(self, background) #TODO, check this... def reset_camera(self): self.camera.reset() if self.zoom_activated: self.zoomed_camera.reset() def capture_mobjects_in_camera(self, mobjects, **kwargs): self.camera.capture_mobjects(mobjects, **kwargs) if self.zoom_activated: if self.big_rectangle in mobjects: mobjects = list(mobjects) mobjects.remove(self.big_rectangle) self.zoomed_camera.capture_mobjects(mobjects, **kwargs) def separate_moving_and_static_mobjects(self, *animations): moving_mobjects, static_mobjects = Scene.separate_moving_and_static_mobjects( self, *animations) if self.zoom_activated and self.little_rectangle in moving_mobjects: # When the camera is moving, so is everything, return self.get_mobjects(), [] else: return moving_mobjects, static_mobjects
class ZoomedScene(Scene): CONFIG = { "zoomed_canvas_space_shape" : (3, 3), "zoomed_canvas_center" : None, "zoomed_canvas_corner" : UP+RIGHT, "zoomed_camera_background" : None, "zoom_factor" : 6, "square_color" : WHITE, "zoom_activated" : False, } def activate_zooming(self): self.generate_big_rectangle() self.setup_zoomed_canvas() self.setup_zoomed_camera() self.zoom_activated = True def disactivate_zooming(self): self.remove(self.big_rectangle, self.little_rectangle) self.zoom_activated = False def get_zoomed_camera_mobject(self): return self.little_rectangle def get_zoomed_screen(self): return self.big_rectangle def generate_big_rectangle(self): height, width = self.zoomed_canvas_space_shape self.big_rectangle = Rectangle( height = height, width = width, color = self.square_color ) if self.zoomed_canvas_center is not None: self.big_rectangle.shift(self.zoomed_canvas_center) elif self.zoomed_canvas_corner is not None: self.big_rectangle.to_corner(self.zoomed_canvas_corner) self.add(self.big_rectangle) def setup_zoomed_canvas(self): upper_left = self.big_rectangle.get_corner(UP+LEFT) lower_right = self.big_rectangle.get_corner(DOWN+RIGHT) pixel_coords = self.camera.points_to_pixel_coords( np.array([upper_left, lower_right]) ) self.zoomed_canvas_pixel_indices = pixel_coords (up, left), (down, right) = pixel_coords self.zoomed_canvas_pixel_shape = ( down-up, right-left ) def setup_zoomed_camera(self): self.little_rectangle = self.big_rectangle.copy() self.little_rectangle.scale(1./self.zoom_factor) self.little_rectangle.center() self.zoomed_camera = MovingCamera( self.little_rectangle, pixel_shape = self.zoomed_canvas_pixel_shape, background = self.zoomed_camera_background ) self.add(self.little_rectangle) #TODO, is there a better way to hanld this? self.zoomed_camera.adjusted_thickness = lambda x : x def get_frame(self): frame = Scene.get_frame(self) if self.zoom_activated: (up, left), (down, right) = self.zoomed_canvas_pixel_indices frame[left:right, up:down, :] = self.zoomed_camera.get_image() return frame def update_frame(self, *args, **kwargs): Scene.update_frame(self, *args, **kwargs) if self.zoom_activated: self.zoomed_camera.reset() self.zoomed_camera.capture_mobjects(self.mobjects)
class ZoomedScene(Scene): CONFIG = { "zoomed_canvas_space_shape": (3, 3), "zoomed_canvas_center": None, "zoomed_canvas_corner": UP + RIGHT, "zoomed_camera_background": None, "zoom_factor": 6, "square_color": WHITE, "zoom_activated": False, } def activate_zooming(self): self.generate_big_rectangle() self.setup_zoomed_canvas() self.setup_zoomed_camera() self.zoom_activated = True def disactivate_zooming(self): self.remove(self.big_rectangle, self.little_rectangle) self.zoom_activated = False def get_zoomed_camera_mobject(self): return self.little_rectangle def get_zoomed_screen(self): return self.big_rectangle def generate_big_rectangle(self): height, width = self.zoomed_canvas_space_shape self.big_rectangle = Rectangle(height=height, width=width, color=self.square_color) if self.zoomed_canvas_center is not None: self.big_rectangle.shift(self.zoomed_canvas_center) elif self.zoomed_canvas_corner is not None: self.big_rectangle.to_corner(self.zoomed_canvas_corner) self.add(self.big_rectangle) def setup_zoomed_canvas(self): upper_left = self.big_rectangle.get_corner(UP + LEFT) lower_right = self.big_rectangle.get_corner(DOWN + RIGHT) pixel_coords = self.camera.points_to_pixel_coords( np.array([upper_left, lower_right])) self.zoomed_canvas_pixel_indices = pixel_coords (up, left), (down, right) = pixel_coords self.zoomed_canvas_pixel_shape = (down - up, right - left) def setup_zoomed_camera(self): self.little_rectangle = self.big_rectangle.copy() self.little_rectangle.scale(1. / self.zoom_factor) self.little_rectangle.center() self.zoomed_camera = MovingCamera( self.little_rectangle, pixel_shape=self.zoomed_canvas_pixel_shape, background=self.zoomed_camera_background) self.add(self.little_rectangle) #TODO, is there a better way to hanld this? self.zoomed_camera.adjusted_thickness = lambda x: x def get_frame(self): frame = Scene.get_frame(self) if self.zoom_activated: (up, left), (down, right) = self.zoomed_canvas_pixel_indices frame[left:right, up:down, :] = self.zoomed_camera.get_image() return frame def update_frame(self, *args, **kwargs): Scene.update_frame(self, *args, **kwargs) if self.zoom_activated: self.zoomed_camera.reset() self.zoomed_camera.capture_mobjects(self.mobjects)