def move(evt): if not evt.actor: return coords = line.points() coords[0] = evt.picked3d for i in range(1, n): v = versor(coords[i] - coords[i - 1]) coords[i] = coords[i - 1] + v * l line.points(coords) # update positions nodes.points(coords) plt.render()
def simulate(self): """ Runs the particle simulation. Simulates one time step, dt, of the particle motion. Calculates the force between each pair of particles and updates particles' motion accordingly """ # Main simulation loop for i in range(self.iterations): for a in self.particles: if a.fixed: continue ftot = vector(0, 0, 0) # total force acting on particle a for b in self.particles: if a.negligible and b.negligible or a == b: continue ab = a.pos - b.pos ftot += ((K_COULOMB * a.charge * b.charge) / mag2(ab)) * versor(ab) a.vel += ftot / a.mass * self.dt # update velocity and position of a a.pos += a.vel * self.dt a.vsphere.pos(a.pos) if vp: vp.show(zoom=1.2) vp.camera.Azimuth(0.1) # rotate camera
def simulate(self): """ Runs the particle simulation. Simulates one time step, dt, of the particle motion. Calculates the force between each pair of particles and updates their motion accordingly """ # Main simulation loop for i in range(self.iterations): for a in self.particles: if a.fixed: continue ftot = vector(0, 0, 0) # total force acting on particle a for b in self.particles: if a.negligible and b.negligible or a == b: continue ab = a.pos - b.pos ftot += ((K_COULOMB * a.charge * b.charge) / mag2(ab)) * versor(ab) a.vel += ftot / a.mass * self.dt # update velocity and position of a a.pos += a.vel * self.dt a.vsphere.pos(a.pos) if plt: plt.show(resetcam=not i, azimuth=1) if plt.escaped: break # if ESC is hit during the loop
gamma * x_dot_m[k]) y_dot[k] -= Dt * (Ks * (bob_y_m[k] - bob_y_m[k - 1]) * factor + gamma * y_dot_m[k] + g) for k in range(1, N): factor = fctr(dij_m[k + 1]) x_dot[k] -= Dt * Ks * (bob_x_m[k] - bob_x_m[k + 1]) * factor y_dot[k] -= Dt * Ks * (bob_y_m[k] - bob_y_m[k + 1]) * factor # Check to see if they are colliding for i in range(1, N): for j in range(i + 1, N + 1): dist2 = (bob_x[i] - bob_x[j])**2 + (bob_y[i] - bob_y[j])**2 if dist2 < DiaSq: # are colliding Ddist = np.sqrt(dist2) - 2 * R tau = versor([bob_x[j] - bob_x[i], bob_y[j] - bob_y[i], 0]) DR = Ddist / 2 * tau bob_x[i] += DR[0] # DR.x bob_y[i] += DR[1] # DR.y bob_x[j] -= DR[0] # DR.x bob_y[j] -= DR[1] # DR.y Vji = vector(x_dot[j] - x_dot[i], y_dot[j] - y_dot[i]) DV = np.dot(Vji, tau) * tau x_dot[i] += DV[0] # DV.x y_dot[i] += DV[1] # DV.y x_dot[j] -= DV[0] # DV.x y_dot[j] -= DV[1] # DV.y # Update the loations of the bobs and the stretching of the springs for k in range(1, N + 1): bob[k].pos([bob_x[k], bob_y[k], 0])
def reflection(p, pos): n = versor(pos) return np.dot(np.identity(3) - 2 * n * n[:, np.newaxis], p)
if a == 0: continue # exactly same velocities b = 2 * np.dot(pos[i] - pos[j], vj - vi) c = mag(pos[i] - pos[j])**2 - (ri + rj)**2 d = b**2 - 4.0 * a * c if d < 0: continue # something wrong; ignore this rare case deltat = (-b + np.sqrt(d)) / (2.0 * a ) # t-deltat is when they made contact pos[i] = pos[i] - (p[i] / mi) * deltat # back up to contact configuration pos[j] = pos[j] - (p[j] / mj) * deltat mtot = mi + mj pcmi = p[i] - ptot * mi / mtot # transform momenta to cm frame pcmj = p[j] - ptot * mj / mtot rrel = versor(pos[j] - pos[i]) pcmi = pcmi - 2 * np.dot(pcmi, rrel) * rrel # bounce in cm frame pcmj = pcmj - 2 * np.dot(pcmj, rrel) * rrel p[i] = pcmi + ptot * mi / mtot # transform momenta back to lab frame p[j] = pcmj + ptot * mj / mtot pos[i] = pos[i] + (p[i] / mi) * deltat # move forward deltat in time pos[j] = pos[j] + (p[j] / mj) * deltat # Bounce off the boundary of the torus for j in range(Natoms): poscircle[j] = versor(pos[j]) * RingRadius * [1, 1, 0] outside = np.greater_equal(mag(poscircle - pos), RingThickness - 2 * Ratom) for k in range(len(outside)): if outside[k] == 1 and np.dot(p[k], pos[k] - poscircle[k]) > 0: p[k] = reflection(p[k], pos[k] - poscircle[k])