Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds edge case check to vectRotate3D #1373

Closed
wants to merge 1 commit into from

Conversation

LorenLuke
Copy link
Contributor

Intercepts an error if 0 is entered as a theta value, and just returns the vector unchanged.

When merged this pull request will:

  • Prevent an error when theta is zero.
  • Return an unchanged vector in vectRotate3D, if theta is zero.

Intercepts an error if 0 is entered as a theta value, and just returns the vector unchanged.
@commy2
Copy link
Contributor

commy2 commented Sep 20, 2020

[[1,2,3], [1,0,0], 0] call CBA_fnc_vectRotate3D // 0

There is no error here. And I don't see why it would error, as there are no divisions that could be by zero.
On the other hand, the function used to return copies, but now it returns references some times for no apparent reason. To me it looks like this pull creates a potential for errors and fixes nothing.

Also, not to be petty, but the fuck was that change 3 years ago:
d91502d

The author says your name, but I remember quite well translating the algorith to SQF myself.

@commy2
Copy link
Contributor

commy2 commented Sep 26, 2020

Close?

@LorenLuke
Copy link
Contributor Author

LorenLuke commented Sep 27, 2020

Close

There's something odd going on that I can't seem to readily reproduce in the abstract, and I'm not sure what exactly is happening when it does happen, figured this would potentially have solved it.
image
(As it seems to only happen if I don't put in a provision for if (_angleDif > 0) then {})

Also, not to be petty, but the fuck was that change 3 years ago:
d91502d
The author says your name, but I remember quite well translating the algorith to SQF myself.

Which wasn't before this (acemod/ACE3#6145) or this (07174a7). You did contribute in the threads to be sure, but a bunch of others did too, I just suggested and wrote the thing as it basically became in the CBA pr.

@commy2
Copy link
Contributor

commy2 commented Sep 28, 2020

Ok, maybe I am getting old.

Just post the code that raises the error, so it can be reproduced.

@LorenLuke
Copy link
Contributor Author

Just a whole block (without context or some of the variables I assure you are present) that seems to be one example of a repeat offender-

{
    _x params ["_object", "_eh", "_fuze", "_seekers", "_flightProfile", "_flightParams"];
    _eh params ["_shooter", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_instigator"];

    //seeker params ["_seekerObject", "_weapon", "_magazine", "_seekerType", "_enabled", "_seekerDirection", "_seekerLookVector", "_seekerLookDirection", "_caged", "_slaves", "_tracking", "_launched", "_lastSeekerReturns", "_sensorArray", "_seekerMisc"];
    //_lastSeekerReturns params ["_lastSeekerReturnVector", "_lastSeekerReturnPos", "_lastSeekerReturnDir", "_lastSeekerReturnRelPos"];

    _flightProfile params ["_flightProfileObject", "_flightProfileType", "_flightProfileSeekers", "_lastFlightProfileReturns", "_flightProfileMisc"];
    _lastFlightProfileReturns params ["_lastProfileReturnVector", "_lastProfileReturnPos", "_lastProfileReturnDir", "_lastProfileReturnRelPos"];

    _flightParams params ["_degreesPerSecond", "_launchTime", "_launchPos", "_launchVector"];

    //If no object/projectile, stop everything
    if ((!alive _object) || (isNull _object)) exitWith {
        GVAR(projectiles) deleteAt _forEachIndex;
    };

    private _toVector = +_lastProfileReturnVector;
    
    if !(_toVector isEqualTo [0, 0, 0]) then {
        private _velocity = velocity _projectile;
        private _vectorDir =  vectorDir _projectile;
        private _angleDif = acos (_vectorDir vectorDotProduct _toVector);
        private _crossVector =  _velocity vectorCrossProduct _toVector;
    
        private _vectorUp = vectorUp _projectile; 
        private _newVectorDir = [_vectorDir, _crossVector, _angleDif min (_deltaTime * _degreesPerSecond)] call CBA_fnc_vectRotate3D;
        private _newVectorUp = [_vectorUp, _crossVector, _angleDif min (_deltaTime * _degreesPerSecond)] call CBA_fnc_vectRotate3D;
        
        _projectile setVectorDir _newVectorDir;
        _projectile setVectorUp _newVectorUp;
        _projectile setVelocity ( ((_newVectorDir) vectorMultiply (vectorMagnitude _velocity))   vectorAdd [0,0,-9.80665 * _deltaTime]);

    };

} forEach GVAR(projectiles);

@commy2
Copy link
Contributor

commy2 commented Oct 1, 2020

Add some debugging systemChat str _this for input validation at the top of the function and then repeat whatever you are doing to trigger this issue. Maybe the global toFixed as well to make sure number serialization does not hide something.

@LorenLuke
Copy link
Contributor Author

@commy2
I know it's been a while, but I recently got back into the swing of things and just happened to capture a glimpse of when two vectors are aligned via a dot-product, I would see -1.#IND pop up/flicker. I wonder if this is what's happening here, and as such, while this may not be the needed fix, it may be the root cause of the issue.

@commy2
Copy link
Contributor

commy2 commented Jan 6, 2021

Give some numbers to reproduce.

@LorenLuke
Copy link
Contributor Author

Give some numbers to reproduce.

copied from the RPT file, Format is V1, V2, and V1 vectorDotProduct V2. All _theta values are equal to acos(V1 vectorDotProduct V2)

4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310565,0.944546,-0.106686]\n1"
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310622,0.944529,-0.106669]\n1"
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310628,0.944532,-0.106627]\n1"
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error vectormultiply: Type Not a Number, expected Number
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error Generic error in expression
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310584,0.944546,-0.106628]\n1"
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error vectormultiply: Type Not a Number, expected Number
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error Generic error in expression
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310583,0.944553,-0.106573]\n1"
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310567,0.944555,-0.1066]\n1"
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error vectormultiply: Type Not a Number, expected Number
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 Error in expression <ate _cosTheta = cos _theta;



