  # hatbat

Member

11

## Community Reputation

10 Good

• Rank
Private First Class

## Profile Information

• Location
London, England

## Contact Methods

• Steam url id
http://steamcommunity.com/profiles/76561198059004332/

## Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

1. Nah. Swapping object 1 and 2 had no effect, at least when calling the function. I've negated the result of _ETA as you suggested and that's provided a suitable workaround. It's also had the effect of fixing _DIST, which previously didn't work. I don't see how this couldn't be an error in the formula. I think the problem stems from the numerator which returns negative when it should be returning positive (at least I think so). Maybe when you get some time you could figure out why? This is the test scenario. https://www.dropbox.com/s/r1pkqe388jwukju/Virtual%20Velocity%20Testing.VR.zip?dl=0
2. Well... I set up some pretty extensive debugging and found that _numerator was evaluating to 0. I thought that was a little odd so I began to input some example numbers into a calculator and quickly realised the coordinates for the objects were identical. All down to this little typo. private _pos1 = if(_is_pos_obj1) then {_obj1} else {getPosASL _obj1}; private _pos2 = if(_is_pos_obj2) then {_obj2} else {getPosASL _obj1}; Since that's sorted I'd like to get on to the issue of the ETA being inverted. I don't think you quite understood what I meant when I said the ETA was negative so here's an example: Note how the ETA in the system chat is negative whilst moving towards the target and positive when away? Are _numerator and _dominator in the wrong order? This is the current script if it helps: /* Author: Sarogahtyp Description: Calculates the current estimated Time of arrival (ETA) at a rendevouz point and the distance at this point for two (flying) objects. the rendevouz point is the point where the two object will get closest together with their actual velocity vectors. Arguments: 0: object1 or 3D ASL position 1 - one of both objects or its position 1: object2 or 3D ASL position 2 - the other object or its position 2: 3D velocity vector for position 1 - only needed if argument 1 is position 3: 3D velocity vector for position 2 - only needed if argument 2 is position return value: array with 2 components 0: ETA 1: Minimum distance (on ETA) */ params [ ["_obj1", objNull, [objNull, []]], ["_obj2", objNull, [objNull, []]], ["_vel1", objNull, [[]]], ["_vel2", objNull, [[]]] ]; if(isNull _obj1 || isNull _obj2) exitWith {true}; private _is_pos_obj1 = (typeName _obj1 isEqualTo "ARRAY"); private _is_pos_obj2 = (typeName _obj2 isEqualTo "ARRAY"); if (( _is_pos_obj1 && isNull _vel1 ) || ( _is_pos_obj2 && isNull _vel2 )) exitWith {true}; private ["_ETA", "_DIST", "_numerator", "_dominator"]; //get ASL positions and split into coordinates private _pos1 = if(_is_pos_obj1) then {_obj1} else {getPosASL _obj1}; private _pos2 = if(_is_pos_obj2) then {_obj2} else {getPosASL _obj2}; _pos1 params ["_p1x", "_p1y", "_p1z"]; _pos2 params ["_p2x", "_p2y", "_p2z"]; //get velocities and split into coordinates _vel1 = if(_is_pos_obj1) then {_vel1} else {velocity _obj1}; _vel2 = if(_is_pos_obj2) then {_vel2} else {velocity _obj2}; _vel1 params ["_v1x", "_v1y", "_v1z"]; _vel2 params ["_v2x", "_v2y", "_v2z"]; //calculate ETA _numerator = (_p2y-_p1y)*_v2y + (_p2x-_p1x)*_v2x + (_p1z-_p2z)*_v1z + (_p1y-_p2y)*_v1y + (_p1x-_p2x)*_v1x + _v2z*_p2z - _v2z*_p1z; _dominator = _v2y^2 - 2*_v1y*_v2y + _v2x^2 - 2*_v1x*_v2x + _v1z^2 - 2*_v2z*_v1z + _v1y^2 + _v1x^2 + _v2z^2; if (_dominator != 0) then { _ETA = _numerator / _dominator; systemChat format ["Numerator: %1, Dominator: %2, ETA: %3, Obj1: %4, Pos1: %5 %6 %7, Vel1: %8 %9 %10, Obj2: %11, Pos2: %12 %13 %14, Vel2: %15 %16 %17", round _numerator, round _dominator, round _ETA, _obj1, round _p1x, round _p1y, round _p1z, round _v1x, round _v1y, round _v1z, _obj2, round _p2x, round _p2y, round _p2z, round _v2x, round _v2y, round _v2z]; //calculate distance on ETA _DIST = sqrt ( ((_v2y-_v1y)*_ETA+_p2y-_p1y )^2 + ((_v2x-_v1x)*_ETA+_p2x-_p1x)^2 + ((_v1z-_v2z)*_ETA-_p2z+_p1z)^2 ); } else {_ETA = '∞'; _DIST = '∞';}; [_ETA, _DIST]
3. Yeah that's zero too. Have you re-read the script? Perhaps it's just something obvious that you missed.
4. I fixed that and I'm not getting any more error reports but for reasons unknown _ETA always evaluates to zero, despite _obj1, _obj2, _vel1 and _vel2 all returning what they should be after having checked them. Perhaps you made a mistake when writing the equation? This is what I have right now: /* Author: Sarogahtyp Description: Calculates the current estimated Time of arrival (ETA) at a rendevouz point and the distance at this point for two (flying) objects. the rendevouz point is the point where the two object will get closest together with their actual velocity vectors. Arguments: 0: object1 or 3D ASL position 1 - one of both objects or its position 1: object2 or 3D ASL position 2 - the other object or its position 2: 3D velocity vector for position 1 - only needed if argument 1 is position 3: 3D velocity vector for position 2 - only needed if argument 2 is position return value: array with 2 components 0: ETA 1: Minimum distance (on ETA) */ params [ ["_obj1", objNull, [objNull, []]], ["_obj2", objNull, [objNull, []]], ["_vel1", objNull, [[]]], ["_vel2", objNull, [[]]] ]; if(isNull _obj1 || isNull _obj2) exitWith {true}; private _is_pos_obj1 = (typeName _obj1 isEqualTo "ARRAY"); private _is_pos_obj2 = (typeName _obj2 isEqualTo "ARRAY"); if (( _is_pos_obj1 && isNull _vel1 ) || ( _is_pos_obj2 && isNull _vel2 )) exitWith {true}; private ["_ETA", "_DIST", "_numerator", "_dominator"]; //get ASL positions and split into coordinates private _pos1 = if(_is_pos_obj1) then {_obj1} else {getPosASL _obj1}; private _pos2 = if(_is_pos_obj2) then {_obj2} else {getPosASL _obj1}; _pos1 params ["_p1x", "_p1y", "_p1z"]; _pos2 params ["_p2x", "_p2y", "_p2z"]; //get velocities and split into coordinates _vel1 = if(_is_pos_obj1) then {_vel1} else {velocity _obj1}; _vel2 = if(_is_pos_obj2) then {_vel2} else {velocity _obj2}; _vel1 params ["_v1x", "_v1y", "_v1z"]; _vel2 params ["_v2x", "_v2y", "_v2z"]; //calculate ETA _numerator = (_p2y-_p1y)*_v2y + (_p2x-_p1x)*_v2x + (_p1z-_p2z)*_v1z + (_p1y-_p2y)*_v1y + (_p1x-_p2x)*_v1x + _v2z*_p2z - _v2z*_p1z; _dominator = _v2y^2 - 2*_v1y*_v2y + _v2x^2 - 2*_v1x*_v2x + _v1z^2 - 2*_v2z*_v1z + _v1y^2 + _v1x^2 + _v2z^2; if (_dominator != 0) then { _ETA = _numerator / _dominator; //calculate distance on ETA _DIST = sqrt ( ((_v2y-_v1y)*_ETA+_p2y-_p1y )^2 + ((_v2x-_v1x)*_ETA+_p2x-_p1x)^2 + ((_v1z-_v2z)*_ETA-_p2z+_p1z)^2 ); } else {_ETA = '∞'; _DIST = '∞';}; systemChat str _ETA; //DEBUG [_ETA, _DIST]
5. First error. I would sort this out but I've never used params before. Where is it missing?
6. What I meant is that it was like the ETA was inverted. Positive when moving away and negative when moving together. For now I've just dodged the zero divisor by adding this if (velocityEquations != 0) then { but I think it might be handy to have it return perhaps an infinity symbol if the velocity was zero. Could that be done?
7. At the start of a mission the velocity will be zero right? That doesn't sit so well with this part: t_dmin = positionEquations / velocityEquations; I also found that the ETA seemed to give a negative number when the two objects were moving towards each other. I wouldn't have a clue why that is and it could possibly be my fault but I found that it was fairly simple just to use abs when fetching the result. abs (round t_dmin); Still, I'm going to test your script if I can figure how to implement a function.
8. Wow, this is rather fortunate timing. I had just written a much more simplistic script based off your post and was about to bring forward some issues. I'll test your script first but I have a feeling there might be the same problem. This is what I wrote. hostile = (nearestObjects [_this, ["Man"], 100]) select 1; //"B_Fighter_Pilot_F" while {true} do { P1x = getPosASL _this select 0; P1y = getPosASL _this select 1; P1z = getPosASL _this select 2; P2x = getPosASL hostile select 0; P2y = getPosASL hostile select 1; P2z = getPosASL hostile select 2; V1x = velocity _this select 0; V1y = velocity _this select 1; V1z = velocity _this select 2; V2x = velocity hostile select 0; V2y = velocity hostile select 1; V2z = velocity hostile select 2; positionEquations = ( (P2y-P1y)*V2y + (P2x-P1x)*V2x + (P1z-P2z)*V1z + (P1y-P2y)*V1y + (P1x-P2x)*V1x + V2z*P2z - V2z*P1z ); velocityEquations = ( V2y^2 - 2*V1y*V2y + V2x^2 - 2*V1x*V2x + V1z^2 - 2*V2z*V1z + V1y^2 + V1x^2 + V2z^2 ); if (velocityEquations != 0) then { t_dmin = positionEquations / velocityEquations; hintSilent parseText format [" Your speed: %1 m/s <br /> Hostile Speed: %2 m/s <br /> ETA = %3 seconds ", round ((velocityModelSpace _this) select 1), round ((velocityModelSpace hostile) select 1), abs (round t_dmin)]; } else { hintSilent ""; }; sleep 0.1; };