Published
Edited
Feb 24, 2021
1 star
Insert cell
md`# Untitled`
Insert cell
strokeWidth = 1.2
Insert cell
spacing = 100
Insert cell
gridsize = 100
Insert cell
seed = 10
Insert cell
svg`<svg
width="${width}px"
height="${height}px"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="${strokeWidth} ${strokeWidth} ${width -
2 * strokeWidth} ${height - strokeWidth}"
>
<g
stroke-linecap="round"
stroke-width="${strokeWidth}px"
fill="none"
stroke="black"
>
${paths.map((d, idx) => {
return `<path key="${idx}" d="${d}" />`;
})}
</g>
</svg>`
Insert cell
paths = pathsToSVGPaths(isoLines, {
width,
height,
units: 'px',
});
Insert cell
Insert cell
Insert cell
isoLines = drawIsoLines([0, width], [0, height])
Insert cell
function drawIsoLines([xMin, xMax], [yMin, yMax]) {
const sizeX = xMax - xMin;
const sizeY = yMax - yMin;
const offset = [xMin, yMin];
const intervals = linspace(spacing);
const gridSize = gridsize;
const lines = [];
let data = [];
Random.setSeed(seed);

// On a grid get noise data
for (let y = 0; y < gridSize; y++) {
data[y] = [];
for (let x = 0; x < gridSize; x++) {
const scale = gridSize;
const noiseValue = worleyNoiseField[y][x];
// const n = Random.noise2D(x / scale, y / scale);
// noise data has a range of -1 to 1, we remap it to 0 to 1
// data[y].push(mapRange(n, -1, 1, 0, 1));
data[y].push(noiseValue);
}
}

// At Equally spaced intervals, generate isoBands
intervals.forEach((_, idx) => {
if (idx > 0) {
const lowerBand = intervals[idx - 1];
const upperBand = intervals[idx];

isoBands(data, lowerBand, upperBand - lowerBand, {
successCallback(bands) {
bands.forEach(band => {
// The isoBand is generate in x: 0-gridsize and y: 0-gridsize
// Map that to the actual width and height of the image
const scaledBand = band.map(([x, y]) => [
offset[0] + mapRange(x, 0, gridSize - 1, 0, sizeX),
offset[1] + mapRange(y, 0, gridSize - 1, 0, sizeY)
]);

lines.push(scaledBand);
});
}
});
}
});

return lines;
}
Insert cell
Random = utils.random
Insert cell
mapRange = utils.math.mapRange
Insert cell
pathsToSVGPaths = utils.penplot.pathsToSVGPaths
Insert cell
linspace = utils.math.linspace
Insert cell
utils = require("https://bundle.run/canvas-sketch-util@1.10.0")
Insert cell
marchingSquares = require("marchingsquares")
Insert cell
isoBands = marchingSquares.isoBands
Insert cell
worley = require("worley-noise")
Insert cell
noise = new worley({ numPoints: 30 })
Insert cell
worleyNoiseField = {
const noiseValues = noise.renderImage(100, { normalize: true });
const noiseArray = [];

for (var y = 0; y < 100; ++y) {
noiseArray[y] = [];
for (var x = 0; x < 100; ++x) {
noiseArray[y][x] = noiseValues[y * 100 + x];
}
}
return noiseArray;
}
Insert cell
md`Need to create noise field image here`
Insert cell
noiseImage = {
const context = DOM.context2d(500, 500);

const imageData = context.getImageData(0, 0, 500, 500);
const pixels = imageData.data;
const noise = new worley({ numPoints: 30 });
const img = noise.renderImage(imageData.width, { normalize: true });

for (var y = 0; y < imageData.height; ++y) {
for (var x = 0; x < imageData.width; ++x) {
const base = (y * imageData.width + x) * 4;
pixels[base] = img[y * imageData.width + x] * 255;
pixels[base + 1] = img[y * imageData.width + x] * 255;
pixels[base + 2] = img[y * imageData.width + x] * 255;
pixels[base + 3] = 255;
}
}

context.putImageData(imageData, 0, 0);

return context.canvas;
}
Insert cell
{
let data = [];
for (let y = 0; y < 100; y++) {
data[y] = [];
for (let x = 0; x < 100; x++) {
const noiseValue = worleyNoiseField[x][y];
// const n = Random.noise2D(x / scale, y / scale);
// noise data has a range of -1 to 1, we remap it to 0 to 1
// data[y].push(mapRange(n, -1, 1, 0, 1));
data[y].push(noiseValue);
}
}
return data;
}
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