madrussian 347 Posted February 10, 2019 Here are a handful of functions I wrote a while back that I figure might help some folks out. MRU_V3_QRotation is the big one. Rotate a 3D vector around any axis in 3D space by any number of degrees. Useful in both world space and model space. [Feel free to use these in any way you see fit. If you use in a release, please add simple credit, as these took a while to develop.] Here ya go. Have fun! MRU_Q_Conjugate = { // MRU_Q_Conjugate by MadRussian (created long ago, updated 2/11/19) // This returns a simple quaternion conjugate. // Call with: [Quaternion] call MRU_Q_Conjugate; // Example: _quaternionConjugate = [[1,1,1,0]] call MRU_Q_Conjugate; // Result is [-1,-1,-1,0] private ["_x","_y","_z","_w"]; params ["_Q"]; _x = -(_Q select 0); _y = -(_Q select 1); _z = -(_Q select 2); _w = (_Q select 3); [_x, _y ,_z ,_w] }; MRU_Q_FromV3 = { // MRU_Q_FromV3 by MadRussian (created long ago, updated 2/11/19) // This is a simple vector to quaternion conversion. // Call with: [Vector3] call MRU_Q_FromV3; // Example: _quaternion = [[1,1,1]] call MRU_Q_FromV3; // Result is [1,1,1,0] params ["_V"]; [_V select 0, _V select 1, _V select 2, 0] }; MRU_Q_Multiply = { // MRU_Q_Multiply by MadRussian (created long ago, updated 2/11/19) // This performs a simple quaternion multiplication. // Call with: [Quaternion1, Quaternion2] call MRU_Q_Multiply; // Example: _quaternion = [ [1,1,1,0], [0,0,0,1] ] call MRU_Q_Multiply; // Result is [1,1,1,0] private ["_x","_y","_z","_w"]; params ["_qA","_qB"]; _x = (_qA select 3)*(_qB select 0) + (_qA select 0)*(_qB select 3) + (_qA select 1)*(_qB select 2) - (_qA select 2)*(_qB select 1); _y = (_qA select 3)*(_qB select 1) - (_qA select 0)*(_qB select 2) + (_qA select 1)*(_qB select 3) + (_qA select 2)*(_qB select 0); _z = (_qA select 3)*(_qB select 2) + (_qA select 0)*(_qB select 1) - (_qA select 1)*(_qB select 0) + (_qA select 2)*(_qB select 3); _w = (_qA select 3)*(_qB select 3) - (_qA select 0)*(_qB select 0) - (_qA select 1)*(_qB select 1) - (_qA select 2)*(_qB select 2); [_x, _y, _z, _w] }; MRU_Q_Normalize = { // MRU_Q_Normalize by MadRussian (created long ago, updated 2/11/19) // This performs a simple quaternion normalize. // Call with: [Quaternion] call MRU_Q_Normalize; // Example: _quaternionNormal = [[7,0,0,0]] call MRU_Q_Normalize; // Result is [1,0,0,0] private ["_l","_result"]; params ["_Q"]; _l = sqrt ( (_Q select 0)*(_Q select 0) + (_Q select 1)*(_Q select 1) + (_Q select 2)*(_Q select 2) + (_Q select 3)*(_Q select 3) ); _result = [0,0,0,0]; if (_l != 0) then { _result = [(_Q select 0)/_l, (_Q select 1)/_l, (_Q select 2)/_l, (_Q select 3)/_l] }; _result }; MRU_V3_QRotation = { // MRU_V3_QRotation by MadRussian (created long ago, updated 2/11/19) // This performs a simple(?) quaternion rotation. // Call with: [OrigVector, RotationAxis, RotationAngle] call MRU_V3_QRotation; // where OrigVector is the original 3D vector to be translated // RotationAxis is the rotational axis to be rotated about, represented by a 3D vector // RotationalAngle is the angle to rotate by in degrees // // Example: _vector3 = [ [0,0,1], [1,0,0], 90 ] call MRU_V3_QRotation; // would result in a rotated 3D vector of [0,1,0] private ["_origQ","_rotAxisQ","_rotAxisNormQ","_sinAD","_rotAxisTransQ","_rotAxisConjQ","_preResultQ","_resultQ"]; params ["_origV","_rotAxis","_rotAng"]; _origQ = [_origV] call MRU_Q_FromV3; _rotAxisQ = [_rotAxis] call MRU_Q_FromV3; _rotAxisNormQ = [_rotAxisQ] call MRU_Q_Normalize; _sinAD = sin(_rotAng/2); _rotAxisTransQ = [ (_rotAxisNormQ select 0)*_sinAD, (_rotAxisNormQ select 1)*_sinAD, (_rotAxisNormQ select 2)*_sinAD, cos(_rotAng/2) ]; _rotAxisConjQ = [_rotAxisTransQ] call MRU_Q_Conjugate; _preResultQ = [_rotAxisTransQ, _origQ] call MRU_Q_Multiply; _resultQ = [_preResultQ, _rotAxisConjQ] call MRU_Q_Multiply; [_resultQ select 0, _resultQ select 1, _resultQ select 2] }; Update 2/11/19: Cleaned up the comments & examples, removed an empty private block. 3 2 Share this post Link to post Share on other sites
johnnyboy 3801 Posted February 10, 2019 Sweet! Thanks man. I've been wanting to simply rotate by degrees forever. 1 Share this post Link to post Share on other sites