def add_white_keys(self): key = Rectangle(*self.white_key_dims) key.set_fill(self.white_key_color, 1) key.set_stroke(width=0) self.white_keys = key.get_grid(1, self.n_white_keys, buff=self.key_buff) self.add(*self.white_keys)
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 elif input_sample_type == "center": sample_input = x + 0.5 * dx else: raise Exception("Invalid input sample type") graph_point = self.input_to_graph_point(sample_input, graph) points = VGroup(*list(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, 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 elif input_sample_type == "center": sample_input = x + 0.5 * dx else: raise Exception("Invalid input sample type") graph_point = self.input_to_graph_point(sample_input, graph) points = VGroup(*list(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 add_black_keys(self): key = Rectangle(*self.black_key_dims) key.set_fill(self.black_key_color, 1) key.set_stroke(width=0) self.black_keys = VGroup() for i in range(len(self.white_keys) - 1): if i % self.white_keys_per_octave not in self.black_pattern: continue wk1 = self.white_keys[i] wk2 = self.white_keys[i + 1] bk = key.copy() bk.move_to(midpoint(wk1.get_top(), wk2.get_top()), UP) big_bk = bk.copy() big_bk.stretch((bk.get_width() + self.key_buff) / bk.get_width(), 0) big_bk.stretch((bk.get_height() + self.key_buff) / bk.get_height(), 1) big_bk.move_to(bk, UP) for wk in wk1, wk2: wk.become(Difference(wk, big_bk).match_style(wk)) self.black_keys.add(bk) self.add(*self.black_keys)
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): """ This method returns the VGroup() of the Riemann Rectangles for a particular curve. Parameters ---------- graph (ParametricFunction) The graph whose area needs to be approximated by the Riemann Rectangles. x_min Union[int,float] The lower bound from which to start adding rectangles x_max Union[int,float] The upper bound where the rectangles stop. dx Union[int,float] The smallest change in x-values that is considered significant. input_sample_type str Can be any of "left", "right" or "center stroke_width : Union[int, float] The stroke_width of the border of the rectangles. stroke_color : str The string of hex colour of the rectangle's border. fill_opacity Union[int, float] The opacity of the rectangles. start_color : str, The hex starting colour for the rectangles, this will, if end_color is a different colour, make a nice gradient. end_color : str, The hex ending colour for the rectangles, this will, if start_color is a different colour, make a nice gradient. show_signed_area : bool (True) Whether or not to indicate -ve area if curve dips below x-axis. width_scale_factor : Union[int, float] How much the width of the rectangles are scaled by when transforming. Returns ------- VGroup A VGroup containing the Riemann Rectangles. """ 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 elif input_sample_type == "center": sample_input = x + 0.5 * dx else: raise Exception("Invalid input sample type") graph_point = self.input_to_graph_point(sample_input, graph) points = VGroup(*list( 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
class Textbox(ControlMobject): CONFIG = { "value_type": np.dtype(object), "box_kwargs": { "width": 2.0, "height": 1.0, "fill_color": WHITE, "fill_opacity": 1.0, }, "text_kwargs": { "color": BLUE }, "text_buff": MED_SMALL_BUFF, "isInitiallyActive": False, "active_color": BLUE, "deactive_color": RED, } def __init__(self, value="", **kwargs): digest_config(self, kwargs) self.isActive = self.isInitiallyActive self.box = Rectangle(**self.box_kwargs) self.box.add_mouse_press_listner(self.box_on_mouse_press) self.text = Text(value, **self.text_kwargs) super().__init__(value, self.box, self.text, **kwargs) self.update_text(value) self.active_anim(self.isActive) self.add_key_press_listner(self.on_key_press) def set_value_anim(self, value): self.update_text(value) def update_text(self, value): text = self.text self.remove(text) text.__init__(value, **self.text_kwargs) height = text.get_height() text.set_width(self.box.get_width() - 2 * self.text_buff) if text.get_height() > height: text.set_height(height) text.add_updater(lambda mob: mob.move_to(self.box)) text.fix_in_frame() self.add(text) def active_anim(self, isActive): if isActive: self.box.set_stroke(self.active_color) else: self.box.set_stroke(self.deactive_color) def box_on_mouse_press(self, mob, event_data): self.isActive = not self.isActive self.active_anim(self.isActive) return False def on_key_press(self, mob, event_data): symbol = event_data["symbol"] modifiers = event_data["modifiers"] char = chr(symbol) if mob.isActive: old_value = mob.get_value() new_value = old_value if char.isalnum(): if (modifiers & PygletWindowKeys.MOD_SHIFT) or ( modifiers & PygletWindowKeys.MOD_CAPSLOCK): new_value = old_value + char.upper() else: new_value = old_value + char.lower() elif symbol in [PygletWindowKeys.SPACE]: new_value = old_value + char elif symbol == PygletWindowKeys.TAB: new_value = old_value + '\t' elif symbol == PygletWindowKeys.BACKSPACE: new_value = old_value[:-1] or '' mob.set_value(new_value) return False