{"ScriptPreparationCode":"Benchmark.prototype.setup = function() {\r\n\r\n /** Converts numeric degrees to radians */\r\n if (typeof(Number.prototype.toRad) === \u0022undefined\u0022) {\r\n Number.prototype.toRad = function() {\r\n return this * Math.PI / 180;\r\n }\r\n }\r\n\r\n /**\r\n * Calculates geodetic distance between two points specified by latitude/longitude using \r\n * Vincenty inverse formula for ellipsoids\r\n *\r\n * @param {Number} lat1, lon1: first point in decimal degrees\r\n * @param {Number} lat2, lon2: second point in decimal degrees\r\n * @returns (Number} distance in metres between points\r\n */\r\n\r\n function distVincentyRef(lat1, lon1, lat2, lon2) {\r\n var a = 6378137,\r\n b = 6356752.314245,\r\n f = 1 / 298.257223563; // WGS-84 ellipsoid params\r\n var L = (lon2 - lon1).toRad();\r\n var U1 = Math.atan((1 - f) * Math.tan(lat1.toRad()));\r\n var U2 = Math.atan((1 - f) * Math.tan(lat2.toRad()));\r\n var sinU1 = Math.sin(U1),\r\n cosU1 = Math.cos(U1);\r\n var sinU2 = Math.sin(U2),\r\n cosU2 = Math.cos(U2);\r\n\r\n var lambda = L,\r\n lambdaP, iterLimit = 100;\r\n do {\r\n var sinLambda = Math.sin(lambda),\r\n cosLambda = Math.cos(lambda);\r\n var sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) \u002B (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));\r\n if (sinSigma == 0) return 0; // co-incident points\r\n var cosSigma = sinU1 * sinU2 \u002B cosU1 * cosU2 * cosLambda;\r\n var sigma = Math.atan2(sinSigma, cosSigma);\r\n var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;\r\n var cosSqAlpha = 1 - sinAlpha * sinAlpha;\r\n var cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;\r\n if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (\u00A76)\r\n var C = f / 16 * cosSqAlpha * (4 \u002B f * (4 - 3 * cosSqAlpha));\r\n lambdaP = lambda;\r\n lambda = L \u002B (1 - C) * f * sinAlpha * (sigma \u002B C * sinSigma * (cos2SigmaM \u002B C * cosSigma * (-1 \u002B 2 * cos2SigmaM * cos2SigmaM)));\r\n } while (Math.abs(lambda - lambdaP) \u003E 1e-12 \u0026\u0026 --iterLimit \u003E 0);\r\n\r\n if (iterLimit == 0) return NaN // formula failed to converge\r\n console.log(iterLimit);\r\n var uSq = cosSqAlpha * (a * a - b * b) / (b * b);\r\n var A = 1 \u002B uSq / 16384 * (4096 \u002B uSq * (-768 \u002B uSq * (320 - 175 * uSq)));\r\n var B = uSq / 1024 * (256 \u002B uSq * (-128 \u002B uSq * (74 - 47 * uSq)));\r\n var deltaSigma = B * sinSigma * (cos2SigmaM \u002B B / 4 * (cosSigma * (-1 \u002B 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 \u002B 4 * sinSigma * sinSigma) * (-3 \u002B 4 * cos2SigmaM * cos2SigmaM)));\r\n var s = b * A * (sigma - deltaSigma);\r\n\r\n s = s.toFixed(3); // round to 1mm precision\r\n return s;\r\n }\r\n\r\n function distVincenty(lat1, lon1, lat2, lon2) {\r\n const\r\n \ta = 6378137,\r\n b = 6356752.314245,\r\n f = 1 / 298.257223563, // WGS-84 ellipsoid params\r\n degToRad = Math.PI / 180,\r\n f2 = f * f,\r\n f_4_4_16 = (f \u002B f2) / 4,\r\n f_3_16 = f2 * 3 / 16,\r\n f1 = 1 - f,\r\n a2 = a * a,\r\n b2 = b * b,\r\n a2b2b2 = (a2 - b2) / b2;\r\n var L = (lon2 - lon1) * degToRad;\r\n var U1 = Math.atan(f1 * Math.tan(lat1 * degToRad));\r\n var U2 = Math.atan(f1 * Math.tan(lat2 * degToRad));\r\n var sinU1 = Math.sin(U1),\r\n cosU1 = Math.cos(U1);\r\n var sinU2 = Math.sin(U2),\r\n cosU2 = Math.cos(U2);\r\n\r\n var lambda = L,\r\n lambdaP, iterLimit = 100;\r\n do {\r\n var sinLambda = Math.sin(lambda),\r\n cosLambda = Math.cos(lambda);\r\n var cosU2sinLambda = cosU2 * sinLambda;\r\n var sinU1sinU2 = sinU1 * sinU2;\r\n var cosU1sinU2_sinU1cosU2cosLambda = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;\r\n var sinSigma = Math.sqrt(cosU2sinLambda * cosU2sinLambda \u002B cosU1sinU2_sinU1cosU2cosLambda * cosU1sinU2_sinU1cosU2cosLambda);\r\n if (sinSigma == 0) return 0; // co-incident points\r\n var cosSigma = sinU1sinU2 \u002B cosU1 * cosU2 * cosLambda;\r\n var sigma = Math.atan2(sinSigma, cosSigma);\r\n var sinAlpha = cosU1 * cosU2sinLambda / sinSigma;\r\n var cosSqAlpha = 1 - sinAlpha * sinAlpha;\r\n var cos2SigmaM = cosSigma - 2 * sinU1sinU2 / cosSqAlpha;\r\n if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (\u00A76)\r\n var C = cosSqAlpha * (f_4_4_16 - f_3_16 * cosSqAlpha);\r\n lambdaP = lambda;\r\n lambda = L \u002B (1 - C) * f * sinAlpha * (sigma \u002B C * sinSigma * (cos2SigmaM \u002B C * cosSigma * (-1 \u002B 2 * cos2SigmaM * cos2SigmaM)));\r\n } while (Math.abs(lambda - lambdaP) \u003E 1e-12 \u0026\u0026 --iterLimit \u003E 0);\r\n\r\n if (iterLimit == 0) return NaN // formula failed to converge\r\n console.log(iterLimit);\r\n var uSq = cosSqAlpha * a2b2b2;\r\n var A = 1 \u002B uSq * (0.25 \u002B uSq * (-0.046875 \u002B uSq * (0.01953125 - 0.01068115234 * uSq)));\r\n var B = uSq * (0.25 \u002B uSq * (-0.125 \u002B uSq * (0.072265625 - 0.0458984375 * uSq)));\r\n var deltaSigma = B * sinSigma * (cos2SigmaM \u002B B / 4 * (cosSigma * (-1 \u002B 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 \u002B 4 * sinSigma * sinSigma) * (-3 \u002B 4 * cos2SigmaM * cos2SigmaM)));\r\n var s = b * A * (sigma - deltaSigma);\r\n\r\n s = s.toFixed(3); // round to 1mm precision\r\n return s;\r\n }\r\n\r\n // Distance in kilometers between two points using the Haversine algo.\r\n function haversine(lat1, lon1, lat2, lon2) {\r\n var R = 6371;\r\n var dLat = (lat2 - lat1).toRad();\r\n var dLong = (lon2 - lon1).toRad();\r\n\r\n var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) \u002B Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLong / 2) * Math.sin(dLong / 2);\r\n var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n var d = R * c;\r\n\r\n return Math.round(d);\r\n }\r\n};","TestCases":[{"Name":"Vincenty reference","Code":"distVincentyRef(-31.965379, 115.822077, -33.85789, 151.214806);","IsDeferred":false},{"Name":"Vincenty","Code":"distVincenty(-31.965379, 115.822077, -33.85789, 151.214806);","IsDeferred":false}]}