def viewing_rays(self, screen): lower_angle, upper_angle = self.viewing_angles(screen) projected_RIGHT = self.project( RIGHT) / np.linalg.norm(self.project(RIGHT)) lower_ray = rotate_vector( projected_RIGHT, lower_angle, axis=self.projection_direction()) upper_ray = rotate_vector( projected_RIGHT, upper_angle, axis=self.projection_direction()) return lower_ray, upper_ray
def viewing_rays(self, screen): lower_angle, upper_angle = self.viewing_angles(screen) projected_RIGHT = self.project(RIGHT) / get_norm(self.project(RIGHT)) lower_ray = rotate_vector(projected_RIGHT, lower_angle, axis=self.projection_direction()) upper_ray = rotate_vector(projected_RIGHT, upper_angle, axis=self.projection_direction()) return lower_ray, upper_ray
def generate_points(self): start_angle = np.pi/2 + self.arc_angle/2 end_angle = np.pi/2 - self.arc_angle/2 self.add(Arc( start_angle = start_angle, angle = -self.arc_angle )) tick_angle_range = np.linspace(start_angle, end_angle, self.num_ticks) for index, angle in enumerate(tick_angle_range): vect = rotate_vector(RIGHT, angle) tick = Line((1-self.tick_length)*vect, vect) label = TexMobject(str(10*index)) label.scale_to_fit_height(self.tick_length) label.shift((1+self.tick_length)*vect) self.add(tick, label) needle = Polygon( LEFT, UP, RIGHT, stroke_width = 0, fill_opacity = 1, fill_color = self.needle_color ) needle.stretch_to_fit_width(self.needle_width) needle.stretch_to_fit_height(self.needle_height) needle.rotate(start_angle - np.pi/2, about_point = ORIGIN) self.add(needle) self.needle = needle self.center_offset = self.get_center()
def generate_points(self): start_angle = np.pi / 2 + self.arc_angle / 2 end_angle = np.pi / 2 - self.arc_angle / 2 self.add(Arc( start_angle=start_angle, angle=-self.arc_angle )) tick_angle_range = np.linspace(start_angle, end_angle, self.num_ticks) for index, angle in enumerate(tick_angle_range): vect = rotate_vector(RIGHT, angle) tick = Line((1 - self.tick_length) * vect, vect) label = TexMobject(str(10 * index)) label.scale_to_fit_height(self.tick_length) label.shift((1 + self.tick_length) * vect) self.add(tick, label) needle = Polygon( LEFT, UP, RIGHT, stroke_width=0, fill_opacity=1, fill_color=self.needle_color ) needle.stretch_to_fit_width(self.needle_width) needle.stretch_to_fit_height(self.needle_height) needle.rotate(start_angle - np.pi / 2, about_point=ORIGIN) self.add(needle) self.needle = needle self.center_offset = self.get_center()
def place_labels(self, new_labels, **kwargs): # move if len(set(list(self.labels.keys()) + list(new_labels.keys()))) == 1: if len(new_labels) == 1: list(new_labels.values())[0].move_to(self.mobject.get_center()) elif len(self.labels) == 1: key, val = list(self.labels.items())[0] new_labels[key] = val.copy().move_to(self.mobject.get_center()) else: print("This should be impossible", file=sys.stderr) breakpoint(context=7) else: vec = rotate_vector(constants.RIGHT, numpy.pi / 2) vec *= LABELED_NODE_RADIUS / 2.4 * self.mobject.scale_factor old_label_copies = OrderedDict() for name, label in self.labels.items(): if name in new_labels: new_labels[name].move_to(self.mobject.get_center() + vec) else: old_label_copies[name] = \ label.copy().move_to( self.mobject.get_center() + vec) vec = rotate_vector( vec, 2 * numpy.pi / len(set( list(self.labels.keys()) + list(new_labels.keys())))) for name, label in new_labels.items(): if name in self.labels: pass else: label.move_to(self.mobject.get_center() + vec) vec = rotate_vector( vec, 2 * numpy.pi / len( set( list(self.labels.keys()) + list(new_labels.keys())))) ordered_labels = OrderedDict() for key in self.labels: if key in new_labels: ordered_labels[key] = new_labels[key] else: ordered_labels[key] = old_label_copies[key] for key in new_labels: if key not in self.labels: ordered_labels[key] = new_labels[key] new_labels = ordered_labels return new_labels
def fractalification_iteration(vmobject, dimension=1.05, num_inserted_anchors_range=range(1, 4)): num_points = vmobject.get_num_points() if num_points > 0: # original_anchors = vmobject.get_anchors() original_anchors = [ vmobject.point_from_proportion(x) for x in np.linspace(0, 1 - 1. / num_points, num_points) ] new_anchors = [] for p1, p2, in zip(original_anchors, original_anchors[1:]): num_inserts = random.choice(num_inserted_anchors_range) inserted_points = [ interpolate(p1, p2, alpha) for alpha in np.linspace(0, 1, num_inserts + 2)[1:-1] ] mass_scaling_factor = 1. / (num_inserts + 1) length_scaling_factor = mass_scaling_factor**(1. / dimension) target_length = np.linalg.norm(p1 - p2) * length_scaling_factor curr_length = np.linalg.norm(p1 - p2) * mass_scaling_factor #offset^2 + curr_length^2 = target_length^2 offset_len = np.sqrt(target_length**2 - curr_length**2) unit_vect = (p1 - p2) / np.linalg.norm(p1 - p2) offset_unit_vect = rotate_vector(unit_vect, np.pi / 2) inserted_points = [ point + u * offset_len * offset_unit_vect for u, point in zip(it.cycle([-1, 1]), inserted_points) ] new_anchors += [p1] + inserted_points new_anchors.append(original_anchors[-1]) vmobject.set_points_as_corners(new_anchors) vmobject.submobjects = [ fractalification_iteration(submob, dimension, num_inserted_anchors_range) for submob in vmobject.submobjects ] return vmobject
def fractalification_iteration(vmobject, dimension=1.05, num_inserted_anchors_range=range(1, 4)): num_points = vmobject.get_num_points() if num_points > 0: # original_anchors = vmobject.get_anchors() original_anchors = [ vmobject.point_from_proportion(x) for x in np.linspace(0, 1 - 1. / num_points, num_points) ] new_anchors = [] for p1, p2, in zip(original_anchors, original_anchors[1:]): num_inserts = random.choice(num_inserted_anchors_range) inserted_points = [ interpolate(p1, p2, alpha) for alpha in np.linspace(0, 1, num_inserts + 2)[1:-1] ] mass_scaling_factor = 1. / (num_inserts + 1) length_scaling_factor = mass_scaling_factor**(1. / dimension) target_length = np.linalg.norm(p1 - p2) * length_scaling_factor curr_length = np.linalg.norm(p1 - p2) * mass_scaling_factor # offset^2 + curr_length^2 = target_length^2 offset_len = np.sqrt(target_length**2 - curr_length**2) unit_vect = (p1 - p2) / np.linalg.norm(p1 - p2) offset_unit_vect = rotate_vector(unit_vect, np.pi / 2) inserted_points = [ point + u * offset_len * offset_unit_vect for u, point in zip(it.cycle([-1, 1]), inserted_points) ] new_anchors += [p1] + inserted_points new_anchors.append(original_anchors[-1]) vmobject.set_points_as_corners(new_anchors) vmobject.submobjects = [ fractalification_iteration( submob, dimension, num_inserted_anchors_range) for submob in vmobject.submobjects ] return vmobject
def __init__(self, n=3, **kwargs): digest_config(self, kwargs, locals()) start_vect = rotate_vector(RIGHT, self.start_angle) vertices = compass_directions(n, start_vect) Polygon.__init__(self, *vertices, **kwargs)
def move_to(self, point_or_mobject): vect = rotate_vector( UP+LEFT, self.orientation_line.get_angle() ) self.next_to(point_or_mobject, vect, buff = 0) return self
def move_to(self, point_or_mobject): vect = rotate_vector( UP + LEFT, self.orientation_line.get_angle() ) self.next_to(point_or_mobject, vect, buff=0) return self
def place_labels(self, new_labels, **kwargs): dic = kwargs.get("dic", OrderedDict()) label_location = dic.get("label_location", 0.5) label_side = dic.get("label_side", Side.CLOCKWISE) start, end = self.mobject.get_start_and_end() vec = start - end vec = vec / numpy.linalg.norm(vec) if label_side == Side.CLOCKWISE: vec = rotate_vector(vec, numpy.pi / 2) else: vec = rotate_vector(vec, 3 * numpy.pi / 2) buff = const.MED_SMALL_BUFF \ if self.mobject.curved \ else const.SMALL_BUFF last_mobject = None old_label_copies = OrderedDict() # move initially existing labels for name, label in self.labels.items(): if name in new_labels: # move the new label into place if last_mobject: new_labels[name].next_to(last_mobject, const.RIGHT, buff=buff) else: new_labels[name].next_to(interpolate( start, end, label_location), vec, buff=buff) else: # move the old label into place if last_mobject: old_label_copies[name] = label.copy().next_to(last_mobject, const.RIGHT, buff=buff) else: old_label_copies[name] = label.copy().next_to(interpolate( start, end, label_location), vec, buff=buff) last_mobject = label # move newly added labels into place for name, label in new_labels.items(): if name in self.labels: pass else: if last_mobject: label.next_to(last_mobject, const.RIGHT, buff=buff) else: label.next_to(interpolate(start, end, label_location), vec, buff=buff) last_mobject = label ordered_labels = OrderedDict() for key in self.labels: if key in new_labels: ordered_labels[key] = new_labels[key] else: ordered_labels[key] = old_label_copies[key] for key in new_labels: if key not in self.labels: ordered_labels[key] = new_labels[key] new_labels = ordered_labels return new_labels
def generate_mobject(self, dic, labels_dict): # Create a dictionary with all attributes to create a new Mobject. # Unspecified values will be filled from the current Mobject if it # exists, and with default values if not. if "stroke_width" not in dic: if hasattr(self, "mobject"): dic["stroke_width"] = self.mobject.stroke_width else: print("Attempted to initialize Edge without stroke_width") breakpoint(context=7) if "rectangular_stem_width" not in dic: if hasattr(self, "mobject"): dic["rectangular_stem_width"] = \ self.mobject.rectangular_stem_width else: print("Attempted to initialize Edge without " "rectangular_stem_width") breakpoint(context=7) if "scale_factor" not in dic: if hasattr(self, "mobject"): dic["scale_factor"] = self.mobject.scale_factor else: print("Attempted to initialize Edge without scale_factor") breakpoint(context=7) if "color" not in dic: if hasattr(self, "mobject"): dic["color"] = self.mobject.color if "directed" not in dic: if hasattr(self, "mobject") and self.mobject.directed: dic["directed"] = self.mobject.directed else: dic["directed"] = False if "curved" not in dic: if hasattr(self, "mobject") and self.mobject.curved: dic["curved"] = self.mobject.curved else: dic["curved"] = False # where along the edge the label is placed if "label_location" not in dic: if hasattr(self, "mobject") and self.mobject.label_location: dic["label_location"] = self.mobject.label_location else: dic["label_location"] = 0.5 # which side of the edge on which the label is placed if "label_side" not in dic: if hasattr(self, "mobject") and self.mobject.label_side: dic["label_side"] = self.mobject.label_side else: dic["label_side"] = Side.CLOCKWISE normalized_vec = self.end_node.mobject.get_center() - \ self.start_node.mobject.get_center() normalized_vec = normalized_vec / numpy.linalg.norm(normalized_vec) normal_vec = rotate_vector(normalized_vec, numpy.pi / 2) if dic["directed"]: mob = Arrow(self.start_node.mobject.get_center() + normalized_vec * (self.start_node.mobject.radius - 0.0), self.end_node.mobject.get_center() - normalized_vec * (self.end_node.mobject.radius - 0.0), buff=0, **dic) else: mob = Line( self.start_node.mobject.get_center() + normalized_vec * self.start_node.mobject.radius, self.end_node.mobject.get_center() - normalized_vec * self.end_node.mobject.radius, **dic) if dic["curved"]: start, end = mob.get_start_and_end() midpoint = (start + end) / 2 def f(x): return x - 0.1 * normal_vec * \ (numpy.linalg.norm(start - midpoint) - numpy.linalg.norm(x - midpoint)) mob.shift(-0.05 * normal_vec).apply_function(f) return mob