def put_start_and_end_on_with_projection(self, new_start, new_end): target_vect = np.array(new_end) - np.array(new_start) curr_vect = self.get_vector() curr_norm = get_norm(curr_vect) if curr_norm == 0: self.put_start_and_end_on(new_start, new_end) return target_norm = get_norm(target_vect) if target_norm == 0: epsilon = 0.001 self.scale(epsilon / curr_norm) self.move_to(new_start) return unit_target = target_vect / target_norm unit_curr = curr_vect / curr_norm normal = np.cross(unit_target, unit_curr) if get_norm(normal) == 0: if unit_curr[0] == 0 and unit_curr[1] == 0: normal = UP else: normal = OUT angle_diff = np.arccos( np.clip(np.dot(unit_target, unit_curr), -1, 1) ) self.scale(target_norm / curr_norm) self.rotate(-angle_diff, normal) self.shift(new_start - self.get_start()) return self
def maximizing_input(network, layer_index, layer_vect, n_steps=100, seed_guess=None): pre_sig_layer_vect = sigmoid_inverse(layer_vect) weights, biases = network.weights, network.biases # guess = np.random.random(weights[0].shape[1]) if seed_guess is not None: pre_sig_guess = sigmoid_inverse(seed_guess.flatten()) else: pre_sig_guess = np.random.randn(weights[0].shape[1]) norms = [] for step in range(n_steps): activations = network.get_activation_of_all_layers( sigmoid(pre_sig_guess), layer_index) jacobian = np.diag(sigmoid_prime(pre_sig_guess).flatten()) for W, a, b in zip(weights, activations, biases): jacobian = np.dot(W, jacobian) a = a.reshape((a.size, 1)) sp = sigmoid_prime(np.dot(W, a) + b) jacobian = np.dot(np.diag(sp.flatten()), jacobian) gradient = np.dot( np.array(layer_vect).reshape((1, len(layer_vect))), jacobian).flatten() norm = get_norm(gradient) if norm == 0: break norms.append(norm) old_pre_sig_guess = np.array(pre_sig_guess) pre_sig_guess += 0.1 * gradient print(get_norm(old_pre_sig_guess - pre_sig_guess)) print("") return sigmoid(pre_sig_guess)
def set_tip_points( self, tip, add_at_end=True, tip_length=None, preserve_normal=True, ): if tip_length is None: tip_length = self.tip_length if preserve_normal: normal_vector = self.get_normal_vector() else: normal_vector = self.normal_vector line_length = get_norm(self.points[-1] - self.points[0]) tip_length = min(tip_length, self.max_tip_length_to_length_ratio * line_length) indices = (-2, -1) if add_at_end else (1, 0) pre_end_point, end_point = [ self.get_anchors()[index] for index in indices ] vect = end_point - pre_end_point perp_vect = np.cross(vect, normal_vector) for v in vect, perp_vect: if get_norm(v) == 0: v[0] = 1 v *= tip_length / get_norm(v) ratio = self.tip_width_to_length_ratio tip.set_points_as_corners([ end_point, end_point - vect + perp_vect * ratio / 2, end_point - vect - perp_vect * ratio / 2, ]) return self
def position_endpoints_on(self, start, end): curr_vect = self.points[-1] - self.points[0] if np.all(curr_vect == 0): raise Exception("Cannot position endpoints of closed loop") target_vect = end - start self.scale(get_norm(target_vect) / get_norm(curr_vect)) self.rotate(angle_of_vector(target_vect) - angle_of_vector(curr_vect)) self.shift(start - self.points[0]) return self
def position_endpoints_on(self, start, end): if any(self.points[:, 2]): raise RuntimeError("Mobject.position_endpoints_on() does not work " "with Mobjects that have depth") curr_vect = self.points[-1] - self.points[0] if np.all(curr_vect == 0): raise Exception("Cannot position endpoints of closed loop") target_vect = end - start self.scale(get_norm(target_vect) / get_norm(curr_vect)) self.rotate( angle_of_vector(target_vect) - angle_of_vector(curr_vect) ) self.shift(start - self.points[0]) return self
def __init__(self, start_point, end_point, angle=TAU / 4, **kwargs): if angle == 0: raise Exception("Arc with zero curve angle: use Line instead.") midpoint = 0.5 * (start_point + end_point) distance_vector = end_point - start_point normal_vector = np.array([-distance_vector[1], distance_vector[0], 0]) distance = get_norm(normal_vector) normal_vector /= distance if angle < 0: normal_vector *= -1 radius = distance / 2 / np.sin(0.5 * np.abs(angle)) length = distance / 2 / np.tan(0.5 * np.abs(angle)) arc_center = midpoint + length * normal_vector w = start_point - arc_center if w[0] != 0: start_angle = np.arctan2(w[1], w[0]) else: start_angle = np.pi / 2 Arc.__init__(self, angle, radius=radius, start_angle=start_angle, **kwargs) self.move_arc_center_to(arc_center)
def get_arc_center(self): first_point = self.points[0] last_point = self.points[-2] v = last_point - first_point radial_unit_vector = v / get_norm(v) arc_center = first_point - self.inner_radius * radial_unit_vector return arc_center
def get_unit_vector(self): vect = self.get_vector() norm = get_norm(vect) if norm == 0: # TODO, is this the behavior I want? return np.array(ORIGIN) return vect / norm
def get_arc_length(self): if self.path_arc: anchors = self.get_anchors() return sum( [get_norm(a2 - a1) for a1, a2 in zip(anchors, anchors[1:])]) else: return self.get_length()
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 get_vector_movement(self, func): for v in self.moving_vectors: v.target = Vector(func(v.get_end()), color=v.get_color()) norm = get_norm(v.target.get_end()) if norm < 0.1: v.target.get_tip().scale_in_place(norm) return self.get_piece_movement(self.moving_vectors)
def get_vector_label(self, vector, label, at_tip=False, direction="left", rotate=False, color=None, label_scale_factor=VECTOR_LABEL_SCALE_FACTOR): if not isinstance(label, TexMobject): if len(label) == 1: label = "\\vec{\\textbf{%s}}" % label label = TexMobject(label) if color is None: color = vector.get_color() label.set_color(color) label.scale(label_scale_factor) label.add_background_rectangle() if at_tip: vect = vector.get_vector() vect /= get_norm(vect) label.next_to(vector.get_end(), vect, buff=SMALL_BUFF) else: angle = vector.get_angle() if not rotate: label.rotate(-angle, about_point=ORIGIN) if direction is "left": label.shift(-label.get_bottom() + 0.1 * UP) else: label.shift(-label.get_top() + 0.1 * DOWN) label.rotate(angle, about_point=ORIGIN) label.shift((vector.get_end() - vector.get_start()) / 2) return label
def add_tip(self): start, end = self.main_line.get_start_and_end() vect = (end - start) / get_norm(end - start) arrow = Arrow(start, end + MED_SMALL_BUFF * vect, buff=0) tip = arrow.tip tip.set_color(self.color) self.tip = tip self.add(tip)
def get_normal_vector(self): p0, p1, p2 = self.tip[0].get_anchors()[:3] result = np.cross(p2 - p1, p1 - p0) norm = get_norm(result) if norm == 0: return self.normal_vector else: return result / norm
def look(self, direction): norm = get_norm(direction) if norm == 0: return direction /= norm self.purposeful_looking_direction = direction for pupil, eye in zip(self.pupils.split(), self.eyes.split()): c = eye.get_center() right = eye.get_right() - c up = eye.get_top() - c vect = direction[0] * right + direction[1] * up v_norm = get_norm(vect) p_radius = 0.5 * pupil.get_width() vect *= (v_norm - 0.75 * p_radius) / v_norm pupil.move_to(c + vect) self.pupils[1].align_to(self.pupils[0], DOWN) return self
def __init__(self, car, target_point, **kwargs): assert isinstance(car, Car) ApplyMethod.__init__(self, car.move_to, target_point, **kwargs) displacement = self.target_mobject.get_right( ) - self.starting_mobject.get_right() distance = get_norm(displacement) if not self.moving_forward: distance *= -1 tire_radius = car.get_tires()[0].get_width() / 2 self.total_tire_radians = -distance / tire_radius
def path_along_arc(arc_angle, axis=OUT): """ If vect is vector from start to end, [vect[:,1], -vect[:,0]] is perpendicular to vect in the left direction. """ if abs(arc_angle) < STRAIGHT_PATH_THRESHOLD: return straight_path if get_norm(axis) == 0: axis = OUT unit_axis = axis / get_norm(axis) def path(start_points, end_points, alpha): vects = end_points - start_points centers = start_points + 0.5 * vects if arc_angle != np.pi: centers += np.cross(unit_axis, vects / 2.0) / np.tan(arc_angle / 2) rot_matrix = rotation_matrix(alpha * arc_angle, unit_axis) return centers + np.dot(start_points - centers, rot_matrix.T) return path
def set_submobject_colors_by_radial_gradient(self, center=None, radius=1, inner_color=WHITE, outer_color=BLACK): if center is None: center = self.get_center() for mob in self.family_members_with_points(): t = get_norm(mob.get_center() - center) / radius t = min(t, 1) mob_color = interpolate_color(inner_color, outer_color, t) mob.set_color(mob_color, family=False) return self
def add_line(self, start, end, color=None): start, end = list(map(np.array, [start, end])) length = get_norm(end - start) if length == 0: points = [start] else: epsilon = self.epsilon / length points = [ interpolate(start, end, t) for t in np.arange(0, 1, epsilon) ] self.add_points(points, color=color)
def get_3d_vmob_unit_normal(vmob, point_index): n_points = vmob.get_num_points() if len(vmob.get_anchors()) <= 2: return np.array(UP) i = point_index im3 = i - 3 if i > 2 else (n_points - 4) ip3 = i + 3 if i < (n_points - 3) else 3 unit_normal = get_unit_normal( vmob.points[ip3] - vmob.points[i], vmob.points[im3] - vmob.points[i], ) if get_norm(unit_normal) == 0: return np.array(UP) return unit_normal
def get_3d_vmob_unit_normal(vmob, point_index): n_points = vmob.get_num_points() if len(vmob.get_anchors()) <= 2: return np.array(UP) i = point_index im1 = i - 1 if i > 0 else (n_points - 2) ip1 = i + 1 if i < (n_points - 1) else 1 unit_normal = get_unit_normal( vmob.points[ip1] - vmob.points[i], vmob.points[im1] - vmob.points[i], ) if get_norm(unit_normal) == 0: return np.array(UP) return unit_normal
def generate_points(self): length = get_norm(self.end - self.start) if length == 0: self.add(Line(self.start, self.end)) return self num_interp_points = int(length / self.dashed_segment_length) # Even number ensures that start and end points are hit if num_interp_points % 2 == 1: num_interp_points += 1 points = [ interpolate(self.start, self.end, alpha) for alpha in np.linspace(0, 1, num_interp_points) ] includes = it.cycle([True, False]) self.submobjects = [ Line(p1, p2, **self.init_kwargs) for p1, p2, include in zip(points, points[1:], includes) if include ] self.put_start_and_end_on_with_projection(self.start, self.end) return self
def align_to(self, mobject_or_point, direction=ORIGIN, alignment_vect=UP): """ Examples: mob1.align_to(mob2, UP) moves mob1 vertically so that its top edge lines ups with mob2's top edge. mob1.align_to(mob2, alignment_vector = RIGHT) moves mob1 horizontally so that it's center is directly above/below the center of mob2 """ if isinstance(mobject_or_point, Mobject): mob = mobject_or_point target_point = mob.get_critical_point(direction) else: target_point = mobject_or_point direction_norm = get_norm(direction) if direction_norm > 0: alignment_vect = np.array(direction) / direction_norm reference_point = self.get_critical_point(direction) else: reference_point = self.get_center() diff = target_point - reference_point self.shift(alignment_vect * np.dot(diff, alignment_vect)) return self
def distance_from_left(p): return np.dot(p - left_point, full_vect) / get_norm(full_vect)
def is_closed(points): return get_norm(points[0] - points[-1]) < CLOSED_THRESHOLD
def get_length(self): start, end = self.get_start_and_end() return get_norm(start - end)
def get_direction(self): vect = self.get_tip() - self.get_center() return vect / get_norm(vect)
def func(point): centered = point + vect return radius * centered / get_norm(centered)