1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| from manim import * import numpy as np
class v2_2(Scene): '''修改move_dot_and_draw_curve()方法,绘制余弦函数''' def construct(self): self.show_axis() self.show_circle() self.move_dot_and_draw_curve() self.wait(2) def show_axis(self): self.ratio = 1.2 self.axes = Axes(x_range=[0, 14, PI], y_range=[-3, 3], x_length=14 / self.ratio, y_length=6 / self.ratio, axis_config={"color": BLUE, "stroke_width": 3}, y_axis_config={'tick_size': 0}, tips=True).shift(RIGHT) labels = self.axes.get_axis_labels( Tex("x").scale(0.7), Text("y").scale(0.45)) self.add(self.axes, labels)
x_labels = [MathTex(r"\pi").scale(0.8), MathTex(r"2\pi").scale(0.8), MathTex(r"3\pi").scale(0.8), MathTex(r"4\pi").scale(0.8)] for i, label in enumerate(x_labels): label.move_to(self.axes.c2p((i+1) * PI, -0.3)) self.add(label)
self.curve_start = self.axes.get_origin()
x_start = self.axes.c2p(-2.5, 0) x_axis = Line(x_start, self.curve_start, color=BLUE, stroke_width=3) self.add(x_axis)
y_start, y_end = self.axes.c2p(-1, -2), self.axes.c2p(-1, 2) y_axis = DashedLine(y_start, y_end, color=GRAY) self.add(y_axis) self.unit_size = np.round(self.axes.x_axis.get_unit_size(), 2) def show_circle(self): self.origin_point = self.axes.c2p(-1, 0) origin_dot = Dot(self.origin_point, color=RED, radius=0.06 ).set_z_index(10)
self.circle = Circle(radius=self.unit_size, color=RED, stroke_width=3) self.circle.move_to(self.origin_point) self.add(origin_dot, self.circle)
def move_dot_and_draw_curve(self): """移动圆上的点并绘制余弦曲线"""
time_tracker = ValueTracker(0)
def update_dot_position(mob): angle = time_tracker.get_value() * TAU * 2 mob.move_to(self.circle.point_at_angle(angle))
dot = Dot(self.circle.point_at_angle(0), radius=0.08, color=YELLOW, z_index=10 ) dot.add_updater(update_dot_position) self.add(dot) radius_line = always_redraw(lambda: Line(self.origin_point, dot.get_center(), color=BLUE, stroke_width=2)) self.add(radius_line)
def update_curve_start_dot_position(mob): ''' 余弦线上动点的位置更新器: x 坐标为起点 + 圆动点转过的弧度 * 坐标轴比例; y 坐标为圆动点的 x 坐标(相对于圆心的坐标) ''' relative_x = dot.get_center()[0] - self.origin_point[0] x_pos = self.curve_start[0] + time_tracker.get_value() * TAU * 2 * self.unit_size y_pos = relative_x position = [x_pos, y_pos, 0] mob.move_to(position) curve_start_dot = Dot(self.axes.c2p(0, 1), color=BLUE, radius=0.08 ).set_z_index(10) curve_start_dot.add_updater(update_curve_start_dot_position) self.add(curve_start_dot)
connection_line = always_redraw(lambda: DashedLine(dot.get_center(), curve_start_dot.get_center(), color=YELLOW_A, stroke_width=2, dash_length=0.1)) self.add(connection_line)
self.cosine_curve = Line(curve_start_dot.get_center(), curve_start_dot.get_center(), color=YELLOW_D, stroke_width=3) def update_cosine_curve(mob): '''更新余弦曲线,添加新的点''' new_point = curve_start_dot.get_center() if len(self.cosine_curve.points) == 0 or np.linalg.norm(new_point - self.cosine_curve.get_end()) > 0.01: new_line = Line(self.cosine_curve.get_end(), new_point) self.cosine_curve.append_points(new_line.points)
self.cosine_curve.add_updater(update_cosine_curve) self.add(self.cosine_curve) equation = MathTex(r"y = \cos(x)", font_size=36, color=RED) equation.to_corner(UR, buff=0.5) self.add(equation) self.play(time_tracker.animate.set_value(1), rate_func=linear, run_time=9) dot.remove_updater(update_dot_position) curve_start_dot.remove_updater(update_curve_start_dot_position) self.cosine_curve.remove_updater(update_cosine_curve)
|