2013-04-05 75 views
0

我想优化我写在AS3中的碰撞检测算法。哪一个执行速度更快:hitTestObject或Point.distance?

我想知道是否有任何性能上的改进,如果我使用

Point.distance(pointObject1, pointObject2); 
两个物体之间

,而不是使用

object1.hitTestObject(object2); 

我对象都或多或少凸形的边界没有按”真的很重要。

回答

2

Point.distance如果您的测试对象是内部有多个孩子的复杂容器,则速度要快得多(4倍以上!)。如果你使用简单的Sprite,它在功能执行时间上只有25%的差异。

就是这样,因为Point.distance只是计算了毕达哥拉斯定理的一个斜边。所以,我们只有2次减法,1次加法和3次小数计数。许多现代处理器都有内卷指令,因此速度很快。如果我们使用hitTest,则需要执行更多的操作。而且这些动作的数量会随着hitTest'ing Sprite的复杂性而增加(因为它很难算出它的界限)。

我刚做了一些测试。结果证实我是对的。

var ar:Vector.<Sprite> = Vector.<Sprite>([]); //Sprites for hitTest 
for(var i:int = 0; i < 100000; i++) { 
    var sp:Sprite = new Sprite(); //!The results will be other, is case of use a huge container with come objects here! 
    sp.graphics.drawCircle(0, 0, randomIntBetween(1, 200)); //add some shapes 
    sp.graphics.drawRect(0, 0, randomIntBetween(1, 200), randomIntBetween(1, 200)); 
    sp.x = randomIntBetween(-800, 800); 
    sp.y = randomIntBetween(-800, 600); 
    sp.rotation = randomIntBetween(-360, 360); //rotate and scale in random way 
    sp.scaleX = sp.scaleY = Math.random(); 
    ar.push(sp); 
} 

var tim:Number = new Date().time; 
for each(var spr:Sprite in ar) { 
    ar[0].hitTestObject(spr); 
} 
tim = new Date().time - tim; 
trace(tim); 

var pn:Vector.<Point> = Vector.<Point>([]); //Points for Point.distance 
for(i = 0; i < 100000; i++) { 
    var point:Point = new Point(randomIntBetween(-800, 800), randomIntBetween(-800, 800)); 
    pn.push(point); 
} 

tim = new Date().time; 
for each(var pnt:Point in pn) { 
    Point.distance(pn[0], pnt); 
} 
tim = new Date().time - tim; 
trace(tim); 
+0

为什么? – Joetjah 2013-04-05 10:05:05

+0

现在,这是一个答案。 – Joetjah 2013-04-05 10:21:21

2

实际上,你无法将这两者相互比较。如果所有对象都是单像素位图,则距离测试可以正常工作。但我认为情况并非如此。

hitTestObject本质上检查对象的边界矩形,所以它非常快。 在进行像素级别检查之前,您可以随时检查距离,看它们是否足够接近,因为它更昂贵,而且您不想做太多。

当您在对象周围设置圆形边界并确定两个这样的圆不相交时,距离检查非常适用。如果它们相交,则必须使用hitTestObject进行另一次检查,以确保两个对象形状实际重叠。所以基本上你会同时使用,距离检查作为第一次通过检查和hitTestObject作为准确性的后续。