@ti.kernel defsimulate(): # 计算受力和速度 for i in range(resolution * resolution): v[i] *= ti.exp(-dt * damping) f = gravity * mass + ef for j in range(resolution * resolution): if l[i, j] != 0: # 胡克定律 dis = ti.sqrt((x[i] - x[j]).dot(x[i] - x[j])) f += -stiffness * (dis - l[i, j]) * (x[i] - x[j]) / dis v[i] += f / mass * dt # 固定住上边两个质点 v[0] = [0, 0] v[resolution - 1] = [0, 0] # 更新位置 for i in range(resolution * resolution): x[i] += v[i] * dt
# 初始化 s = 0.6 / (resolution - 1) for i in range(resolution): for j in range(resolution - 1): l[i*resolution+j, i*resolution+j+1] = s * 0.6 l[i*resolution+j+1, i*resolution+j] = s * 0.6 l[j*resolution+i, (j+1)*resolution+i] = s * 0.6 l[(j+1)*resolution+i, j*resolution+i] = s * 0.6 for i in range(resolution): for j in range(resolution): x[j*resolution+i] = [0.2+i*s, 0.8+j*-s]
gravity[None] = [0, -9.8]
gui = ti.GUI('Mass Spring System') whileTrue: # 处理事件 for e in gui.get_events(): if e.key == ti.GUI.ESCAPE: exit() elif e.key == ti.GUI.LMB and e.type == ti.GUI.PRESS: ef[None] = [(e.pos[0] - 0.5) * 20.0, (e.pos[1] - 0.5) * 20.0] elif e.key == ti.GUI.LMB and e.type == ti.GUI.RELEASE: ef[None] = [0, 0] # 模拟 for step in range(10): simulate() # GUI显示 pos = x.to_numpy() gui.circles(pos, radius=5) for i in range(resolution): for j in range(resolution-1): gui.line(pos[i*resolution+j], pos[i*resolution+j+1], radius=1) gui.line(pos[j*resolution+i], pos[(j+1)*resolution+i], radius=1) gui.show()