## Calculate force and torque to interpolate between 2 mat4s

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

### Re: Calculate force and torque to interpolate between 2 mat4s

Using the ACos() code, I run into the problem of the object taking the longer route to reach the desired angle, at certain angles. Using the code I posted, here is the behavior. This is using a large dt value to make the rotation smoothed:

With a higher smoothing value, here you can see the body always takes the closest approach to reach the desired orientation:

I believe you, but I shouldn't have to write out a bunch of formulas on paper just to figure out how to rotate an object. I think that would be more useful as a basic command in the library. How many of your users even know what a quaternion is?

Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

Leadwerks wrote:How many of your users even know what a quaternion is?

This does make a good point, i personally don't know what a quarternion is in math-sense, all i know is it has 4 values, it fixes gimbal lock and sometimes it's useful, when it works i think of it as "magic" or something - i never study how underlyning formulas work as i'm not good with it, i was never that good with math and physics, i'm better at rendering graphics and making game logic..
Help improving the Newton Game Dynamics WIKI

JernejL

Posts: 1531
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

### Re: Calculate force and torque to interpolate between 2 mat4s

I have already make some test in 3d with quarternion and I have get problem with the gimbal look limitation.
I know it is possible to over pass this but I don't know how and I think it cost more too.
I never have success to make a continuous rotation with quarternion, I have all times back with matrix rotation.

http://www.euclideanspace.com/physics/k ... /index.htm
http://www.koders.com/cpp/fid38F83F165A ... %3Acompute
ReturnMatrix Omega(const Quaternion & q, const Quaternion & q_dot)
You search a nice physics solution, if you can read this message you're at the good place
OrionX3D Projects & Demos:

Dave Gravel

Posts: 725
Joined: Sat Apr 01, 2006 9:31 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

the thing is that the function In teh SDK is what to do what you need to do exatly what you want.

are you expectiong the diferent in rotation to be larger than 180 dregree?
the funtion tah you want is ginet tow 4 x 4 matrices calutale teh angule velocity the will rotate matrix one on ot matrix tow?
and you wan this value to be laregt that 180 gregree

Code: Select all
`void CalculateToOmegaFromMatrix (vector omegaOut, matrix A, marix B, float time){......}`

I will post the code in the FAQ tonight?
Julio Jerez
Moderator

Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: Calculate force and torque to interpolate between 2 mat4s

the thing is that the function In teh SDK is what to do what you need to do exatly what you want.

That is not completely true. I already demonstrated your code has an error, in that it sometimes chooses the longer route (>180 degrees) to rotate around. I did, however, find a fix that uses your ACos() recommendation. If the m_q0 ("w" for my quaternions) term is greater than zero, the other terms of the quaternion need to be flipped. Here is my final code:
Code: Select all
`   Method CalcAverageOmega:TVec3( QB:TQuat, dt:Double=1.0 )            Const REALLYSMALLNUMBER:Double=0.00001      Local dirMag:Double      Local dirMag2:Double      Local omegaMag:Double      Local dirMagInv:Double      Local dq:TQuat      Local omegaDir:TVec4      Local dq2:TQuat      Local scale:Float            dq=Inverse().Times(QB)            omegaDir=vec4(dq.x,dq.y,dq.z,dq.w)      dirMag2=omegaDir.dot(omegaDir);      If dirMag2<REALLYSMALLNUMBER*REALLYSMALLNUMBER Return vec3(0)      dirMagInv=1.0/Sqr(dirMag2)      omegaMag=2.0*ACos(dq.w)/dt      If omegaDir.w>0.0         omegaDir.x:*-1.0         omegaDir.y:*-1.0         omegaDir.z:*-1.0      EndIf      omegaDir.x=Degrees(omegaDir.x)      omegaDir.y=Degrees(omegaDir.y)      omegaDir.z=Degrees(omegaDir.z)      scale=Degrees(dirMagInv*omegaMag)      Return (omegaDir.xyz()).Scale(scale)   EndMethod`

Does that look right to you?

Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

I whish My english was good enought to explain.
My guess is that you are converting your matrices to quartenions and calling the funtion,
fliping the values based of heuritic or gusses will only hide the bug until it shows up somewhere else.
tell me if this is correct, are you dount this:

you start with two matrices; M0 and M1 and you are convertion then to quaternions,

q0 = Quat (m0)
q1 = Quat (m1)

the you are call the function

if that is correct then the problems is this
if q0 is the quaternion reprentation of matrix M0, then -q0 is also a represetaion of matrix0.
whith the Lema, it is possible the the above convertion give you

q0 = -Quat (m0)
q1 = Quat(m1)

and it will be arithmetically correct, but it will intepoiste in teh wornd diorection.
that is because dot product (q0, q1) will alway generates the shortest arch of rotation.
if whatI am saying is wjhat you are doing, then this is teh solution.
Code: Select all
`void GetOmega (vector omega, matrix  m0, matrix ma1, time dt){    q0 = quat (m0);    q1= quat(m1)        dot = dotpropduct (q0, q1)    if (dot < 0) {      q1 = q1 * -1;    }  GetOmega (omega, q0, q1, dt)}`

