在2D位图上找到质心
问题内容:
我正在编写一个游戏,并且希望能够在这样的黑白位图上找到任意形状的重心:
012345678
0.XX ......
1..XXX ....
2 ... XXX ...
3..XXXXXXX
4 ... XXX ...
所有“单元”的重量相同。对角线相邻的单元格不被视为已连接,并且形状始终是单个形状,因为在此之前它已经被另一个功能分开了。
它仅用于分辨率较低的图像(最多可能为50x50),并且不需要非常精确,速度是可取的。
我觉得有适当的方法可以做到这一点,但我真的不知道该怎么做。
我在ActionScript 3中对此进行编码,但是可以理解任何语言的示例,而且如果使人类理解它们的话。
编辑:随意假设数据存储在您认为对示例最方便的任何数据结构中。我正在使用位图,但是二维数组甚至单个数组也很好!
编辑:这是我最终使用的代码,它很有可能可以更快地完成,但是我发现这是很容易理解的:
// _bmp is a private BitmapData instance
public function getCenterOfMass():Point {
var avg :Point = new Point(0, 0);
var points :uint = 0;
for (var ix:uint = 0; ix < _bmp.width; ix++) {
for (var iy:uint = 0; iy < _bmp.height; iy++) {
if (_bmp.getPixel(ix, iy) == ACTIVE_COLOR) {
avg.x += ix;
avg.y += iy;
points++;
}
}
}
avg.x /= points;
avg.y /= points;
return avg;
}
问题答案:
像您的示例一样,基于布尔矩阵的该算法(伪代码)如何:
xSum = 0
ySum = 0
points = 0
for point in matrix
if point is marked
xSum += pointX
ySum += pointY
points++
return (xSum/points, ySum/points)
没什么复杂的,计算X最存在的位置,与Y相同,除以您计算的点数,便得到了质心。您可以通过在平均中给某些点不同的权重来进一步使其复杂化,但这应该是您的主要方向。