[英]Calculating Path (Polygon) of Path with Stroke - Javascript or Pseudocode
因此,我有一个形成路径的点(x,y)数组。 我需要计算周围多边形的点。 如果您熟悉iOS,则本质上是CGPathCreateCopyByStrokingPath
。 不幸的是,ObjC不是一个选择。 我需要用Javascript,PHP等实现它。
-------
| | |
| | |
\ \ \
\ \ \
\ \ \
\ \ \
\ \ \-----------
\ \----------- |
\---------------
对不良的ascii艺术表示歉意。
我有一个使用Javascript的半工作版本,但是我遇到了一些问题。
function pathToPoly(points) {
var numOfPoints = points.length;
var fullPath = [];
var leftPaths = [];
var rightPaths = [];
var pad = 20;
for(var i=0; i<numOfPoints-1; i++) {
var pointA = points[i];
var pointB = points[i+1];
var slope = (pointB.Y - pointA.Y) / (pointB.X - pointA.X);
var inverseSlope = -1 / slope;
var inverseAngle = Math.atan(inverseSlope);
if(inverseAngle < 0) {
leftPaths.push({
X1: pointA.X - pad * Math.cos(inverseAngle),
Y1: pointA.Y - pad * Math.sin(inverseAngle),
X2: pointB.X - pad * Math.cos(inverseAngle),
Y2: pointB.Y - pad * Math.sin(inverseAngle)
});
rightPaths.push({
X1: pointA.X + pad * Math.cos(inverseAngle),
Y1: pointA.Y + pad * Math.sin(inverseAngle),
X2: pointB.X + pad * Math.cos(inverseAngle),
Y2: pointB.Y + pad * Math.sin(inverseAngle)
});
} else {
rightPaths.push({
X1: pointA.X - pad * Math.cos(inverseAngle),
Y1: pointA.Y - pad * Math.sin(inverseAngle),
X2: pointB.X - pad * Math.cos(inverseAngle),
Y2: pointB.Y - pad * Math.sin(inverseAngle)
});
leftPaths.push({
X1: pointA.X + pad * Math.cos(inverseAngle),
Y1: pointA.Y + pad * Math.sin(inverseAngle),
X2: pointB.X + pad * Math.cos(inverseAngle),
Y2: pointB.Y + pad * Math.sin(inverseAngle)
});
}
if(drawSides) {
var leftSide = leftPaths[i];
var rightSide = rightPaths[i];
context.beginPath();
context.moveTo(leftSide.X1, leftSide.Y1);
context.lineTo(leftSide.X2, leftSide.Y2);
context.lineWidth = 1;
context.strokeStyle = 'yellow';
context.stroke();
context.beginPath();
context.moveTo(rightSide.X1, rightSide.Y1);
context.lineTo(rightSide.X2, rightSide.Y2);
context.lineWidth = 1;
context.strokeStyle = 'cyan';
context.stroke();
}
}
for(var i=0; i<numOfPoints-1; i++) {
var line1 = leftPaths[i];
var line2 = leftPaths[i+1];
fullPath.push({
X: line1.X1,
Y: line1.Y1
});
fullPath.push({
X: line1.X2,
Y: line1.Y2,
});
if(line2) {
fullPath.push({
X: line2.X1,
Y: line2.Y1,
});
}
}
fullPath.push({
X: leftPaths[numOfPoints-2].X2,
Y: leftPaths[numOfPoints-2].Y2
});
for(var i=numOfPoints-2; i>=0; i--) {
var line1 = rightPaths[i];
var line2 = rightPaths[i-1];
fullPath.push({
X: line1.X2,
Y: line1.Y2
});
fullPath.push({
X: line1.X1,
Y: line1.Y1,
});
if(line2) {
fullPath.push({
X: line2.X2,
Y: line2.Y2,
});
}
}
fullPath.push({
X: rightPaths[0].X1,
Y: rightPaths[0].Y1
});
return fullPath;
}
该代码在每段的每一侧绘制平行线,并将它们连接起来。 但是反过来,我的方法创建了一个INVALID多边形。 边“交换”并生成“反”区域。 能够计算面积对于我的应用至关重要。
示例(我的声誉太低,无法发布图像):蓝色很好用,但是红色失败(注意右下角如何旋转,两边互换)。
![example](http://www.originalfunction.com/stackoverflow_16590082-1.png)
有什么建议么?
看起来只有当线以锐角弯曲时(基于少量样本),它才会失败,对吗?
我还没有深入研究算法,只是有根据的猜测:我想知道您是否考虑到以下事实:对于atan(slope)
,有两个正确答案,而javascript atan()
函数可能不是返回您期望的答案(关闭180度)?
如果可以使用atan2(y,x)消除这种歧义。
您可以使用Javascript Clipper来偏移多边形(封闭路径)。 要偏移折线(开放路径),可以使用此代码 。 有一个演示 ,您可以在其中测试偏移多边形。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.