d3.geom.hull
函数将找到一个紧密包含所有节点的多边形,没有额外的间隔。这当然会取消掉Voronoi区域的很多作用,因为它们旨在为节点周围添加一些活动空间。所以你需要计算的是,在凸包多边形的所有侧面上比凸包多边形大一定距离的多边形。使用d3.geom.hull(nodes)
计算定义节点紧密边界的顶点数组。
使用这些顶点创建一个d3多边形对象。
使用.centroid()
计算多边形的中心。
对于凸包中的每个顶点,计算一个距离多边形中心更远的点padding。
使用这个扩展多边形剪切由Voronoi函数返回的所有多边形数组。
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);
});
defs
中使用了expandedHull
作为clipPath
。谢谢。 - Risingson最近我做了一个例子来说明多边形裁剪的工作原理:http://tributary.io/inlet/8263747
你可以在update
函数中看到裁剪代码,在process
函数中看到渲染代码。拖动点以查看裁剪效果。
需要注意的几个问题:
“hull”(或者在我的例子中是裁剪路径)中点的顺序很重要。你的多边形必须是逆时针方向并且是凸多边形(没有洞)。如果不满足这些条件,就不会出现错误,只会得到一个空数组。
多边形操作会直接修改你的点数组,如果你不想让几何图形本身被裁剪,而是想要一个副本,你需要先复制一份。