我正在为一个小型2D游戏编程物理,我需要检查屏幕上的每个对象与屏幕上的每个其他对象。那是O(N^2)
,我真的不喜欢那样。
我的想法:
for (var i = 0; i < objects.length; i ++)
for (var j = 0; j < objects.length; j ++)
if (collide(objects[i], objects[j])) doStuff(objects[i], objects[j]);
这是不必要的,我将多次检查相同的对象。我怎么能避免这种情况?我想过有一个矩阵,它是n*n
(假设n是对象的数量),然后每次我访问一对对象时我会这样:
visited[i][j] = 1;
visited[j][i] = 1;
然后,我总是知道我访问了哪一对象。
这样可行,但是,我会再次需要设置所有这些单元格n*n
次,只需将它们全部设置为0
即可!也许,我可以将所有内容设置为[]
,但这对我来说似乎仍然不是一个可行的解决方案。还有更好的东西吗?
显然,我选择的语言是Javascript,但我比较熟悉C,C ++和Python,所以你可以回答它们(尽管Javascript,C和C ++的语法几乎相同)。
答案 0 :(得分:3)
你不会避免使用O(n ^ 2),但你可以减少一半:
for (var i = 0; i < objects.length; i ++)
for (var j = i; j < objects.length; j ++)
if (collide(objects[i], objects[j])) doStuff(objects[i], objects[j]);
假设碰撞是对称的。如果它也是反身的,并且测试碰撞是昂贵的,你可以将doStuff(object[i], object[i])
移出内循环以避免测试碰撞并从i+1
开始内循环
答案 1 :(得分:0)
如果您的精灵有最大尺寸,您可以对数组进行排序,并跳过比较屏幕上较低的顶点+ maxsize ...