【发布时间】:2012-11-15 00:42:13
【问题描述】:
假设我在网格环境中有某个多边形的顶点,我如何遍历它包含的每个单元格(包括边缘上的单元格)?
为了澄清,我有以下顶点(算作左上角是(0, 0)):
//each point is [x, y]
var verts = [
[1, 1],
[3, 1],
[3, 2],
[4, 2],
[4, 4],
[0, 4],
[0, 3],
[1, 3]
];
这会定义一个像这样的多边形:
根据上面的顶点,每个绿点都是我想要迭代的点。顶点沿着多边形边缘的方向没有模式,它可以围绕多边形顺时针或逆时针移动。但是,它们将井然有序;也就是说,如果你放下笔并按顺序移动到每个顶点,而不抬起,它会绘制轮廓而不会在多边形内部交叉。
用例是我有来自通过画布 API 加载的 PNG 的 imageData。这个PNG被分成“区域”,我需要迭代当前“区域”的每个像素。每个“区域”都由一个顶点数组定义,如上。
我尝试了类似以下的方法,它将为数组中的每组 4 个顶点创建一个用于迭代的正方形。
for(var v = 0, vl = verts.length - 4; v < vl; ++v) {
//grabbing the minimum X, Y and maximum X, Y to define a square to iterate in
var minX = Math.min(verts[v][0], verts[v + 1][0], verts[v + 2][0], verts[v + 3][0]),
minY = Math.min(verts[v][1], verts[v + 1][1], verts[v + 2][1], verts[v + 3][1]),
maxX = Math.max(verts[v][0], verts[v + 1][0], verts[v + 2][0], verts[v + 3][0]),
maxY = Math.min(verts[v][1], verts[v + 1][1], verts[v + 2][1], verts[v + 3][1]);
for(var x = minX; x < maxX; ++x) {
for(var y = minY; y < maxY; ++y) {
//do my checks on this pixel located at X, Y in the PNG
}
}
}
这有两个大问题:
- 它可以在多边形内重复点,并且
- 可以抓取多边形外的点
我可以通过跟踪我检查的点来解决第一个问题,因此我不会重复检查。第二个只能通过对每个点运行PointInPoly 检查来解决,这会使这个解决方案比我想要的要重得多。
编辑
迭代整个图像中的每个像素并对每个像素应用PointInPoly 检查也是不可接受的;它会比上面的算法还要慢。
【问题讨论】:
-
1:你是对的——遍历画布的 ImageData 中的像素,即使是在屏幕外,也很粗糙。 2:你有一堆你正在定义的矩形,基于你列表中的每4个点,然后你用蛮力穿过像素。相反,为什么不尝试从您的点数据创建最大面积的矩形。这不是一个简单的解决方案,但是如果您获取顶点列表并从这些点创建边界框,这些点保证在这些区域内,并将这些新框推入一个新数组,这就是所有内存,然后是像素每个框都需要修改。
-
@Norguard 我不认为我完全理解你在说什么,或者如何实现它。有什么方法可以获取代码示例(甚至是伪代码)?
标签: javascript canvas polygon