Thanks to ffur2007slx2_5 for giving me the heads up about inconsistencies between calculating distances the usual way and using distance command in game. Every man and his dog knows that if you have 2 points in 3D space, the distance between these points could be calculated using a simple Euclidean equation:

sqrt ((p1.x – p2.x)^2 + (p1.y – p2.y)^2 + (p1.z – p2.z)^2)

And this is how one would expect the distance to be calculated in Arma when you supply distance function with 2 points. Apparently this is not the case at all. In Arma resulting distance actually varies from your usual calculations result. The result could even differ if you simply swap the start and end params around. I’ve raised this question on the feedback tracker, but unofficially was told this is expected behaviour and has something to do with floats vs. ints and all that nonsense.

TBH I would have left it there, but my preliminary test showed that the precision of the distance command is not that great. So I decided to make a function to calculate precise distance by old fashion way. It is 4 times slower than the distance command, but once I show you how imprecise the distance command could be, I think you will soon forget about the speed loss.

KK_fnc_distanceASL = { private ["_v0","_v1"]; _v0 = _this select 0; _v1 = _this select 1; sqrt ( ((_v0 select 0) - (_v1 select 0)) ^ 2 + ((_v0 select 1) - (_v1 select 1)) ^ 2 + ((_v0 select 2) - (_v1 select 2)) ^ 2 ) };

Laying all that single point precision stuff aside, let’s just brutal force check how good distance command really is. I’ve constructed 2 loops to iterate through numbers from min [10,10,10] to max [9000,9000,9000]. A very small test to show a very big problem with distance command:

for "_i" from 1 to 9 do { _xyz = _i; for "_j" from 1 to 3 do { _xyz = _xyz * 10; _end = [_xyz, _xyz, _xyz]; _dist = [0,0,0] distance _end; _distP = [[0,0,0], _end] call KK_fnc_distanceASL; "debug_console" callExtension format [ "0 to %1 - dist: %2 - distP: %3 - diff: %4", _end, _dist, _distP, abs (_dist - _distP) ]; }; };

And this is the result (highlighted most interesting parts):

0 to [10,10,10] – dist: 17.181 – distP: 17.3205 – diff: 0.139479
0 to [100,100,100] – dist: 173.061 – distP: 173.205 – diff: 0.143845
0 to [1000,1000,1000] – dist: 1731.91 – distP: 1732.05 – diff: 0.141113
0 to [20,20,20] – dist: 34.6648 – distP: 34.641 – diff: 0.0237694
0 to [200,200,200] – dist: 346.38 – distP: 346.41 – diff: 0.0303955
0 to [2000,2000,2000] – dist: 3477.64 – distP: 3464.1 – diff: 13.5388
0 to [30,30,30] – dist: 51.8251 – distP: 51.9615 – diff: 0.136421
0 to [300,300,300] – dist: 519.603 – distP: 519.615 – diff: 0.0119019
0 to [3000,3000,3000] – dist: 5300.83 – distP: 5196.15 – diff: 104.677
0 to [40,40,40] – dist: 69.275 – distP: 69.282 – diff: 0.00705719
0 to [400,400,400] – dist: 692.674 – distP: 692.82 – diff: 0.145874
0 to [4000,4000,4000] – dist: 7003.53 – distP: 6928.2 – diff: 75.3286
0 to [50,50,50] – dist: 86.5184 – distP: 86.6025 – diff: 0.0840988
0 to [500,500,500] – dist: 866.009 – distP: 866.025 – diff: 0.0163574
0 to [5000,5000,5000] – dist: 8768.26 – distP: 8660.25 – diff: 108.004
0 to [60,60,60] – dist: 103.851 – distP: 103.923 – diff: 0.0725327
0 to [600,600,600] – dist: 1039.2 – distP: 1039.23 – diff: 0.0255127
0 to [6000,6000,6000] – dist: 10392.3 – distP: 10392.3 – diff: 0.0214844
0 to [70,70,70] – dist: 121.227 – distP: 121.244 – diff: 0.0166779
0 to [700,700,700] – dist: 1212.29 – distP: 1212.44 – diff: 0.14502
0 to [7000,7000,7000] – dist: 12124.2 – distP: 12124.4 – diff: 0.12793
0 to [80,80,80] – dist: 138.433 – distP: 138.564 – diff: 0.130585
0 to [800,800,800] – dist: 1385.64 – distP: 1385.64 – diff: 0.00390625
0 to [8000,8000,8000] – dist: 13856.4 – distP: 13856.4 – diff: 0.0214844
0 to [90,90,90] – dist: 155.907 – distP: 155.885 – diff: 0.0222778
0 to [900,900,900] – dist: 1558.81 – distP: 1558.85 – diff: 0.0404053
0 to [9000,9000,9000] – dist: 15588.4 – distP: 15588.5 – diff: 0.0654297

Yes, you see this right, 108 m difference at 8 km. If you don’t believe me, take a calculator and do it by hand. This is amazing! I’m looking at it myself again and aging trying to figure out if I made a mistake somewhere and this is going to come back and hit me in the face, but so far nothing. I hope devs would see this and it gets their attention now.

About KK_fnc_distanceASL. It takes coordinates. If you have objects you can simply:

[getPosASL _obj1, getPosASL _obj2] call KK_fnc_distanceASL;

Enjoy,
KK

EDIT: Mystery solved, thanks to SaMatra!  The answer is simple. The distance command will re-interpret coordinates as if you obtained them from position or getPos commands. This means if you are over ground it will treat them as ATL position, and over sea it will treat them as ASLW position (including waves). As I’ve done my experiment on Stratis, at 3477, 5300, 7000 and 8768 m distances, the coordinates appeared to be over land, hence the huge difference in results.

What this means? This means that distance command is only good for measuring distances between objects and known relative positions, relative to either sea or ground. Apparently there is no command in Arma that would just return distance between 2 absolute points. If such command is added it would expected to be very fast and use simple Euclidean equation and very fast ASL positioning. If you would like to see such command, please upvote this ticket.

I can now give myself a well deserved facepalm .

EDIT2: BIS introduced vectorDistance command which can be used to calculate simple euclidean distance of 2 points, sort of like proposed distanceASL. Below I’ve included a little example of available vector operations to show what is available and how it could be used:

//define 2 points _p1 = [1,1,1]; _p2 = [5,5,5]; //distance between _p1 and _p2 _d1 = _p1 vectorDistance _p2; //6.9282 //vector from _p1 to _p2 _v1 = _p2 vectorDiff _p1; //[4,4,4] //alternative way to calc distance via vector magnitude _m1 = vectorMagnitude _v1; //6.9282 //extend vector twice the size _v2 = _v1 vectorMultiply 2; //[8,8,8] //distance from tail to tip of extended vector _m2 = vectorMagnitude _v2; //13.8564 //find coordinates of the tip _p3 = _p1 vectorAdd _v2; //[9,9,9] //alt way of finding distance _d2 = _p1 vectorDistance _p3; //13.8564