(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
4:50:20   Error Generic error in expression
4:50:20 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310495,0.94458,-0.106591]\n1"
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310417,0.944605,-0.106596]\n1"
4:50:20 "[0.310837,0.944462,-0.106643]\n[0.310373,0.94462,-0.106592]\n1"

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

???

toFixed 20;
private _vec1 = [0.310837,0.944462,-0.106643]; 
private _vec2 = [0.310628,0.944532,-0.106627]; 
[_vec1, _vec2, 0] call CBA_fnc_vectRotate3D

returns [0.31083700060844421000,0.94446200132369995000,-0.10664299875497818000] without error.

Maybe use

toFixed 20;

at the top of the script to keep more digits on the floats.

@LorenLuke
Copy link
Contributor Author

Apparently it's a super-tiny issue more with their vector dot product stuff, than anything here, I guess.

[0.26993277668952942000,0.95782107114791870000,-0.09856489300727844200],0.99999934434890747000]
 6:14:13 ["%1\n%2\n%3",[0.27024456858634949000,0.95774263143539429000,-0.09847403317689895600],[0.26995429396629333000,0.95781433582305908000,-0.09857137501239776600],1.00000000000000000000]
 6:14:13 ["%1\n%2\n%3",[0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300],[0.26996955275535583000,0.95781064033508301000,-0.09856573492288589500],1.00000011920928960000]
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error vectormultiply: Type Not a Number, expected Number
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error Generic error in expression
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 ["%1\n%2\n%3",[0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300],[0.26997107267379761000,0.95780789852142334000,-0.09858801215887069700],1.00000011920928960000]
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error vectormultiply: Type Not a Number, expected Number
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error Generic error in expression
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 ["%1\n%2\n%3",[0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300],[0.26994735002517700000,0.95781952142715454000,-0.09854075312614440900],1.00000011920928960000]
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error vectormultiply: Type Not a Number, expected Number
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 Error in expression <ate _cosTheta = cos _theta;

