Source code for manim_pymunk.custom_mobjects.v_spring
import numpy as np
from manim import *
[docs]
class VSpring(Line):
def __init__(
self,
start=LEFT,
end=RIGHT,
turns=18,
amplitude=0.1,
end_length=0.2,
stroke_width=1,
color=WHITE,
**kwargs
):
self.turns = turns
self.amplitude = amplitude
self.end_length = end_length
# 注意:Line 内部会调用 generate_points()
super().__init__(start, end, stroke_width=stroke_width, color=color, **kwargs)
[docs]
def generate_points(self):
"""重写 generate_points,使其不再生成直线,而是生成螺旋线"""
# 1. 计算当前起点和终点的距离
start = self._pointify(self.start)
end = self._pointify(self.end)
vec = end - start
total_dist = np.linalg.norm(vec)
# 避免除零错误
if total_dist < 0.001:
self.set_points_as_corners([start, end])
return
# 2. 在水平方向(x轴)生成螺旋点集
helix_dist = max(total_dist - 2 * self.end_length, 0.01)
points = []
# 起始端子
points.append([0, 0, 0])
points.append([self.end_length, 0, 0])
# 螺旋部分
num_steps = self.turns * 12
for i in range(num_steps + 1):
t = i / num_steps
angle = 2 * PI * self.turns * t
x = self.end_length + t * helix_dist
# 渐收系数,确保与端子水平衔接
taper = 1.0
if t < 0.1: taper = t / 0.1
elif t > 0.9: taper = (1 - t) / 0.1
y = self.amplitude * np.sin(angle) * taper
points.append([x, y, 0])
# 结束端子
points.append([self.end_length + helix_dist + self.end_length, 0, 0])
# 3. 将生成的水平点集应用变换,对齐到 start -> end 向量
self.set_points_as_corners(points)
self.make_smooth() # 产生平滑的螺旋效果
# 旋转和平移
target_angle = angle_of_vector(vec)
self.rotate(target_angle, about_point=ORIGIN)
self.shift(start)
[docs]
def put_start_and_end_on(self, start, end):
"""当位置改变时(如被 Updater 调用),重新生成点"""
self.start = np.array(start)
self.end = np.array(end)
self.generate_points()
return self