This will alway guarates the shortest arch of rotation from m0 to m1
Julio Jerez
Moderator

Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: Calculate force and torque to interpolate between 2 mat4s

Okay, I seem to be getting correct results with that:
Code: Select all
`   Method CalcAverageOmega:TVec3( QB:TQuat, dt:Double=1.0 )            Const REALLYSMALLNUMBER:Double=0.00001      Local dirMag:Double      Local dirMag2:Double      Local omegaMag:Double      Local dirMagInv:Double      Local dq:TQuat      Local omegaDir:TVec4      Local dq2:TQuat      Local scale:Float            If dot(QB)>0.0         QB.w:*-1.0         QB.x:*-1.0         QB.y:*-1.0         QB.z:*-1.0         Return CalcAverageOmega(QB,dt)      EndIf      dq=Inverse().Times(QB)            omegaDir=vec4(dq.x,dq.y,dq.z,dq.w)      dirMag2=omegaDir.dot(omegaDir);      If dirMag2<REALLYSMALLNUMBER*REALLYSMALLNUMBER Return vec3(0)      dirMagInv=1.0/Sqr(dirMag2)      omegaMag=2.0*ACos(dq.w)/dt      Return (omegaDir.xyz()).Scale(dirMagInv*omegaMag)   EndMethod`

Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

So I guess this is all correct now? Thanks. Hopefully this thread will make it easier for people who want to do this in the future.

Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

Hre is my test prog, just to get this off my desktop:
Code: Select all
`'   ===================================================================='   This file was generated by Leadwerks C++/LEO/BlitzMax Project Wizard'   Written by Rimfrost Software'   http://www.rimfrost.com '   ====================================================================SuperStrictFramework leadwerks.engineLocal world:TWorldLocal gbuffer:TBufferLocal camera:TCameraLocal mesh:TMeshLocal light:TLightLocal ground:TMeshLocal material:TMaterialRegisterAbstractPath( "C:/Program Files/Leadwerks Engine SDK" ) Graphics(800,600)world=CreateWorld()If Not world RuntimeError "Failed to create world."gbuffer=CreateBuffer(GraphicsWidth(),GraphicsHeight(),BUFFER_COLOR|BUFFER_DEPTH|BUFFER_NORMAL)camera=CreateCamera()PositionEntity camera,[0.0,0.0,-2.0]material=LoadMaterial("abstract::cobblestones.mat")mesh=CreateCube()PaintEntity mesh,materialground=CreateCube()ScaleEntity ground,[10.0,1.0,10.0]PositionEntity ground,[0.0,-2.0,0.0]PaintEntity ground,materialLocal gb:TBody=CreateBodyBox(10,1,10)PositionEntity gb,[0.0,-2.0,0.0]gb.setcollisiontype 1light=CreateDirectionalLight()Local body:TBody=CreateBodyBox()SetBodyMass body,1SetBodyGravityMode body,0body.setcollisiontype 1DebugPhysics TrueRotateEntity light,[45.0,45.0,45.0]SetBodyDamping body,0,0Function QuatToNewtonQuat:TQuat(q:TQuat)   Local result:TQuat=New TQuat   result.x=q.w   result.y=-q.x   result.z=-q.y   result.w=-q.z   Return resultEndFunctionFunction NewtonQuatToQuat:TQuat(q:TQuat)   Local result:TQuat=New TQuat   result.w=q.x   result.x=-q.y   result.y=-q.z   result.z=-q.w   Return resultEndFunction'RotateEntity body,[0.0,0.0,0.0]'RotateEntity mesh,[0.0,0.0,10.0]Global mx:Float=MouseX()collisions 1,1,1Repeat   'RotateEntity cube,[0.0,0.0,45.0]   'HideEntity cube      Local a#=MouseX()-mx      RotateEntity mesh,vec3(0,0,a)      'TurnEntity mesh,vec3(0.3,1.0,-0.5)      'If MouseHit(1)   '   Local b:TBody=CreateBodyBox(0.1,0.1,0.1)   '   b.setmass 1   '   b.setposition([0.0,4.0,0.0])   '   b.setcollisiontype 1   'EndIf         Local q:TQuat=New TQuat   Local q2:TQuat=New TQuat   Local omega:TVec3   Local mat:TMat4=New TMat4   omega=body.CalcOmega(mesh.rotation,1)   'If MouseHit(1)      body.setomega omega   'Else   '   body.setomega vec3(0)   'EndIf   If KeyHit(KEY_ESCAPE) Exit   If AppTerminate() Exit      UpdateAppTime()   UpdateWorld(1)'AppSpeed())   SetBuffer(gbuffer)   RenderWorld()   SetBuffer(BackBuffer())   RenderLights(gbuffer)      DrawText a,0,0      Flip(1)Forevergbuffer=NullFreeEntity lightGCCollect()End`

Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

is this a bug?
Julio Jerez
Moderator

Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: Calculate force and torque to interpolate between 2 mat4s

Julio Jerez wrote:is this a bug?

No, I believe he posted that as a working example for others who may want to do the same thing.
agi_shi

Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

### Re: Calculate force and torque to interpolate between 2 mat4s

Just some code I used for testing that I wanted to delete, but still have a copy of somewhere, just in case.