Here is the trajectory function with a minor bug fix, and a commented example of calling it.
Example
//Example of calling trajectory script. In this case for M119. I know a priori that the drag coefficient is 4.5e-4
//so I will not bother pulling it from config
_muzzleOffset = 1.0; // height from ground to axis about which barrel rotates. My estimate for M119.
_muzzleLength = 2.0; // length of barrel from axis about which barrel rotates to the muzzle mouth. My estimate for M119.
_pos = getPosASL _gun;
_vectorDir = _gun weaponDirection _muzzle;
_elev = 90 - acos ((_vectorDir select 2) /
sqrt ((_vectorDir select 0)^2 + (_vectorDir select 1)^2 + (_vectorDir select 2)^2));//barrel elevation i.e. angle
// between horizontal and barrel
_x = _pos select 0;
_y = _pos select 1;
_theta = (360 + (_vectorDir select 0) atan2 (_vectorDir select 1)) mod 360; // compass heading of your barrel
//get ASL pos of muzzle mouth
_x = _x + _muzzleLength * (cos _elev) * (sin _theta);
_y = _y + _muzzleLength * (cos _elev) * (cos _theta);
_z = _muzzleOffset + (_pos select 2) + _muzzleLength * sin _elev; // ASL height of muzzle
//other parameters
_initSpeed = whatever you want; //M119 config value is 1100 m/s.
_drag = 4.5e-4; // drag for M119 shell
_dt = 0.005; // time increment for calculation. Smaller is more accurate but takes longer to calculate.
_maxRange = 5000; //distance at which to stop bothering with calculation.
//call function. takes about 1 second.
_return = [[_x,_y,_z], _vectorDir, _initSpeed, _drag, _maxRange, _dt] call smb_trajectory ;
_npos = _return select 0; // Final position of shell.
_elapsed = _return select 1; // Flight time
_d = _return select 2; // Straight line distance to target.
Trajectory function
private ["_pos", "_vectorDir", "_vm", "_k", "_max", "_dt", "_gl_start","_gl","_posASL", "_x", "_y", "_z",
"_u", "_v", "_w", "_zASL_Land", "_lastPos", "_vel", "_d", "_elapsed"];
_pos = _this select 0;
_vectorDir = _this select 1;
_vm = _this select 2;
_k = _this select 3;
_max = _this select 4;
_dt = _this select 5;
_gl_start = "logic" createVehicleLocal [0,0,0];
_gl = "logic" createVehicleLocal [0,0,0];
_gl_start setPosASL _pos;
_x = _pos select 0;
_y = _pos select 1;
_z = _pos select 2;
_u = _vm * (_vectorDir select 0);
_v = _vm * (_vectorDir select 1);
_w = _vm * (_vectorDir select 2);
_gl_start setPosASL [_x, _y, _z];
_zASL_Land = -666;
_d = -666;
_lastPos =[];
_elapsed = 0;
while {_z > _zASL_Land and _d < _max} do
{
_lastPos = getPos _gl;
_vel = sqrt(_u*_u + _v*_v +_w*_w);
_u = _u - _k *_u*_vel*_dt;
_v = _v - _k *_v*_vel*_dt;
_w = _w - (_k *_w*_vel + 9.8)*_dt;
_x = _x + _u*_dt;
_y = _y + _v*_dt;
_z = _z + _w*_dt;
_gl setPos [_x, _y, 0];
_d = _gl_start distance _gl;
_zASL_Land = (getPosASL _gl) select 2;
_elapsed = _elapsed + _dt;
//hint format ["%1 %2 %3\n%4 %5 %6\n%7 %8",_x,_y,_z,_u,_v,_w,_d,_zASL_Land];
// sleep 0.5;
};
deleteVehicle _gl;
deleteVehicle _gl_start;
if (_d >= _max) then
{
[nil, _elapsed, _d]
}
else
{
[_lastPos, _elapsed, _d]
};
I have used the most primitive means of integrating the trajectory. I also tried a "leap-frog" type scheme similar to RK2(Runge-Kutta 2), but it did not seem to make much difference. I am presently trying a modified RK4 to see if I can keep the same accuracy but increase the function speed. If you can not stand the hiccup that the function causes, test to see if adding a small sleep in the main loop improves things. I can not remember the status of the sleep command in functions. You could also rewrite the function as a script.