In [1]:
import k3d
import random
import numpy as np
import matplotlib

T = 1500
N = 10
P = 100
mod = 50

positions = [None] * N
colors = [None] * N
trajectories = [None] * N
colormaps = [k3d.colormaps.matplotlib_color_maps.hot]

for n in range(N):
positions[n] = {}
trajectories[n] = {}
bang = False

pos = np.zeros((P, 3), dtype=np.float32)
velocity = np.zeros((P, 3), dtype=np.float32)
velocity[:, 2] = 180.0 + np.random.random(P) * 0.1

pos[:, 0] = np.sin(n/N * 2.0 * np.pi) * 10.0
pos[:, 1] = np.cos(n/N * 2.0 * np.pi) * 10.0

cm = random.choice(colormaps)
cm_space = np.linspace(np.min(cm[0::4]), np.max(cm[0::4]), 2048)

c = (np.interp(cm_space, cm[::4], cm[3::4]) * 255).astype(np.uint32) + \
(np.interp(cm_space, cm[::4], cm[2::4]) * 255).astype(np.uint32) * 256 + \
(np.interp(cm_space, cm[::4], cm[1::4]) * 255).astype(np.uint32) * 256 ** 2

colors[n] = c[np.random.randint(0, c.shape[0], P)]

for t in range(T):
if t > n * 30:
if np.mean(velocity[:, 2] < 30.0) and not bang:
bang = True
velocity[:, 0] += np.random.normal(size=P) * 55
velocity[:, 1] += np.random.normal(size=P) * 55
velocity[:, 2] += np.random.normal(size=P) * 35

velocity[:, 2] -= 0.05
velocity *= 0.995
pos += velocity * 0.001

if t % mod == 0:
positions[n][str(t/100.0)] = pos.copy()

In [2]:
for n in range(N):
db = np.array([positions[n][k] for k in positions[n].keys()])

for t in range(T//mod):
anim = np.empty((P, T//mod + 1, 3), dtype=np.float32)
anim.fill(np.nan)
for p in range(P):
anim[p, 0:t+1, :] = db[0:t+1, p]
anim[p, t + 1, :] = anim[p, t, :]

trajectories[n][str(t * mod/100.0)] = anim

In [3]:
plot = k3d.plot(grid=[-100,-100,-100,100,100,100], grid_auto_fit=False, camera_auto_fit=False)

for n in range(N):
plot += k3d.points(positions[n], colors=colors[n], shader='3d', opacity=0.85, point_size=0.5)

text_positions= {
'0.0': np.array([0,0,100]),
'4.3': np.array([0,0,100]),
'4.8': np.array([0,0,20])
}

text_size= {
'0.0': 1,
'4.0': 1,
'4.8': 80
}

plot += k3d.texture_text('Happy New Year!', text_positions, size=text_size, color=0xaaaaaa)
plot.display()

In [4]:
plot.camera = [29.542883324245675,
-25.92168776472573,
5.31411376357905,
7.077758917185657,
-2.251048430642773,
15.430438268131883,
0.20569267725971274,
-0.2848548297554603,
0.9362415545609555]
plot.fps = 30

In [5]:
plot.start_auto_play()

In [ ]:
plot.stop_auto_play()