我做了一个jsFiddle对于给定的多边形,计算外多边形,我希望能满足您的要求。我已经在这个pdf document后面加上了数学。
更新:代码已经作出处理垂直线。
function Vector2(x, y)
{
this.x = x;
this.y = y;
}
function straight_skeleton(poly, spacing)
{
// http://stackoverflow.com/a/11970006/796832
// Accompanying Fiddle: http://jsfiddle.net/vqKvM/35/
var resulting_path = [];
var N = poly.length;
var mi, mi1, li, li1, ri, ri1, si, si1, Xi1, Yi1;
for(var i = 0; i < N; i++)
{
mi = (poly[(i+1) % N].y - poly[i].y)/(poly[(i+1) % N].x - poly[i].x);
mi1 = (poly[(i+2) % N].y - poly[(i+1) % N].y)/(poly[(i+2) % N].x - poly[(i+1) % N].x);
li = Math.sqrt((poly[(i+1) % N].x - poly[i].x)*(poly[(i+1) % N].x - poly[i].x)+(poly[(i+1) % N].y - poly[i].y)*(poly[(i+1) % N].y - poly[i].y));
li1 = Math.sqrt((poly[(i+2) % N].x - poly[(i+1) % N].x)*(poly[(i+2) % N].x - poly[(i+1) % N].x)+(poly[(i+2) % N].y - poly[(i+1) % N].y)*(poly[(i+2) % N].y - poly[(i+1) % N].y));
ri = poly[i].x+spacing*(poly[(i+1) % N].y - poly[i].y)/li;
ri1 = poly[(i+1) % N].x+spacing*(poly[(i+2) % N].y - poly[(i+1) % N].y)/li1;
si = poly[i].y-spacing*(poly[(i+1) % N].x - poly[i].x)/li;
si1 = poly[(i+1) % N].y-spacing*(poly[(i+2) % N].x - poly[(i+1) % N].x)/li1;
Xi1 = (mi1*ri1-mi*ri+si-si1)/(mi1-mi);
Yi1 = (mi*mi1*(ri1-ri)+mi1*si-mi*si1)/(mi1-mi);
// Correction for vertical lines
if(poly[(i+1) % N].x - poly[i % N].x==0)
{
Xi1 = poly[(i+1) % N].x + spacing*(poly[(i+1) % N].y - poly[i % N].y)/Math.abs(poly[(i+1) % N].y - poly[i % N].y);
Yi1 = mi1*Xi1 - mi1*ri1 + si1;
}
if(poly[(i+2) % N].x - poly[(i+1) % N].x==0)
{
Xi1 = poly[(i+2) % N].x + spacing*(poly[(i+2) % N].y - poly[(i+1) % N].y)/Math.abs(poly[(i+2) % N].y - poly[(i+1) % N].y);
Yi1 = mi*Xi1 - mi*ri + si;
}
//console.log("mi:", mi, "mi1:", mi1, "li:", li, "li1:", li1);
//console.log("ri:", ri, "ri1:", ri1, "si:", si, "si1:", si1, "Xi1:", Xi1, "Yi1:", Yi1);
resulting_path.push({
x: Xi1,
y: Yi1
});
}
return resulting_path;
}
var canvas = document.getElementById("Canvas");
var ctx = canvas.getContext("2d");
var poly = [
new Vector2(150, 170),
new Vector2(400, 120),
new Vector2(200, 270),
new Vector2(350, 400),
new Vector2(210, 470)
];
draw(poly);
draw(straight_skeleton(poly, 10));
function draw(p) {
ctx.beginPath();
ctx.moveTo(p[0].x, p[0].y);
for(var i = 1; i < p.length; i++)
{
ctx.lineTo(p[i].x, p[i].y);
}
ctx.strokeStyle = "#000000";
ctx.closePath();
ctx.stroke();
}
将多边形放入点对象数组中。
函数draw(p)
在画布上绘制多边形p
。
给定的多边形位于数组poly中,数组poly中的外部。
spacing
是继安格斯·约翰逊的评论多边形之间的距离(如沿着你的绿色图中的箭头)
,我已经产生了一些更小提琴展现他提出的问题。这个问题比我第一次想到的要困难得多。
请解释一下你的形象,这部分做的红色和绿色代表什么? – Hogan 2012-08-13 20:48:55
谢谢。编辑。 – davey555 2012-08-13 21:08:16
您可以发布您用于多边形,平移和缩放的代码吗?你是什么意思“不总是匹配”?它在什么情况下失败? – 2012-08-13 21:14:52