Public
Edited
Oct 26, 2023
31 stars
Insert cell
Insert cell
Insert cell
Insert cell
{
const ratio = Math.min(2.5, width / tin.width), ctx = DOM.context2d(tin.width * ratio, tin.height * ratio);
await visibility();

const T = new Uint8Array(tin.triangles.length / 3); // lookup table for visited triangles
const V = new Uint8Array(tin.coords.length / 2); // lookup table for visited vertices
let numVisited = 0;

for (let i = 0; i < tin.halfedges.length; i++) { // mark all boundary vertices as visited
if (tin.halfedges[i] === -1) V[tin.triangles[i]] = 1;
}

const queue = [];
let h = startingHalfedge; // start with an arbitrary half-edge
while (h !== undefined) {
const h0 = h % 3 === 0 ? h + 2 : h - 1; // previous half-edge in a triangle
const h1 = h % 3 === 2 ? h - 2 : h + 1; // next half-edge in a triangle

const v = tin.triangles[h0]; // tip of the triangle
const l = tin.halfedges[h0]; // half-edge of an adjacent triangle on the left
const r = tin.halfedges[h1]; // half-edge of an adjacent triangle on the right
const t = Math.floor(h / 3); // triangle index
const tipVisited = V[v];
const leftVisited = l === -1 || T[Math.floor(l / 3)];
const rightVisited = r === -1 || T[Math.floor(r / 3)];

T[t] = 1; V[v] = 1; V[tin.triangles[h]] = 1; V[tin.triangles[h1]] = 1; // mark triangle as visited

let type;
if (!tipVisited) {
type = 0; h = r; // C (vertex not yet encoded; add it & continue to the right)
} else if (leftVisited && rightVisited) {
type = 2; h = queue.pop(); // E (dead end; pop from the stack)
} else if (leftVisited) {
type = 1; h = r; // L (left triangle already encoded; continue to the right)
} else if (rightVisited) {
type = 3; h = l; // R (right triangle already encoded; continue to the left)
} else {
type = 4; h = r; queue.push(l); // S (split; continue to the right + add left to the stack)
}
drawTriangle(ctx, t, ++numVisited, type, ratio); if (numVisited % speed === 0) yield ctx.canvas;
}
return ctx.canvas;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {fetchImage} from '@mbostock/cross-origin-images'
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more