Not so long ago we discussed about the fastest way to find the distance between two points.
In that case, it was a challenge between Euclidean and Manhattan distance. By the way, AS3 provides geom.Point
class which comes with built in methods to deal with distances, such as distance
and polar
. Refer to the official docs for more information.
Will these methods allow faster computation of the distance between two points? Look at this script:
package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.utils.Timer;
import flash.utils.getTimer;
public class pointvstrig extends Sprite {
public function pointvstrig() {
var p1:Point=new Point(10,20);
var p2:Point=new Point(20,30);
var res:Number;
var begin,end:Number;
var i:int;
begin=getTimer();
for (i=0; i<1000000; i++) {
res=pow_euclidian(p1,p2);
}
end=getTimer();
trace("Euclidian with Math.pow: "+(end-begin));
begin=getTimer();
for (i=0; i<1000000; i++) {
res=mul_euclidian(p1,p2);
}
end=getTimer();
trace("Euclidian with multiplication: "+(end-begin));
begin=getTimer();
for (i=0; i<1000000; i++) {
res=point_distance(p1,p2);
}
end=getTimer();
trace("Point.distance: "+(end-begin));
}
private function pow_euclidian(p1:Point, p2:Point):Number {
return Math.sqrt(Math.pow((p1.x-p2.x),2)+Math.pow((p1.y-p2.y),2));
}
private function mul_euclidian(p1:Point, p2:Point):Number {
return Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
private function point_distance(p1:Point, p2:Point):Number {
return Point.distance(p1,p2);
}
}
}
It calculates the distance in three ways: in the Euclidian way using Math.pow
method, in the Euclidian way using the good old multiplication and using Point.distance
method.
After a million calculations, these are the results:
Euclidian with Math.pow: 269ms
Euclidian with multiplication: 140ms
Point.distance: 687ms
The good old multiplication, the most basic way to calculate the power, is the fastest way to return the distance between two points. Point.distance
is absolutely slow.
But I wanted to give Point
class another try, calculating a point at a specified angle and distance from another point (in this case the origin).
Looks at this script:
package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.utils.Timer;
import flash.utils.getTimer;
public class pointvstrig extends Sprite {
public function pointvstrig() {
var distance:Number=100;
var angle:Number=-0.5*Math.PI;
var p:Point;
var begin,end:Number;
var i:int;
begin=getTimer();
for (i=0; i<1000000; i++) {
p=Point.polar(distance,angle);
}
end=getTimer();
trace("Moving point with Point.polar: "+(end-begin));
trace(p);
begin=getTimer();
for (i=0; i<1000000; i++) {
p=new Point(distance*Math.cos(angle),distance*Math.sin(angle));
}
end=getTimer();
trace("Moving point with trigonometry: "+(end-begin));
trace(p);
}
}
}
It calculates the point in two ways: using trigonometry and using Point.polar
method. This time it's not just a matter of speed, I also want a good approximation of the result that should be as close as possible to (x=0, y=-100).
After a million iterations, these are the results:
Moving point with Point.polar: 705ms
(x=6.123031769111886e-15, y=-100)
Moving point with trigonometry: 536ms
(x=6.123031769111886e-15, y=-100)
As you can see, Point class is slower again, while the results are identical.
In the end, we can say trigonometry is faster than Point
class.