跳到内容

德洛奈三角剖分

德洛奈三角剖分是由一组 *x* 和 *y* 中的点形成的三角形网格。任何点都不在任何三角形的圆周内,这是一个在某些应用中很不错的几何属性,并且倾向于避免“薄片”三角形。德洛奈三角剖分是 沃罗诺伊图 的对偶。

new Delaunay(points)

源代码 · 返回给定平坦数组 [x0, y0, x1, y1, …] 的 points 的德洛奈三角剖分。

js
const delaunay = new d3.Delaunay(Float64Array.of(0, 0, 0, 1, 1, 0, 1, 1));

给定的 points 可以是任何类数组类型,但通常是 Float64Array。

delaunay.points

点的坐标,作为数组 [x0, y0, x1, y1, …]。

delaunay.halfedges

半边索引,作为 Int32Array [j0, j1, …]。对于每个索引 0 ≤ i < halfedges.length,存在一条从三角形顶点 j = halfedges[i] 到三角形顶点 i 的半边。等效地,这意味着三角形 ⌊i / 3⌋ 与三角形 ⌊j / 3⌋ 相邻。如果 j 为负,则三角形 ⌊i / 3⌋ 是 凸包 上的外部三角形。例如,要渲染德洛奈三角剖分的内部边

js
const {points, halfedges, triangles} = delaunay;
for (let i = 0, n = halfedges.length; i < n; ++i) {
  const j = halfedges[i];
  if (j < i) continue;
  const ti = triangles[i];
  const tj = triangles[j];
  context.moveTo(points[ti * 2], points[ti * 2 + 1]);
  context.lineTo(points[tj * 2], points[tj * 2 + 1]);
}

另请参见 delaunay.render

delaunay.hull

一个 Int32Array,包含形成凸包的点索引,以逆时针顺序排列。如果点共线,则以排序后的顺序返回它们。

另请参见 delaunay.renderHull

delaunay.triangles

三角形顶点索引,作为 Uint32Array [i0, j0, k0, i1, j1, k1, …]。每个连续的三元组索引 i, j, k 形成一个逆时针三角形。三角形点的坐标可以通过遍历 delaunay.points 来找到。例如,要渲染三角形 i

js
const {points, triangles} = delaunay;
const t0 = triangles[i * 3 + 0];
const t1 = triangles[i * 3 + 1];
const t2 = triangles[i * 3 + 2];
context.moveTo(points[t0 * 2], points[t0 * 2 + 1]);
context.lineTo(points[t1 * 2], points[t1 * 2 + 1]);
context.lineTo(points[t2 * 2], points[t2 * 2 + 1]);
context.closePath();

另请参见 delaunay.renderTriangle

delaunay.inedges

传入半边索引,作为 Int32Array [e0, e1, e2, …]。对于每个点 iinedges[i] 是传入半边的半边索引 e。对于重合点,半边索引为 -1;对于凸包上的点,传入半边位于凸包上;对于其他点,传入半边的选择是任意的。inedges 表可以用来遍历德洛奈三角剖分;另请参见 delaunay.neighbors

Delaunay.from(points, fx, fy, that)

提示

Delaunay.from 通常比 new Delaunay 慢,因为它需要物化一个新的 xy 坐标的平坦数组。

源代码 · 返回给定数组或可迭代的 points 的德洛奈三角剖分。如果未指定 fxfy,则假设 points 是一个由两元素数组组成的数组,每个数组包含数字:[[x0, y0], [x1, y1], …]。

js
const delaunay = d3.Delaunay.from([[0, 0], [0, 1], [1, 0], [1, 1]]);

否则,fxfy 是为 points 数组中的每个元素按顺序调用的函数,并且必须分别返回每个点的 x 和 y 坐标。

js
const delaunay = d3.Delaunay.from([{x: 0, y: 0}, {x: 0, y: 1}, {x: 1, y: 0}, {x: 1, y: 1}], (d) => d.x, (d) => d.y);

如果指定了 that,则函数 fxfy 将以 that 作为 this 来调用。(参见 Array.from 以作参考。)

delaunay.find(x, y, i)

js
delaunay.find(0, 0) // -1

示例 · 源代码 · 返回最靠近指定点 ⟨x, y⟩ 的输入点的索引。搜索从指定的点 i 开始。如果未指定 i,则默认为零。

delaunay.neighbors(i)

js
delaunay.neighbors(-1) // []

源代码 · 返回指定点 i 的相邻点的索引的可迭代对象。如果 i 是重合点,则可迭代对象为空。

delaunay.render(context)

源代码 · 将德洛奈三角剖分的边渲染到指定的 context。指定的 context 必须实现 CanvasPathMethods API 中的 context.moveTo 和 context.lineTo 方法。如果未指定 context,则改为返回一个 SVG 路径字符串。

delaunay.renderHull(context)

源代码 · 将德洛奈三角剖分的凸包渲染到指定的 context。指定的 context 必须实现 CanvasPathMethods API 中的 context.moveTo 和 context.lineTo 方法。如果未指定 context,则改为返回一个 SVG 路径字符串。

delaunay.renderTriangle(i, context)

源代码 · 将德洛奈三角剖分的三角形 i 渲染到指定的 context。指定的 context 必须实现 CanvasPathMethods API 中的 context.moveTo、context.lineTo 和 context.closePath 方法。如果未指定 context,则改为返回一个 SVG 路径字符串。

delaunay.renderPoints(context, radius)

源代码 · 将德洛奈三角剖分的输入点渲染到指定的 context,作为具有指定 radius 的圆。如果未指定 radius,则默认为 2。指定的 context 必须实现 CanvasPathMethods API 中的 context.moveTo 和 context.arc 方法。如果未指定 context,则改为返回一个 SVG 路径字符串。

delaunay.hullPolygon()

源代码 · 返回表示凸包的闭合多边形 [[x0, y0], [x1, y1], …, [x0, y0]]。另请参见 delaunay.renderHull

delaunay.trianglePolygons()

源代码 · 返回 每个三角形的多边形 的可迭代对象,按顺序排列。另请参见 delaunay.renderTriangle

delaunay.trianglePolygon(i)

源代码 · 返回表示三角形 i 的闭合多边形 [[x0, y0], [x1, y1], [x2, y2], [x0, y0]]。另请参见 delaunay.renderTriangle

delaunay.update()

源代码 · 在对点进行就地修改后重新计算三角剖分。

delaunay.voronoi(bounds)

源代码 · 返回给定 Delaunay 三角剖分的 Voronoi 图。 渲染时,该图将被裁剪到指定的 bounds = [xmin, ymin, xmax, ymax]。

js
const delaunay = d3.Delaunay.from(points);
const voronoi = delaunay.voronoi([0, 0, 640, 480]);

如果未指定 bounds,则默认为 [0, 0, 960, 500]。 即使在没有三角剖分存在的情况下(即 0、1 或 2 个点,以及共线点)也会返回 Voronoi 图。