我正在编写一个游戏,并且希望能够在这样的黑白位图上找到任意形状的重心:
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相同,除以您计算的点数,便得到了质心。您可以通过在平均中给某些点不同的权重来进一步使其复杂化,但这应该是您的主要方向。