diff --git a/addons/vectors/CfgFunctions.hpp b/addons/vectors/CfgFunctions.hpp index 77bd304b9..06b5c8f84 100644 --- a/addons/vectors/CfgFunctions.hpp +++ b/addons/vectors/CfgFunctions.hpp @@ -1,116 +1,24 @@ -// ----------------------------------------------------------------------------- -// Automatically generated by 'functions_config.rb' -// DO NOT MANUALLY EDIT THIS FILE! -// ----------------------------------------------------------------------------- -class CfgFunctions -{ - class CBA - { - class Vectors - { - // CBA_fnc_polar2vect - class polar2vect - { - description = "Creates a vector based on a inputted magnitude, direction and elevation"; - file = "\x\cba\addons\vectors\fnc_polar2vect.sqf"; - }; - // CBA_fnc_scaleVect - class scaleVect - { - description = "scales a specified vector by a specified factor."; - file = "\x\cba\addons\vectors\fnc_scaleVect.sqf"; - }; - // CBA_fnc_scaleVectTo - class scaleVectTo - { - description = "scales a vector so that its new Magnitude is equivalent to a specified value."; - file = "\x\cba\addons\vectors\fnc_scaleVectTo.sqf"; - }; - // CBA_fnc_simplifyAngle - class simplifyAngle - { - description = "Returns an equivalent angle to the specified angle in the range 0 to 360. This allows adjustment from negative angles and angles equal or greater to 360. If the inputted angle is in the range 0 - 360, it will be returned unchanged."; - file = "\x\cba\addons\vectors\fnc_simplifyAngle.sqf"; - }; - // CBA_fnc_simplifyAngle180 - class simplifyAngle180 - { - description = "Returns an equivalent angle to the specified angle in the range -180 to 180. If the inputted angle is in the range -180 to 180, it will be returned unchanged."; - file = "\x\cba\addons\vectors\fnc_simplifyAngle180.sqf"; - }; - // CBA_fnc_vect2polar - class vect2polar - { - description = "Parameters:"; - file = "\x\cba\addons\vectors\fnc_vect2polar.sqf"; - }; - // CBA_fnc_vectAdd - class vectAdd - { - description = "Returns the sum of two vectors. Vectors can be 2D or 3D"; - file = "\x\cba\addons\vectors\fnc_vectAdd.sqf"; - }; - // CBA_fnc_vectCross - class vectCross - { - description = "Returns the cross product vector of two vectors. Vectors must both be three dimensional."; - file = "\x\cba\addons\vectors\fnc_vectCross.sqf"; - }; - // CBA_fnc_vectCross2D - class vectCross2D - { - description = "Returns the cross product vector of two 2D vectors. The result is an integer value (positive or negative), representing the magnitude of the height component."; - file = "\x\cba\addons\vectors\fnc_vectCross2D.sqf"; - }; - // CBA_fnc_vectDir - class vectDir - { - description = "Returns the angle of a vector with the given i and k coordinates in the range 0 to 360."; - file = "\x\cba\addons\vectors\fnc_vectDir.sqf"; - }; - // CBA_fnc_vectDot - class vectDot - { - description = "Returns the dot product of two vectors. Vectors can be either two or three dimesions, but they must be the same dimension."; - file = "\x\cba\addons\vectors\fnc_vectDot.sqf"; - }; - // CBA_fnc_vectElev - class vectElev - { - description = "Returns the angle of elevation of a 3D vector with the given i, j and k coordinates in the range -90 to 90."; - file = "\x\cba\addons\vectors\fnc_vectElev.sqf"; - }; - // CBA_fnc_vectMagn - class vectMagn - { - description = "Returns the magnitude of a 3D vector with the given i, j and k coordinates."; - file = "\x\cba\addons\vectors\fnc_vectMagn.sqf"; - }; - // CBA_fnc_vectMagn2D - class vectMagn2D - { - description = "Returns the magnitude of a vector with the given i and k coordinates or the magnitude of the i and k components of a 3D vector."; - file = "\x\cba\addons\vectors\fnc_vectMagn2D.sqf"; - }; - // CBA_fnc_vectRotate2D - class vectRotate2D - { - description = "Rotates a 2D vector around a given center, for rotating of a vector from its origin, use BIS_fnc_rotateVector2D"; - file = "\x\cba\addons\vectors\fnc_vectRotate2D.sqf"; - }; - // CBA_fnc_vectSubtract - class vectSubtract - { - description = "Returns the difference of two vectors. Vectors can be 2D or 3D."; - file = "\x\cba\addons\vectors\fnc_vectSubtract.sqf"; - }; - // CBA_fnc_testVectors - class testVectors - { - description = "Internal Self Check. Check the RPT file for results."; - file = "\x\cba\addons\vectors\test.sqf"; - }; +class CfgFunctions { + class CBA { + class Vectors { + PATHTO_FNC(polar2vect); + PATHTO_FNC(scaleVect); + PATHTO_FNC(scaleVectTo); + PATHTO_FNC(simplifyAngle); + PATHTO_FNC(simplifyAngle180); + PATHTO_FNC(vect2polar); + PATHTO_FNC(vectAdd); + PATHTO_FNC(vectCross); + PATHTO_FNC(vectCross2D); + PATHTO_FNC(vectDir); + PATHTO_FNC(vectDot); + PATHTO_FNC(vectElev); + PATHTO_FNC(vectMagn); + PATHTO_FNC(vectMagn2D); + PATHTO_FNC(vectRotate2D); + PATHTO_FNC(vectRotate3D); + PATHTO_FNC(vectSubtract); }; }; }; diff --git a/addons/vectors/fnc_vectRotate3D.sqf b/addons/vectors/fnc_vectRotate3D.sqf new file mode 100644 index 000000000..3387da610 --- /dev/null +++ b/addons/vectors/fnc_vectRotate3D.sqf @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_vectRotate3D + +Description: + Rotates the first vector around the second, clockwise by theta degrees. + +Parameters: + _vector - 3D vector that is to be rotated + _rotationAxis - 3D vector that the first argument is rotated around + _theta - Angle, in degrees clockwise, about which the first vector is rotated + +Returns: + _returnVector - 3D vector returned after rotation + +Examples: + (begin example) + //Rotate 25 degrees right of player weapon direction; + [weaponDirection player, [0,0,1], 25] call CBA_fnc_vectRotate3D; + + //Pitch a projectile's velocity down 10 degrees; + [velocity _projectile, (velocity _projectile) vectorCrossProduct [0,0,1], 10] call CBA_fnc_vectRotate3D; + (end) + +Author: + LorenLuke +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +params ["_vector", "_rotationAxis", "_theta"]; + +private _normalVector = vectorNormalized _rotationAxis; +private _sinTheta = sin _theta; +private _cosTheta = cos _theta; + +// Rodrigues Rotation Formula; +// https://wikimedia.org/api/rest_v1/media/math/render/svg/2d63efa533bdbd776434af1a7af3cdafaff1d578 +(_vector vectorMultiply _cosTheta) vectorAdd +((_normalVector vectorCrossProduct _vector) vectorMultiply _sinTheta) vectorAdd +(_normalVector vectorMultiply ((_normalVector vectorDotProduct _vector) * (1 - _cosTheta))) diff --git a/addons/vectors/test_vectors.sqf b/addons/vectors/test_vectors.sqf index 42167cac5..ae0435877 100644 --- a/addons/vectors/test_vectors.sqf +++ b/addons/vectors/test_vectors.sqf @@ -247,6 +247,33 @@ _result = [[5,-5],[-10,0],-270] call CBA_fnc_vectRotate2D; _expected = [0,-20]; TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); +// UNIT TESTS (vectRotate3D) +_fn = "CBA_fnc_vectRotate3D"; +TEST_DEFINED("CBA_fnc_vectRotate3D",""); + +_result = [[0,0,1],[0,0,1],0] call CBA_fnc_vectRotate3D; +_expected = [0,0,1]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); + +_result = [[0,0,1],[0,0,1],90] call CBA_fnc_vectRotate3D; +_expected = [0,0,1]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); + +_result = [[0,1,0],[0,0,-1],90] call CBA_fnc_vectRotate3D; +_expected = [1,0,0]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); + +_result = [[0,1,0],[0,0,-10],90] call CBA_fnc_vectRotate3D; +_expected = [1,0,0]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); + +_result = [[0,1,0],[1,0,0],90] call CBA_fnc_vectRotate3D; +_expected = [0,-0.00000004371138828674,1]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); + +_result = [[0,1,0],[0,0,1],-45] call CBA_fnc_vectRotate3D; +_expected = [sqrt 2/2,sqrt 2/2,0]; +TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals,_fn); // UNIT TESTS (vectSubtract) _fn = "CBA_fnc_vectSubtract"; @@ -269,4 +296,4 @@ _result = _temp call CBA_fnc_polar2vect; TEST_TRUE([ARR_2(_result,_expected)] call _fnc_vectorEquals, "complex polar 2"); -nil; \ No newline at end of file +nil;