【发布时间】:2013-05-16 14:24:00
【问题描述】:
所以我有一个形成路径的点数组 (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;
}
此代码在每个段的每一侧绘制平行线,并将它们连接起来。但是对于轮流,我的方法会创建一个无效的多边形。两侧“交换”并生成“反向”区域。并且能够计算面积对我的应用程序至关重要。
示例(我的声望太低,无法发布图片):蓝色效果很好,但红色效果不佳(注意右下角如何转,两边互换)。

有什么建议吗?
【问题讨论】:
-
我很好奇为什么需要计算输出点,而不是在某物上绘制多边形。你打算如何处理结果?
-
我最终绘制了多边形,但我为多边形计算了额外的东西。这是针对我正在编程的游戏。
-
好的。你能举个例子说明它是如何失败的(显示输入点、预期输出、实际输出)?
-
(我不保证我会有时间找出问题所在,但在我看来,如果你更明确地表明你试图解决什么失败,那么有人可以帮助你的可能性更大解决。)
-
@LarsH 谢谢。 atan2 确实解决了大部分问题!
标签: javascript graphics path polygon stroke