Published
Edited
Jul 18, 2018
1 fork
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
paths = {
noise.seed(seed)
const TAU = Math.PI * 2
const particles = []

//const W = 1000
//const H = 1000
const PERIOD = 1/frequency
const STEP = step
const PART_STEPS = part_steps

const SQN = 40
const NPART = SQN * SQN
const FINENESS = 1
const DAMPING = damping

/*
for (let i = 0; i < NPART; i++) {
particles.push({
x: ((i/SQN)|0)/SQN * W - W/2 + W/SQN/2,
y: (i%SQN)/SQN * H - H/2 + H/SQN/2,//Math.random() * H - H/2,//0 + Math.random() * 50,
})
}*/

for (let i = 0; i < NPART; i++) {
particles.push({
x: Math.random() * W - W/2,
y: Math.random() * H - H/2,//0 + Math.random() * 50,
})
}

const M = 0.3

//const f = (x) => Math.sign(x) * Math.sqrt(Math.abs(x))
const f = (x, y) => 5

const xfn = (n, x, y) => {
return Math.sin(n) //Math.sin(x / 10 / TAU) + n
}
const yfn = (n, x, y) => {
return Math.cos(n) //Math.cos(y / 10 / TAU) + n
}

const paths = particles.map(initial => {
let pa = []

let p = {x:initial.x, y:initial.y, vx:0, vy:0}
for (let i = 0; i < PART_STEPS * FINENESS; i++) {
const dist = Math.sqrt(p.x*p.x/500/500 + p.y*p.y/500/500)
const a = Math.atan2(p.y, p.x) + TAU/4
const n = noise.perlin2(p.x * PERIOD, p.y * PERIOD) * f(p.x, p.y)

p.vx += lerp(dist, xfn(n, p.x, p.y), Math.cos(a)) * STEP
p.vy += lerp(dist, yfn(n, p.x, p.y), Math.sin(a)) * STEP

p.x += p.vx / FINENESS
p.y += p.vy / FINENESS
p.vx *= DAMPING; p.vy *= DAMPING

pa.push([p.x, p.y])
if (p.x < -W || p.x > W || p.y < -H || p.y > H) break
}

return pa
})

return paths
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more