# Angle between three points

## JavaScript performance comparison

Test case created by Gavin Kistner

## Preparation code

``````

<script>
Benchmark.prototype.setup = function() {
function findAngle1(p0,p1,p2) { // Expressive
var b = Math.pow(p1.x-p0.x,2) + Math.pow(p1.y-p0.y,2),
a = Math.pow(p1.x-p2.x,2) + Math.pow(p1.y-p2.y,2),
c = Math.pow(p2.x-p0.x,2) + Math.pow(p2.y-p0.y,2);
return Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
}

function findAngle2(p0,p1,p2) { // Simple unroll
var b = (p1.x-p0.x)*(p1.x-p0.x) + (p1.y-p0.y)*(p1.y-p0.y),
a = (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y),
c = (p2.x-p0.x)*(p2.x-p0.x) + (p2.y-p0.y)*(p2.y-p0.y);
return Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
}

function findAngle3(p0,p1,p2) { // Do each subtraction only once
var x1 = p1.x-p0.x, y1 = p1.y-p0.y,
x2 = p1.x-p2.x, y2 = p1.y-p2.y,
x3 = p2.x-p0.x, y3 = p2.y-p0.y,
b = x1*x1 + y1*y1,
a = x2*x2 + y2*y2,
c = x3*x3 + y3*y3;
return Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
}

pts = [{x:11,y:30},{x:24,y:8},{x:1,y:3},{x:11,y:11},{x:56,y:58},{x:14,y:18},{x:49,y:13},{x:37,y:27},{x:35,y:13},{x:5,y:65},{x:32,y:16},{x:13,y:89},{x:45,y:39},{x:78,y:30},{x:53,y:27},{x:53,y:68},{x:35,y:53},{x:18,y:39},{x:15,y:60},{x:69,y:82},{x:24,y:15},{x:25,y:99},{x:96,y:4},{x:91,y:64},{x:48,y:80},{x:93,y:27},{x:24,y:84},{x:86,y:37},{x:78,y:53},{x:76,y:92},{x:46,y:92},{x:28,y:9},{x:5,y:57},{x:14,y:15},{x:51,y:18},{x:86,y:33},{x:37,y:3},{x:84,y:7},{x:9,y:38},{x:61,y:43},{x:74,y:53},{x:16,y:94},{x:20,y:97},{x:29,y:37},{x:87,y:54},{x:65,y:15},{x:79,y:18},{x:96,y:97},{x:41,y:27},{x:21,y:27},{x:3,y:62},{x:83,y:81},{x:9,y:38},{x:15,y:39},{x:64,y:37},{x:83,y:60},{x:38,y:0},{x:91,y:1},{x:30,y:37},{x:66,y:61},{x:30,y:8},{x:32,y:94},{x:10,y:38},{x:24,y:54},{x:88,y:6},{x:99,y:84},{x:20,y:3},{x:49,y:77},{x:74,y:97},{x:17,y:3},{x:80,y:28},{x:39,y:59},{x:58,y:66},{x:71,y:91},{x:76,y:76},{x:74,y:64},{x:83,y:85},{x:60,y:56},{x:61,y:41},{x:0,y:15},{x:19,y:53},{x:39,y:99},{x:89,y:60},{x:55,y:42},{x:70,y:37},{x:5,y:77},{x:44,y:62},{x:67,y:59},{x:34,y:28},{x:79,y:85},{x:47,y:59},{x:87,y:31},{x:16,y:49},{x:63,y:56},{x:56,y:74},{x:1,y:65},{x:79,y:32},{x:99,y:85},{x:3,y:53}];
idx = [[74,43,12],[70,60,92],[31,85,80],[98,98,20],[85,16,26],[37,17,46],[28,52,61],[87,8,97],[98,62,71],[82,98,86],[16,29,9],[72,88,45],[93,85,35],[12,35,83],[27,23,6],[94,88,15],[83,68,57],[82,11,59],[37,19,76],[35,31,78],[21,79,32],[80,68,9],[0,59,18],[62,62,1],[36,79,80],[63,85,62],[51,22,83],[60,4,98],[77,46,36],[43,22,91],[49,89,98],[26,95,4],[53,87,43],[5,69,86],[89,72,10],[29,14,4],[96,11,1],[84,56,83],[79,41,30],[23,49,68],[59,80,22],[7,54,4],[37,24,90],[29,31,7],[28,68,17],[91,19,88],[26,84,98],[94,32,3],[92,22,92],[32,78,70],[63,18,70],[9,98,43],[55,60,62],[18,56,98],[34,89,90],[37,67,71],[1,73,52],[61,2,68],[84,82,20],[0,53,69],[54,88,52],[23,67,47],[86,88,1],[45,64,0],[13,70,48],[63,30,82],[12,27,1],[18,15,7],[24,58,12],[16,72,16],[7,3,62],[82,8,3],[57,2,5],[45,83,43],[72,15,71],[69,71,35],[81,58,19],[18,88,50],[9,15,5],[30,72,92],[25,69,1],[56,78,98],[67,3,68],[76,66,1],[12,85,9],[64,5,52],[0,28,63],[6,33,60],[85,81,90],[84,97,56],[17,98,33],[20,79,76],[12,32,72],[83,0,91],[46,62,86],[66,88,98],[36,48,50],[39,38,6],[46,98,70]];

};

</script>
``````

## Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Expressive
``````for (var i=idx.length;i--;)
findAngle1(pts[idx[i][0]],pts[idx[i][1]],pts[idx[i][2]]);``````
pending…
No Math.pow
``````for (var i=idx.length;i--;)
findAngle2(pts[idx[i][0]],pts[idx[i][1]],pts[idx[i][2]]);``````
pending…
Less subtraction
``````for (var i=idx.length;i--;)
findAngle3(pts[idx[i][0]],pts[idx[i][1]],pts[idx[i][2]]);``````
pending…

You can edit these tests or add even more tests to this page by appending `/edit` to the URL.