Blockland Welcome, Guest. Please login or register.
Did you miss your activation email?
May 23, 2018, 04:54:12 AM

Home Help Login Register
+  Blockland Forum
|-+  Blockland Forums
| |-+  Modification Help
| | |-+  How do I rotate an axis-angle around a normal vector?
Pages: [1] 2
Author Topic: How do I rotate an axis-angle around a normal vector?  (Read 677 times)
Rally

« April 07, 2018, 06:14:01 AM »

Essentially I have a static shape that I can align to the normal of a brick, but as you can see here the rotation, represented by the yellow line, is always facing north.



Essentially what I wanted to do was rotate that axis-angle around the normal (represented by the blue line) so I can adjust which way the static shape is facing. I don't really know how to do this though.

I've been told that the correct way to do this is to sum two axis-angles together, one being a rotation around the normal axis, which would result in one axis-angle that has both rotations implemented. The problem is that I have no idea how to add two axis-angles together in torque script. I think what that entails would be converting both axis-angles to quaternions and then multiplying them together, but I'm literally just not good enough at math to write those functions, and I can't wrap my head around the explanations online.

Any help with this would be appreciated.
Logged
Ad Bot

« Full members do not see ads »

Rally

« April 07, 2018, 06:42:18 AM »

Also does eulerToQuat actually return a quaternion or does it return a regular axis-angle lol?
Logged
Rally

« April 07, 2018, 07:12:08 AM »

I tried defining a new axis-angle rotation like this:
Code:
%newRotAxis = %normal SPC %angle;

And then I converted it to a euler, and combined it with the euler of the axis-angle rotation of the static-shape, and then turned that combined euler into an axis-angle and used it to reset the static-shapes transform, and the weird part is that it sorta worked, but it forgets up on anything that's facing north or south
Logged
Tendon

« April 07, 2018, 09:25:22 AM »

I wish I knew this.  I was able to copy the axis-angle values from blender for what I was doing, but a formula would help with this sort of thing.
Logged
Conan

« April 07, 2018, 12:23:09 PM »

for some reason badspot named the euler to quat function “eulerToMatrix” so maybe try that? i didnt realize eulerToQuat existd
Logged
Rally

« April 07, 2018, 12:37:03 PM »

i didnt realize eulerToQuat existd

Me neither lol. When I tested it it returned the same thing as the axis-angle.

Thanks for the tip about eulerToMatrix. I found these quaternion functions online but I can't speak for their accuracy because I don't actually understand how they work:

Code:
function axisAngleToQuat(%axisAngle) 

// --- Axis Angle to Quaternion Conversion --- 
   %halfAngle = 0.5 * GetWord(%axisAngle, 3); 
     
   %quatW = mCos(%halfAngle); 
   %quatX = mSin(%halfAngle)*getWord(%axisAngle, 0); 
   %quatY = mSin(%halfAngle)*getWord(%axisAngle, 1); 
   %quatZ = mSin(%halfAngle)*getWord(%axisAngle, 2); 
     
   %quat = %quatX SPC %quatY SPC %quatZ SPC %quatW; 
   return %quat; 
}
function quatToAxisAngle(%quat) 

   //%quat = quatNormalize(%quat); 
     
   %quatX = GetWord(%quat, 0); 
   %quatY = GetWord(%quat, 1); 
   %quatZ = GetWord(%quat, 2); 
   %quatW = GetWord(%quat, 3); 
     
   %scale = mSqrt(%quatX*%quatX + %quatY*%quatY + %quatZ*%quatZ); 
 
   %axisX = %quatX / %scale; 
   %axisY = %quatY / %scale; 
   %axisZ = %quatZ / %scale; 
 
   %axisA = mAcos(%quatW)*2; 
     
   %axisAngle = %axisX SPC %axisY SPC %axisZ SPC %axisA; 
   return %axisAngle; 
}
function quatMult(%quatA, %quatB) 

//---Quaternion Multiplication (q1*q2)--- 
   %quatAX = getWord(%quatA, 0); 
   %quatAY = getWord(%quatA, 1); 
   %quatAZ = getWord(%quatA, 2); 
   %quatAW = getWord(%quatA, 3); 
   %quatBX = getWord(%quatB, 0); 
   %quatBY = getWord(%quatB, 1); 
   %quatBZ = getWord(%quatB, 2); 
   %quatBW = getWord(%quatB, 3); 
     
   %quatCX = %quatAW * %quatBX + %quatAX * %quatBW + %quatAY * %quatBZ - %quatAZ * %quatBY; 
   %quatCY = %quatAW * %quatBY - %quatAX * %quatBZ + %quatAY * %quatBW + %quatAZ * %quatBX; 
   %quatCZ = %quatAW * %quatBZ + %quatAX * %quatBY - %quatAY * %quatBX + %quatAZ * %quatBW; 
   %quatCW = %quatAW * %quatBW - %quatAX * %quatBX - %quatAY * %quatBY - %quatAZ * %quatBZ; 
     
   %quatC = %quatCX SPC %quatCY SPC %quatCZ SPC %quatCW; 
   return %quatC; 

Logged
thegoodperry

