2018-10-03 18:59:01 +00:00
|
|
|
# from https://github.com/sklam/numba-example-wavephysics
|
|
|
|
# setup: N=100
|
|
|
|
# run: wave(N)
|
2018-04-05 22:07:33 +00:00
|
|
|
import numpy as np
|
2018-10-03 18:59:01 +00:00
|
|
|
|
2018-04-05 22:07:33 +00:00
|
|
|
|
|
|
|
def physics(masspoints, dt, plunk, which):
|
2018-10-03 18:59:01 +00:00
|
|
|
ppos = masspoints[1]
|
|
|
|
cpos = masspoints[0]
|
|
|
|
N = cpos.shape[0]
|
|
|
|
# apply hooke's law
|
2020-06-28 18:24:40 +00:00
|
|
|
HOOKE_K = 2100000.0
|
2018-10-03 18:59:01 +00:00
|
|
|
DAMPING = 0.0001
|
2020-06-28 18:24:40 +00:00
|
|
|
MASS = 0.01
|
2018-10-03 18:59:01 +00:00
|
|
|
|
|
|
|
force = np.zeros((N, 2))
|
|
|
|
for i in range(1, N):
|
|
|
|
dx, dy = cpos[i] - cpos[i - 1]
|
2020-06-28 18:24:40 +00:00
|
|
|
dist = np.sqrt(dx ** 2 + dy ** 2)
|
2018-10-03 18:59:01 +00:00
|
|
|
assert dist != 0
|
|
|
|
fmag = -HOOKE_K * dist
|
|
|
|
cosine = dx / dist
|
|
|
|
sine = dy / dist
|
|
|
|
fvec = np.array([fmag * cosine, fmag * sine])
|
|
|
|
force[i - 1] -= fvec
|
|
|
|
force[i] += fvec
|
|
|
|
|
|
|
|
force[0] = force[-1] = 0, 0
|
|
|
|
force[which][1] += plunk
|
|
|
|
accel = force / MASS
|
|
|
|
|
|
|
|
# verlet integration
|
2020-06-28 18:24:40 +00:00
|
|
|
npos = (2 - DAMPING) * cpos - (1 - DAMPING) * ppos + accel * (dt ** 2)
|
2018-10-03 18:59:01 +00:00
|
|
|
|
|
|
|
masspoints[1] = cpos
|
|
|
|
masspoints[0] = npos
|
|
|
|
|
2020-06-28 18:24:40 +00:00
|
|
|
|
2018-10-03 18:59:01 +00:00
|
|
|
# pythran export wave(int)
|
|
|
|
|
|
|
|
|
2018-04-05 22:07:33 +00:00
|
|
|
def wave(PARTICLE_COUNT):
|
|
|
|
SUBDIVISION = 300
|
|
|
|
FRAMERATE = 60
|
|
|
|
count = PARTICLE_COUNT
|
|
|
|
width, height = 1200, 400
|
|
|
|
|
|
|
|
masspoints = np.empty((2, count, 2), np.float64)
|
|
|
|
initpos = np.zeros(count, np.float64)
|
|
|
|
for i in range(1, count):
|
|
|
|
initpos[i] = initpos[i - 1] + float(width) / count
|
|
|
|
masspoints[:, :, 0] = initpos
|
|
|
|
masspoints[:, :, 1] = height / 2
|
|
|
|
f = 15
|
|
|
|
plunk_pos = count // 2
|
2020-06-28 18:24:40 +00:00
|
|
|
physics(masspoints, 1.0 / (SUBDIVISION * FRAMERATE), f, plunk_pos)
|
2018-04-05 22:07:33 +00:00
|
|
|
return masspoints[0, count // 2]
|