Find distance between 2 points in fastest way

2020-06-23 07:50发布

问题:

This code calculates the distance between 2 points by using distance formula, Math.sqrt ( (x1 – x2)^2 + (y1 – y2) ^2). My first point has mmx and mmy coordination and second one has ox and oy coordination. My question is simple, is there any FASTER way for calculate this?

private function dist(mmx:int, mmy:int, ox:int, oy:int):Number{
  return Math.sqrt((mmx-ox)*(mmx-ox)+(mmy-oy)*(mmy-oy));
}

This is my code, Thanks for help.

public function moveIT(Xmouse, Ymouse):void{
            f = Point.distance( new Point( Xmouse, Ymouse ), new Point( mainSP.x, mainSP.y ) );// distance between mouse and instance 
            distancePro = Point.distance( pointO, new Point( mainSP.x, mainSP.y ) );// distance from start point 
            if (  f < strtSen ){ // move forward
                tt.stop(); tt.reset(); // delay timer on destination    
                mF = true;  mB = false;
                ag = Math.atan2((Ymouse - mainSP.y),(Xmouse - mainSP.x)); // move-forward angle, between mouse and instance
            }
            if (mF){ /// shoot loop
                if (f > 5){// 5 pixel
                    mainSP.x -= Math.round( (400 /f) + .5 ) * Math.cos(ag);
                    mainSP.y -= Math.round( (400 /f) + .5 ) * Math.sin(ag);
                }
                if (  distancePro > backSen ){// (backSen = max distance)
                    mF = false;         
                    tt.start();// delay timer on destination
                }
            }
            if (mB){ /// return loop
                if ( distancePro < 24 ){//  back angle re-calculation
                    agBACK = Math.atan2((y1 - mainSP.y),(x1 - mainSP.x));                   
                }
                mainSP.x += (Math.cos(agBACK) * rturnSpeed);
                mainSP.y += (Math.sin(agBACK) * rturnSpeed);
                if ( distancePro < 4 ){ // fix position to start point (x1,y1)
                    mB = false;
                    mainSP.x = x1; mainSP.y = y1;
                }
            }
        }
private function scTimer(evt:TimerEvent):void {// timer
            tt.stop();
            agBACK = Math.atan2((y1 - mainSP.y),(x1 - mainSP.x));// move-back angle between start point and instance
            mB = true;
        }

Also: pointO = new Point(x1,y1); set start point. I can not use mouseX and mouseY because of the way that the application is called by parent class, so I can just pass x and y to my loop.

回答1:

Calling a static function is a bit expensive. You can save that overhead by doing this:

private var sqrtFunc = Math.sqrt;

private function dist(mmx:int, mmy:int, ox:int, oy:int):Number{
    return sqrtFunc((mmx-ox)*(mmx-ox)+(mmy-oy)*(mmy-oy));
}


回答2:

I think that if you in-line your function instead of making an actual function call, it is the fastest way possible.

f = Math.sqrt((Xmouse-mainSP.x)*(Xmouse-mainSP.x)+(Ymouse-mainSP.y)*(Ymouse-mainSP.y)); 
distancePro = Math.sqrt((x1-mainSP.x)*(x1-mainSP.x)+(y1-mainSP.y)*(y1-mainSP.y));

Using Point.distance is WAY more readable, but it is several times slower. If you want speed, you want to inline your math directly.



回答3:

Use Point.distance

d = Point.distance( new Point( x1, y1 ), new Point( x2, y2 ) );

It'll be executed in native code which is typically faster than interpreted code.

If you're in 3D space, use Vector3D.distance

If you're doing collision detection, comparing the lengths of vectors (2D or 3D) is quite common and can be resource intensive due to the use of the sqrt function. If you compare the lengthSquared instead, it will be much more performant.