def handle_mathy(self, creatures): self.fade_all_but(creatures, 2) physy, compy, mathy = creatures v_color = YELLOW w_color = BLUE sum_color = GREEN v_arrow = Vector([1, 1]) w_arrow = Vector([2, 1]) w_arrow.shift(v_arrow.get_end()) sum_arrow = Vector(w_arrow.get_end()) arrows = VMobject(v_arrow, w_arrow, sum_arrow) arrows.scale(0.7) arrows.to_edge(LEFT, buff = 2) v_array = matrix_to_mobject([3, -5]) w_array = matrix_to_mobject([2, 1]) sum_array = matrix_to_mobject(["3+2", "-5+1"]) arrays = VMobject( v_array, TexMobject("+"), w_array, TexMobject("="), sum_array ) arrays.arrange_submobjects(RIGHT) arrays.scale(0.75) arrays.to_edge(RIGHT).shift(UP) v_sym = TexMobject("\\vec{\\textbf{v}}") w_sym = TexMobject("\\vec{\\textbf{w}}") syms = VMobject(v_sym, TexMobject("+"), w_sym) syms.arrange_submobjects(RIGHT) syms.center().shift(2*UP) statement = TextMobject("We'll ignore him \\\\ for now") statement.highlight(PINK) statement.scale_to_fit_width(arrays.get_width()) statement.next_to(arrays, DOWN, buff = 1.5) circle = Circle() circle.shift(syms.get_bottom()) VMobject(v_arrow, v_array, v_sym).highlight(v_color) VMobject(w_arrow, w_array, w_sym).highlight(w_color) VMobject(sum_arrow, sum_array).highlight(sum_color) self.play( Write(syms), Write(arrays), ShowCreation(arrows, submobject_mode = "one_at_a_time"), ApplyMethod(mathy.change_mode, "pondering"), run_time = 2 ) self.play(Blink(mathy)) self.add_scaling(arrows, syms, arrays) self.play(Write(statement)) self.play(ApplyMethod(mathy.change_mode, "sad")) self.wait() self.play( ShowCreation(circle), ApplyMethod(mathy.change_mode, "plain") ) self.wait()
def handle_mathy(self, creatures): self.fade_all_but(creatures, 2) physy, compy, mathy = creatures v_color = YELLOW w_color = BLUE sum_color = GREEN v_arrow = Vector([1, 1]) w_arrow = Vector([2, 1]) w_arrow.shift(v_arrow.get_end()) sum_arrow = Vector(w_arrow.get_end()) arrows = VMobject(v_arrow, w_arrow, sum_arrow) arrows.scale(0.7) arrows.to_edge(LEFT, buff = 2) v_array = matrix_to_mobject([3, -5]) w_array = matrix_to_mobject([2, 1]) sum_array = matrix_to_mobject(["3+2", "-5+1"]) arrays = VMobject( v_array, TexMobject("+"), w_array, TexMobject("="), sum_array ) arrays.arrange_submobjects(RIGHT) arrays.scale(0.75) arrays.to_edge(RIGHT).shift(UP) v_sym = TexMobject("\\vec{\\textbf{v}}") w_sym = TexMobject("\\vec{\\textbf{w}}") syms = VMobject(v_sym, TexMobject("+"), w_sym) syms.arrange_submobjects(RIGHT) syms.center().shift(2*UP) statement = TextMobject("We'll ignore him \\\\ for now") statement.highlight(PINK) statement.scale_to_fit_width(arrays.get_width()) statement.next_to(arrays, DOWN, buff = 1.5) circle = Circle() circle.shift(syms.get_bottom()) VMobject(v_arrow, v_array, v_sym).highlight(v_color) VMobject(w_arrow, w_array, w_sym).highlight(w_color) VMobject(sum_arrow, sum_array).highlight(sum_color) self.play( Write(syms), Write(arrays), ShowCreation(arrows, submobject_mode = "one_at_a_time"), ApplyMethod(mathy.change_mode, "pondering"), run_time = 2 ) self.play(Blink(mathy)) self.add_scaling(arrows, syms, arrays) self.play(Write(statement)) self.play(ApplyMethod(mathy.change_mode, "sad")) self.dither() self.play( ShowCreation(circle), ApplyMethod(mathy.change_mode, "plain") ) self.dither()
class NumberPlane(VMobject): CONFIG = { "color" : BLUE_D, "secondary_color" : BLUE_E, "axes_color" : WHITE, "secondary_stroke_width" : 1, "x_radius": None, "y_radius": None, "x_unit_size" : 1, "y_unit_size" : 1, "center_point" : ORIGIN, "x_line_frequency" : 1, "y_line_frequency" : 1, "secondary_line_ratio" : 1, "written_coordinate_height" : 0.2, "propagate_style_to_family" : False, } def generate_points(self): if self.x_radius is None: center_to_edge = (SPACE_WIDTH + abs(self.center_point[0])) self.x_radius = center_to_edge / self.x_unit_size if self.y_radius is None: center_to_edge = (SPACE_HEIGHT + abs(self.center_point[1])) self.y_radius = center_to_edge / self.y_unit_size self.axes = VMobject() self.main_lines = VMobject() self.secondary_lines = VMobject() tuples = [ ( self.x_radius, self.x_line_frequency, self.y_radius*DOWN, self.y_radius*UP, RIGHT ), ( self.y_radius, self.y_line_frequency, self.x_radius*LEFT, self.x_radius*RIGHT, UP, ), ] for radius, freq, start, end, unit in tuples: main_range = np.arange(0, radius, freq) step = freq/float(freq + self.secondary_line_ratio) for v in np.arange(0, radius, step): line1 = Line(start+v*unit, end+v*unit) line2 = Line(start-v*unit, end-v*unit) if v == 0: self.axes.add(line1) elif v in main_range: self.main_lines.add(line1, line2) else: self.secondary_lines.add(line1, line2) self.add(self.secondary_lines, self.main_lines, self.axes) self.stretch(self.x_unit_size, 0) self.stretch(self.y_unit_size, 1) self.shift(self.center_point) #Put x_axis before y_axis y_axis, x_axis = self.axes.split() self.axes = VMobject(x_axis, y_axis) def init_colors(self): VMobject.init_colors(self) self.axes.set_stroke(self.axes_color, self.stroke_width) self.main_lines.set_stroke(self.color, self.stroke_width) self.secondary_lines.set_stroke( self.secondary_color, self.secondary_stroke_width ) return self def get_center_point(self): return self.coords_to_point(0, 0) def coords_to_point(self, x, y): x, y = np.array([x, y]) result = self.axes.get_center() result += x*self.get_x_unit_size()*RIGHT result += y*self.get_y_unit_size()*UP return result def point_to_coords(self, point): new_point = point - self.axes.get_center() x = new_point[0]/self.get_x_unit_size() y = new_point[1]/self.get_y_unit_size() return x, y def get_x_unit_size(self): return self.axes.get_width() / (2.0*self.x_radius) def get_y_unit_size(self): return self.axes.get_height() / (2.0*self.y_radius) def get_coordinate_labels(self, x_vals = None, y_vals = None): coordinate_labels = VGroup() if x_vals == None: x_vals = range(-int(self.x_radius), int(self.x_radius)+1) if y_vals == None: y_vals = range(-int(self.y_radius), int(self.y_radius)+1) for index, vals in enumerate([x_vals, y_vals]): num_pair = [0, 0] for val in vals: if val == 0: continue num_pair[index] = val point = self.coords_to_point(*num_pair) num = TexMobject(str(val)) num.add_background_rectangle() num.scale_to_fit_height( self.written_coordinate_height ) num.next_to(point, DOWN+LEFT, buff = SMALL_BUFF) coordinate_labels.add(num) self.coordinate_labels = coordinate_labels return coordinate_labels def get_axes(self): return self.axes def get_axis_labels(self, x_label = "x", y_label = "y"): x_axis, y_axis = self.get_axes().split() quads = [ (x_axis, x_label, UP, RIGHT), (y_axis, y_label, RIGHT, UP), ] labels = VGroup() for axis, tex, vect, edge in quads: label = TexMobject(tex) label.add_background_rectangle() label.next_to(axis, vect) label.to_edge(edge) labels.add(label) self.axis_labels = labels return labels def add_coordinates(self, x_vals = None, y_vals = None): self.add(*self.get_coordinate_labels(x_vals, y_vals)) return self def get_vector(self, coords, **kwargs): point = coords[0]*RIGHT + coords[1]*UP arrow = Arrow(ORIGIN, coords, **kwargs) return arrow def prepare_for_nonlinear_transform(self, num_inserted_anchor_points = 50): for mob in self.family_members_with_points(): num_anchors = mob.get_num_anchor_points() if num_inserted_anchor_points > num_anchors: mob.insert_n_anchor_points(num_inserted_anchor_points-num_anchors) mob.make_smooth() return self def apply_function(self, function, maintain_smoothness = True): VMobject.apply_function(self, function, maintain_smoothness = maintain_smoothness)
class NumberPlane(VMobject): CONFIG = { "color" : BLUE_D, "secondary_color" : BLUE_E, "axes_color" : WHITE, "secondary_stroke_width" : 1, "x_radius": None, "y_radius": None, "x_unit_size" : 1, "y_unit_size" : 1, "center_point" : ORIGIN, "x_line_frequency" : 1, "y_line_frequency" : 1, "secondary_line_ratio" : 1, "written_coordinate_height" : 0.2, "propogate_style_to_family" : False, } def generate_points(self): if self.x_radius is None: center_to_edge = (SPACE_WIDTH + abs(self.center_point[0])) self.x_radius = center_to_edge / self.x_unit_size if self.y_radius is None: center_to_edge = (SPACE_HEIGHT + abs(self.center_point[1])) self.y_radius = center_to_edge / self.y_unit_size self.axes = VMobject() self.main_lines = VMobject() self.secondary_lines = VMobject() tuples = [ ( self.x_radius, self.x_line_frequency, self.y_radius*DOWN, self.y_radius*UP, RIGHT ), ( self.y_radius, self.y_line_frequency, self.x_radius*LEFT, self.x_radius*RIGHT, UP, ), ] for radius, freq, start, end, unit in tuples: main_range = np.arange(0, radius, freq) step = freq/float(freq + self.secondary_line_ratio) for v in np.arange(0, radius, step): line1 = Line(start+v*unit, end+v*unit) line2 = Line(start-v*unit, end-v*unit) if v == 0: self.axes.add(line1) elif v in main_range: self.main_lines.add(line1, line2) else: self.secondary_lines.add(line1, line2) self.add(self.secondary_lines, self.main_lines, self.axes) self.stretch(self.x_unit_size, 0) self.stretch(self.y_unit_size, 1) self.shift(self.center_point) #Put x_axis before y_axis y_axis, x_axis = self.axes.split() self.axes = VMobject(x_axis, y_axis) def init_colors(self): VMobject.init_colors(self) self.axes.set_stroke(self.axes_color, self.stroke_width) self.main_lines.set_stroke(self.color, self.stroke_width) self.secondary_lines.set_stroke( self.secondary_color, self.secondary_stroke_width ) return self def get_center_point(self): return self.coords_to_point(0, 0) def coords_to_point(self, x, y): x, y = np.array([x, y]) result = self.axes.get_center() result += x*self.get_x_unit_size()*RIGHT result += y*self.get_y_unit_size()*UP return result def point_to_coords(self, point): new_point = point - self.axes.get_center() x = new_point[0]/self.get_x_unit_size() y = new_point[1]/self.get_y_unit_size() return x, y def get_x_unit_size(self): return self.axes.get_width() / (2.0*self.x_radius) def get_y_unit_size(self): return self.axes.get_height() / (2.0*self.y_radius) def get_coordinate_labels(self, x_vals = None, y_vals = None): result = [] if x_vals == None and y_vals == None: x_vals = range(-int(self.x_radius), int(self.x_radius)) y_vals = range(-int(self.y_radius), int(self.y_radius)) for index, vals in enumerate([x_vals, y_vals]): num_pair = [0, 0] for val in vals: if val == 0: continue num_pair[index] = val point = self.coords_to_point(*num_pair) num = TexMobject(str(val)) num.add_background_rectangle() num.scale_to_fit_height( self.written_coordinate_height ) vect = DOWN if index == 0 else LEFT num.next_to(point, vect, buff = SMALL_BUFF) result.append(num) return result def get_axes(self): return self.axes def get_axis_labels(self, x_label = "x", y_label = "y"): x_axis, y_axis = self.get_axes().split() quads = [ (x_axis, x_label, UP, RIGHT), (y_axis, y_label, RIGHT, UP), ] labels = VGroup() for axis, tex, vect, edge in quads: label = TexMobject(tex) label.add_background_rectangle() label.next_to(axis, vect) label.to_edge(edge) labels.add(label) self.axis_labels = labels return labels def add_coordinates(self, x_vals = None, y_vals = None): self.add(*self.get_coordinate_labels(x_vals, y_vals)) return self def get_vector(self, coords, **kwargs): point = coords[0]*RIGHT + coords[1]*UP arrow = Arrow(ORIGIN, coords, **kwargs) return arrow def prepare_for_nonlinear_transform(self, num_inserted_anchor_points = 50): for mob in self.family_members_with_points(): num_anchors = mob.get_num_anchor_points() if num_inserted_anchor_points > num_anchors: mob.insert_n_anchor_points(num_inserted_anchor_points-num_anchors) mob.make_smooth() return self