(_vector vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error position: <vectorMultiply _cosTheta) vectorAdd
((_n>
 6:14:13   Error Generic error in expression
 6:14:13 File \x\cba\addons\vectors\fnc_vectRotate3D.sqf [CBA_fnc_vectRotate3D]..., line 1796
 6:14:13 ["%1\n%2\n%3",[0.27024453878402710000,0.95774251222610474000,-0.09847402572631835900],[0.26992955803871155000,0.95782536268234253000,-0.09853193163871765100],0.99999988079071045000]
 6:14:13 ["%1\n%2\n%3",[0.27018120884895325000,0.95780962705612183000,-0.09799453616142272900],[0.26996532082557678000,0.95781177282333374000,-0.09856578707695007300],0.99999982118606567000]
 6:14:13 ["%1\n%2\n%3",[0.26986634731292725000,0.95794826745986938000,-0.09750540554523468000],[0.26996123790740967000,0.95781612396240234000,-0.09853519499301910400],0.99999946355819702000]

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

toFixed 20;
private _vec1 = [0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300]; 
private _vec2 = [0.26996955275535583000,0.95781064033508301000,-0.09856573492288589500]; 
private _theta = 1.00000011920928960000;
[_vec1, _vec2, _theta] call CBA_fnc_vectRotate3D

[0.27024596929550171000,0.95774173736572266000,-0.09847897291183471700]
No error.

Also, now theta is != 0. That means the current PR doesn't fix it?

@LorenLuke
Copy link
Contributor Author

LorenLuke commented Jan 9, 2021

No error

_theta there would be acos(1.00000011920928960000) (third values are the dot-products, not the thetas);

Also, now theta is != 0. That means the current PR doesn't fix it?

That's my guess, since this is coming from an issue with the vanilla vector dot product generating values over 1 from unit vectors, since acos(_anyNumberTheTeensiestBitOverOne) leads to this issue.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

Can you just give me the code to reproduce please? I don't get it to error out with your numbers.

@LorenLuke
Copy link
Contributor Author

LorenLuke commented Jan 9, 2021

toFixed 20; 
_vec1 = [0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300]; 
_vec2 = [0.26996955275535583000,0.95781064033508301000,-0.09856573492288589500];  
 
_crossVector = (vectorNormalized _vec1) vectorCrossProduct (vectorNormalized _vec2); 
_theta = acos(_vec1 vectorDotProduct _vec2); 
 
[_vec1, _crossVector, _theta] call CBA_fnc_vectRotate3D;

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

toFixed 20;  
_vec1 = [0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300];  
_vec2 = [0.26996955275535583000,0.95781064033508301000,-0.09856573492288589500];   
  
_crossVector = (vectorNormalized _vec1) vectorCrossProduct (vectorNormalized _vec2);  
_theta = acos(_vec1 vectorDotProduct _vec2);  

_theta

reports -1.#IND0000000000000000

  1. your theta already is not a number. Garbage in garbage out.
  2. Funnily, toFixed appends NaN with zeros, lol

@LorenLuke
Copy link
Contributor Author

your theta already is not a number. Garbage in garbage out.
Which is amazing because a unit-vector shouldn't be longer than 1, so a dot-product of two unit vectors should never be more than 1.

As I said, I think I can blame BI for this one, rather than the script, though the 'if > 0' seems to catch this weirdness anyhow.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

Sure, however

  1. The bug in your code exists whether you use vectRotate3D or anything else not even from CBA that expects number, but not NaN.
  2. The proposed change in the pull request does not fix the issue.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

toFixed 20; 
_vec1 = [0.27024456858634949000,0.95774263143539429000,-0.09847404062747955300]; 
_vec2 = [0.26996955275535583000,0.95781064033508301000,-0.09856573492288589500]; 
 
_crossVector = (vectorNormalized _vec1) vectorCrossProduct (vectorNormalized _vec2); 
_theta = acos ((_vec1 vectorDotProduct _vec2) min 1); 
 
[_vec1, _crossVector, _theta] call CBA_fnc_vectRotate3D;

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

Also, pretty sure you should use vectorCos over vectorDorProduct if you're not sure that the inputs are unit vectors, which the vectorNormalized's above imply to me.

@LorenLuke
Copy link
Contributor Author

LorenLuke commented Jan 9, 2021

The bug in your code exists whether you use vectRotate3D or anything else not even from CBA that expects number, but not NaN.
The proposed change in the pull request does not fix the issue.

If doing something a bit much like

if (!(_theta < 0) && {!(_theta > 0)}) exitWith {_vector};

isn't right out, I'll change it to that. Otherwise probably could close the PR.

Also, pretty sure you should use vectorCos over vectorDorProduct if you're not sure that the inputs are unit vectors, which the vectorNormalized's above imply to me.

I mean, that will still throw the same error for these values, but point noted.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

!(_theta < 0) && !(_theta > 0)
=> _theta >= 0 && _theta <= 0
=> _theta == 0

Huh?

@LorenLuke
Copy link
Contributor Author

It returns the vector when _theta == 0 OR not a number.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

So it's just:

if (_theta isEqualType 0 && {_theta == 0})

Basically what you want is for the function to type check.

@LorenLuke
Copy link
Contributor Author

So it's just:

if (_theta isEqualType 0 && {_theta == 0})

Basically what you want is for the function to type check.

Yes, had been unaware of the isEqualType function until just now, and knew isNumber only worked in configs, hence the much more hacky solution.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

Would have to test that, but pretty sure isEqualType does not report true for NaN vs NUMBER.

The thing is, I see no justification why returning the original vector is necessarily correct when _theta is NaN. Why not any other rotated vector?

@LorenLuke
Copy link
Contributor Author

The thing is, I see no justification why returning the original vector is necessarily correct when _theta is NaN. Why not any other rotated vector?

If I'm understanding your question, my response is that if you rotate a vector by zero degrees, you're not rotating it at all, and it returns the same vector as you started with, after the rotation operation. Similarly, if you're trying to rotate a vector by anything but a number... you're not rotating it at all, which is the same effect as rotating it zero degrees, which leaves you with the same vector you started with, after having attempted your rotation matrix operation. So the outcome being the same, the case of the returned value should also be the same.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

The only thing I could see is it raising an error via params input validation, then defaulting _theta to 0.

params ["_vector", "_rotationAxis", ["_theta", 0, [0]]];

But it would make the function slightly slower. And inconsistent with the other math functions that trust input.

@LorenLuke
Copy link
Contributor Author

But it would make the function slightly slower. And inconsistent with the other math functions that trust input.

You're the code curator. If you don't want having any check like that to be the case, you can close the PR without my objection.

@commy2
Copy link
Contributor

commy2 commented Jan 9, 2021

I'd rather BI fixes vectorCos so it clamps [-1,1].

@commy2 commy2 closed this Jan 9, 2021
@LorenLuke LorenLuke deleted the patch-2 branch January 9, 2021 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants