一尘不染

在2D位图上找到质心

algorithm

我正在编写一个游戏,并且希望能够在这样的黑白位图上找到任意形状的重心:

 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;
}

阅读 297

收藏
2020-07-28

共1个答案

一尘不染

像您的示例一样,基于布尔矩阵的该算法(伪代码)如何:

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相同,除以您计算的点数,便得到了质心。您可以通过在平均中给某些点不同的权重来进一步使其复杂化,但这应该是您的主要方向。

2020-07-28