« April 07, 2018, 01:21:55 PM »

why do quaternions even exist lol
Logged
Conan

« April 07, 2018, 02:29:25 PM »

why do quaternions even exist lol
a quikk google search: cause quaternions are much easier to interpolate between two diff quats, and also the computer can do mathy functions on them far more easily than on axis-angles. the only other comparable representation is matrix rotations, but that's even harder conceptually and requires more memory to store, but requires less math to multiply/whatever.
Logged
irrel

« May 16, 2018, 07:24:35 AM »

I don't know if you're still having this issue or want it solved, but axis-angle rotations are very simple, so I'll explain them for you.

They consist of two parts: a vector and a length (or angle, if you prefer). The vector is the normal to the disc you want to rotate in (in this case, you already have the normal to the plane the object is sitting on), and the length (angle) is equal to the rotation in radians you want to perform. In this case, the angle is the only thing left for you to calculate. Simply normalize the blue vector in the image you provided, then append a fourth number with the angle of rotation. You could probably calculate the angle of rotation by using the direction that the normal is pointing in.
Logged
Punished Rally

« May 16, 2018, 09:15:31 AM »

The problem is that the shape is already rotated to match the normal of the brick it's placed on, what I need to do is a second axis-angle rotation on-top of an existing axis-angle rotation, and combine them into one. The first rotation simply aligns the shape to the normal of the brick, the second rotation would be relative to the direction the player is facing.
Logged
irrel

« May 16, 2018, 02:14:18 PM »

Axis-angle is a way of saying quaternion, so all we have to do is perform quaternion multiplication, where s1 and s2 are the scalars (i.e. the angles) and v1 and v2 are the vectors (i.e. the normals):

(s1 v2 + s2 v1 + v1 x v2, s1 s2 - v1 * v2) = R1R2

with * being vector dot product and x being vector cross product. This applies the rotation R1 before R2. This could be written in code as:

Code:
function combineAxisAngleRotations(%rot1, %rot2) {
%normal1 = vectorNormalize(getWords(%rot1, 0, 2));
%normal2 = vectorNormalize(getWords(%rot2, 0, 2));

%angle1 = getWord(%rot1, 3);
%angle2 = getWord(%rot2, 3);

return vectorScale(%normal2, %angle1) + vectorScale(%normal1, %angle2) + vectorCross(%normal1, %normal2) SPC %angle1 * angle2 - vectorDot(%normal1, %normal2);
}
Logged
Punished Rally

« May 16, 2018, 02:26:07 PM »

I gave your function a shot but I'm not sure I'm using it correctly. I took the rotation that aligns the shape to the normal and passed it as the first argument, and then I created a separate rotation %brickNormal SPC mDegToRad(90) and passed it as the second, but it didn't produce the correct results. Is it something I did wrong?
Logged
irrel

« May 16, 2018, 02:36:00 PM »

Try inverting the argument order, maybe I misread something.
Logged
Punished Rally

« May 16, 2018, 02:37:31 PM »

Tried it right after I posted but no dice unfortunately. Are we sure axis-angles and quaternions are the same thing lol? I always thought axis-angles were the relatively simple concept that you explained but quats were terrifying theoretical 4d math cones or something
Logged
irrel

« May 16, 2018, 03:18:40 PM »

Ok, so I did some more reading: apparently, quaternions are not the same as axis angle, but are very close.
Specifically, the unit quaternion (w, x, y, z) is equivalent to axis-angle (x, y, z, 2*cos-1(w)). In other words, we can pretty easily convert them to multiply them. However, they are not exactly equal, as the x, y, z part of the quaternion also has a factor of 2*sin-1(w) in it.

Here's some relatively simplified code that should do what you want. It'll be used exactly the same as the code I botched earlier.
Code:
function axisAngleToQuat(%rot)
{
%axis = getWords(%rot, 0, 2);
%angle = getWord(%rot, 3);

return mcos(%angle/2) SPC vectorScale(%axis, msin(%angle/2));
}

function quatToAxisAngle(%quat)
{
%axis = vectorNormalize(getWords(%quat, 1, 3));
%quatAngle = getWord(%quat, 0);

return %axis SPC 2*macos(%quatAngle);
}

function combineAxisAngleRotations(%rot1, %rot2)
{
%quat1 = axisAngleToQuat(%rot1);
%quat2 = axisAngleToQuat(%rot2);

%quatAngle1 = getWord(%quat1, 0);
%quatAngle2 = getWord(%quat2, 0);

%quatVector1 = getWords(%quat1, 1, 3);
%quatVector2 = getWords(%quat2, 1, 3);

%quatCombined = %quatAngle1 * %quatAngle2 - vectorDot(%quatVector1, %quatVector2) SPC vectorScale(%quatVector2, %quatAngle1) + vectorScale(%quatVector1, %quatAngle2) + vectorCross(%quatVector1, %quatVector2);

return quatToAxisAngle(%quatCombined);
}
Logged
Pages: [1] 2  


Login with username, password and session length

Powered by SMF 1.1.20 | SMF © 2013, Simple Machines
Page created in 0.031 seconds with 19 queries.