我正在尝试优化用AS3编写的碰撞检测算法。
我想知道如果我使用
,性能是否有任何改进Point.distance(pointObject1, pointObject2);
在两个对象之间而不是使用
object1.hitTestObject(object2);
我的物体或多或少是凸起的,所以边界并不重要。
答案 0 :(得分: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);
答案 1 :(得分:2)
实际上,你无法将这两者相互比较。如果所有对象都是单像素位图,则距离测试可以正常工作。但我认为事实并非如此。
hitTestObject
基本上检查对象的边界矩形,所以它非常快。
在进行像素级别检查之前,您可以随时检查距离,看它们是否足够接近,因为它更贵,而且您不想做太多。
当您在对象周围设置圆形边界并确定两个这样的圆不相交时,距离检查很有用。如果它们相交,则必须使用hitTestObject进行另一次检查,以确保两个对象形状实际重叠。所以基本上你会使用两者,距离检查作为第一次检查,而hitTestObject作为准确性的后续跟踪。