Published
Edited
Oct 11, 2022
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
colour_data = {
let yoff=0
let points =[]
for(let y=1;y<=height;y+=pix_size){ // y
let xoff = 0
for(let x=1;x<=width;x+=pix_size){ // x
points.push({x:x,y:y,n:simplex.noise2D(xoff,yoff)})
xoff+=eps*pix_size
}
yoff+=eps*pix_size
}
return points
}
Insert cell
pix_size = 10
Insert cell
Insert cell
plot_circles = {
let d = []
for (let i = 1; i <= lots_of_dots; ++i) { // number of circles to draw.
let x = d3.randomInt(10,width-10)()
let y = d3.randomInt(10,height-10)()
let v = curlNoise2D(x+eps,y-eps)
let c = ColourYscale(y)
d.push({x,y,vx:v[0],vy:v[1],c:c})
}
return d
}
Insert cell
Insert cell
ColourYscale = d3.scaleLinear()
.domain([0, height*0.25, height*0.75, height])
.range(["yellow", 'red','purple','DarkBlue'])
Insert cell
Insert cell
//eps = 0.005
Insert cell
function curlNoise2D(x, y){
//Find rate of change in X direction
var n1 = simplex.noise2D(x + eps, y);
var n2 = simplex.noise2D(x - eps, y);

//Average to find approximate derivative
var a = (n1 - n2)/(2 * eps);

//Find rate of change in Y direction
var n1 = simplex.noise2D(x, y + eps);
var n2 = simplex.noise2D(x, y - eps);

//Average to find approximate derivative
var b = (n1 - n2)/(2 * eps);

return [b, -a];
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof SVG_2D = {
const svg = d3.create('svg').attr("width", width).attr("height", height)

svg.append('rect')
.attr('x',0)
.attr('y',0)
.attr("width", width)
.attr("height", height)
.attr('fill','#caa') // default background


const sim = svg.append("g").attr('id','sim')
sim.selectAll('rect')
.data(colour_data)
.join("rect")
.attr('stroke','none') // to show rects
.attr("x", d => d.x)
.attr("y", d => d.y)
.attr("width", pix_size)
.attr("height", pix_size)
.attr('fill',d => `rgb(${nScale(d.n)},${nScale(d.n)},${nScale(d.n)})`)
svg.append("g").attr('id','flow')
return svg.node()
}
Insert cell
circles = {
d3.select('#flow')
.selectAll('circle')

.data(plot_circles)
.join("circle")
.attr('stroke','none')
.attr('stroke-width',0.5)
.attr('fill', d => d.c)
.attr("cx", d => {
let cn = curlNoise2D(d.x*eps,d.y*eps)
d.vx = cn[0]
d.vy = cn[1]
d.x += d.vx
d.y += d.vy
let o = t
return d.x
})
.attr("cy", d => d.y)
.attr('r',pix_size/2)

mutable t += 0.01
}
Insert cell
mutable t = 0
Insert cell
nScale = d3.scaleLinear()
.domain([-1,1]) // -1 1 but expanded to suit my data generated d3.extent(colour_data, d => d.n
.range([0,255])
Insert cell
Insert cell
height = width/2
Insert cell
Insert cell
simplex = new SimplexNoise(RndSeed)
Insert cell
SimplexNoise = require('simplex-noise@2.4.0')
Insert cell
import {Range, Select} from "@observablehq/inputs"
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