Published
Edited
Nov 29, 2020
Importers
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cameraPosition = ({
x: dist * cos(alpha) * cos(beta),
y: dist * sin(beta),
z: dist * sin(alpha) * cos(beta),
})
Insert cell
pixelSize = tan(fov / 2) / ((rows - 1) / 2)
Insert cell
c = ({
rows,
cols: rows,
scaleX: 1,
scaleY: 1,
camX: dist * cos(alpha) * cos(beta),
camY: dist * sin(beta),
camZ: dist * sin(alpha) * cos(beta),
ux: -pixelSize * sin(alpha),
uz: +pixelSize * cos(alpha),
vx: +pixelSize * cos(alpha) * sin(beta),
vy: -pixelSize * cos(beta),
vz: +pixelSize * sin(alpha) * sin(beta),
x0: -cos(alpha) * cos(beta),
y0: -sin(beta),
z0: -sin(alpha) * cos(beta),
})
Insert cell
mat = ({
x: [
c.x0 - c.cols / 2 * c.scaleX * c.ux - c.rows / 2 * c.scaleY * c.vx + 0.02,
c.scaleX * c.ux * c.rows,
c.scaleY * c.vx * c.cols,
],
y: [
c.y0 - c.rows / 2 * c.scaleY * c.vy + 0.05,
0,
c.scaleY * c.vy * c.cols,
],
z: [
c.z0 - c.cols / 2 * c.scaleX * c.uz - c.rows / 2 * c.scaleY * c.vz,
c.scaleX * c.uz * c.rows,
c.scaleY * c.vz * c.cols,
],
})
Insert cell
Insert cell
normFunctions = ({
euclid: "Math.sqrt(nx ** 2 + ny ** 2 + nz ** 2) * 1.6",
manhattan: "Math.abs(nx) + Math.abs(ny) + Math.abs(nz)",
sum: "nx + ny + nz",
const: "1.7",
})
Insert cell
getPixel = new Function('row', 'col', `\
const nx = ${float(mat.x[0])} + col * ${float(mat.x[1])} + row * ${float(mat.x[2])};
const ny = ${float(mat.y[0])} + row * ${float(mat.y[2])};
const nz = ${float(mat.z[0])} + col * ${float(mat.z[1])} + row * ${float(mat.z[2])};
const n = ${normFunctions[pixelRayLengthNorm]};

let v = 0;
for (let iter=0; iter<${itersCount}; iter++) {
const x = ${float(cameraPosition.x)} + v * nx / n;
const y = ${float(cameraPosition.y)} + v * ny / n;
const z = ${float(cameraPosition.z)} + v * nz / n;
v += ${sdfSource};
}

return (v - ${float(objectMinDistToCamera)}) / ${float(objectMaxDistToCamera - objectMinDistToCamera)};\
`)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
float = v => v.toFixed(2)
Insert cell
function range(n) {
const res = [];
for (let i=0; i<n; i++) {
res.push(i);
}
return res;
}
Insert cell
function grid(data, rows, cols, maxVal=1) {
const gamma = 0.6; // gamma correction
const ctx = DOM.context2d(width / 2, width / 2);
ctx.fillStyle = 'lightgrey';
ctx.fillRect(0, 0, width, width);
ctx.scale(width / 2 / cols, width / 2 / rows);
for (let row=0; row<rows; row++) {
for (let col=0; col<cols; col++) {
const grey = Math.round(Math.max(0, Math.min(1, data[row][col] / maxVal)) ** gamma * 255);
ctx.fillStyle = `rgba(${grey}, ${grey}, ${grey})`;
ctx.fillRect(col, row, 1, 1);
}
}
return ctx.canvas;
}
Insert cell
Insert cell
Insert cell
Insert cell
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