答案 0 :(得分:4)
d3.geom.hull
函数将找到一个包含所有节点的多边形,没有多余的间距。这当然会抵消Voronoi区域的大部分目的,这些区域旨在在节点周围添加一些活动空间。所以你需要计算的是一个多边形,它的填充距离大于所有边上的凸包多边形。
我推荐的算法:
使用d3.geom.hull(nodes)
计算定义节点紧密边界的顶点数组。
使用这些顶点创建d3 polygon object。
使用.centroid()
计算该多边形的中心。
对于凸包中的每个顶点,计算 padding 距离多边形中心更远的点。
使用此扩展多边形剪裁Voronoi function返回的数组中的所有多边形。
示例代码:
var hullFunction = d3.geom.hull()
.x(/*x accessor function*/)
.y(/*y accessor function*/);
var tightHull = hullFunction(nodes); //returns an array of vertices
var centerPoint = d3.geom.polygon(tightHullArray).centroid();
var expandedHull = tightHullArray.map( function(vertex) {
//Create a new array of vertices, each of which is the result
//of running this function on the corresponding vertex of the
//original hull.
//Each vertex is of the form [x,y]
var vector = [vertex[0] - centerPoint[0],
vertex[1] - centerPoint[1] ];
//the vector representing the line from center to this point
var vectorLength = Math.sqrt(vector[0]*vector[0]
+ vector[1]*vector[1]);
//Pythagorus' theorem to get the length of the line
var normalizedVector = [vector[0] / vectorLength,
vector[1] / vectorLength];
//the vector scaled down to length 1, but with the same angle
//as the original vector
return [vertex[0] + normalizedVector[0]*padding,
vertex[1] + normalizedVector[1]*padding ];
//use the normalized vector to adjust the vertex point away from
//the center point by a distance of `padding`
});
var clippedVoronoi = voronoiPolygons.map(function(voronoi) {
//voronoiPolygons would be the array returned by the voronoi function
return expandedHull.clip(voronoi);
//I think this is correct; if you get weird results, try
// return voronoi.clip(expandedHull);
});
答案 1 :(得分:0)
我最近做了一个例子来向自己说明多边形裁剪是如何工作的: http://tributary.io/inlet/8263747
您可以在update
函数中查看剪辑代码,并在process
函数中查看渲染代码。拖动点以查看剪辑将如何受到影响。
需要注意的几件事情:
“船体”(或我的示例中的剪切路径)中的点的顺序很重要。你的多边形必须是逆时针和凸面(没有洞穴)。如果不满足这些条件,则没有错误,您只需返回一个空数组。
多边形操作在适当的位置操作点阵列,如果您不希望几何体本身被剪裁,但想要复制,则需要先复制。