def generate_dual_graph(self): point_at_infinity = np.array([np.inf] * 3) cycles = self.graph.region_cycles self.dual_points = [ center_of_mass([self.points[index] for index in cycle]) for cycle in cycles ] self.dual_vertices = [ Dot(point).set_color("green") for point in self.dual_points ] self.dual_vertices[-1] = Circle().scale(FRAME_X_RADIUS + FRAME_Y_RADIUS) self.dual_points[-1] = point_at_infinity self.dual_edges = [] for pair in self.graph.edges: dual_point_pair = [] for cycle in cycles: if not (pair[0] in cycle and pair[1] in cycle): continue index1, index2 = cycle.index(pair[0]), cycle.index(pair[1]) if abs(index1 - index2) in [1, len(cycle) - 1]: dual_point_pair.append( self.dual_points[cycles.index(cycle)]) assert (len(dual_point_pair) == 2) for i in 0, 1: if all(dual_point_pair[i] == point_at_infinity): new_point = np.array(dual_point_pair[1 - i]) vect = center_of_mass([ self.points[pair[0]], self.points[pair[1]] ]) - new_point new_point += FRAME_X_RADIUS * vect / np.linalg.norm(vect) dual_point_pair[i] = new_point self.dual_edges.append(Line(*dual_point_pair).set_color())
def set_rectangular_stem_points(self): start, end = self.get_start_and_end() tip_base_points = self.tip[0].get_anchors()[1:3] tip_base = center_of_mass(tip_base_points) tbp1, tbp2 = tip_base_points perp_vect = tbp2 - tbp1 tip_base_width = get_norm(perp_vect) if tip_base_width > 0: perp_vect /= tip_base_width width = min( self.rectangular_stem_width, self.max_stem_width_to_tip_width_ratio * tip_base_width, ) if hasattr(self, "second_tip"): start = center_of_mass( self.second_tip.get_anchors()[1:] ) self.rect.set_points_as_corners([ tip_base - perp_vect * width / 2, start - perp_vect * width / 2, start + perp_vect * width / 2, tip_base + perp_vect * width / 2, ]) self.stem = self.rect # Alternate name return self
def set_rectangular_stem_points(self): start, end = self.get_start_and_end() tip_base_points = self.tip[0].get_anchors()[1:] tip_base = center_of_mass(tip_base_points) tbp1, tbp2 = tip_base_points perp_vect = tbp2 - tbp1 tip_base_width = np.linalg.norm(perp_vect) if tip_base_width > 0: perp_vect /= tip_base_width width = min( self.rectangular_stem_width, self.max_stem_width_to_tip_width_ratio * tip_base_width, ) if hasattr(self, "second_tip"): start = center_of_mass( self.second_tip.get_anchors()[1:] ) self.rect.set_points_as_corners([ tip_base + perp_vect * width / 2, start + perp_vect * width / 2, start - perp_vect * width / 2, tip_base - perp_vect * width / 2, ]) self.stem = self.rect # Alternate name return self
def generate_dual_graph(self): point_at_infinity = np.array([np.inf] * 3) cycles = self.graph.region_cycles self.dual_points = [ center_of_mass([ self.points[index] for index in cycle ]) for cycle in cycles ] self.dual_vertices = [ Dot(point).set_color("green") for point in self.dual_points ] self.dual_vertices[-1] = Circle().scale(FRAME_X_RADIUS + FRAME_Y_RADIUS) self.dual_points[-1] = point_at_infinity self.dual_edges = [] for pair in self.graph.edges: dual_point_pair = [] for cycle in cycles: if not (pair[0] in cycle and pair[1] in cycle): continue index1, index2 = cycle.index(pair[0]), cycle.index(pair[1]) if abs(index1 - index2) in [1, len(cycle) - 1]: dual_point_pair.append( self.dual_points[cycles.index(cycle)] ) assert(len(dual_point_pair) == 2) for i in 0, 1: if all(dual_point_pair[i] == point_at_infinity): new_point = np.array(dual_point_pair[1 - i]) vect = center_of_mass([ self.points[pair[0]], self.points[pair[1]] ]) - new_point new_point += FRAME_X_RADIUS * vect / np.linalg.norm(vect) dual_point_pair[i] = new_point self.dual_edges.append( Line(*dual_point_pair).set_color() )
def transform_points_pre_display(self, mobject, points): fixed_orientation = mobject in self.fixed_orientation_mobjects fixed_in_frame = mobject in self.fixed_in_frame_mobjects if fixed_in_frame: return points if fixed_orientation: center = center_of_mass(points) new_center = self.project_point(center) return points + (new_center - center) else: return self.project_points(points)
def get_anchor_points(self): step = float(self.radius) * self.start_step step /= (self.scale_factor**self.order) curr = np.zeros(3) result = [curr] for letter in self.get_command_string(): if letter is "+": step = rotate(step, self.angle) elif letter is "-": step = rotate(step, -self.angle) else: curr = curr + step result.append(curr) return np.array(result) - center_of_mass(result)
def get_number_design(self, value, symbol): num = int(value) n_rows = { 2: 2, 3: 3, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3, 9: 4, 10: 4, }[num] n_cols = 1 if num in [2, 3] else 2 insertion_indices = { 5: [0], 7: [0], 8: [0, 1], 9: [1], 10: [0, 2], }.get(num, []) top = self.get_top() + symbol.get_height() * DOWN bottom = self.get_bottom() + symbol.get_height() * UP column_points = [ interpolate(top, bottom, alpha) for alpha in np.linspace(0, 1, n_rows) ] design = VGroup( *[symbol.copy().move_to(point) for point in column_points]) if n_cols == 2: space = 0.2 * self.get_width() column_copy = design.copy().shift(space * RIGHT) design.shift(space * LEFT) design.add(*column_copy) design.add(*[ symbol.copy().move_to(center_of_mass(column_points[i:i + 2])) for i in insertion_indices ]) for symbol in design: if symbol.get_center()[1] < self.get_center()[1]: symbol.rotate_in_place(np.pi) return design