Re: 3 decimals is not a lot of precision for rotation matrices
 March 26, 2013 03:29PM James Jessiman Memorial Award Recipient Registered: 4 years agoPosts: 35
Quote
Ben Supnik
I think "fixing a rounded rotation" is getting way into the territory of a batch process we should consider running on the library, then fast-tracking if the mechanical transformation can be demonstrated and spot-tested to be good. :-)

What I like about pre-processing is that the code runs once and a human can inspect the results. Every bit of 'mesh repair' I put into BrickSmith is code whose results are somewhat hidden to the part author, and whose results (as data) can only be viewed by a programmer with source code and a debugger. It's an opaque process, so the less complicated that black box, the better.

(Or maybe I am just lazy and want to keep my end of the code simple. ;-)

cheers
ben

I Agree!
Furthermore, a lot of code (and time) is spent to fix parts definition problems.

Following a pair of useful (I hope) function to extract the rotation portion of a matrix:

Given the matrix M, you call GetMatrixScale to get scale factor Vs of M along x,y,z axis
vs=GetMatrixScale(M)

then you call the M=PurifyMatrix(M,Vs,vt) to get back M as a pure rotation matrix. The VT parameter is a vector containing original M translation values

Finally you can get the rotation angles along each 3 axles that M was built by:
vRot=GetMatrixRot(M)
vRot is a x,y,z vector containing a value representing the rotation around the specific axle that built M

To recreate M you can multiply the 3 matrix resulting by creating a rotation matrix around any of the 3axles by the amount o vRot:
xM=matrix.rotationaxleX(vrot.x)
yM=matrix.rotationaxleY(vrot.y)
zM=matrix.rotationaxleZ(vrot.z)
M= xM x yM x zM

Hope this could useful for someone...

Sergio

About the code: it is for DirectX matrix notation. For openGL standard you may need to transpose matrix values
```Function GetMatrixScale(ByRef M As Matrix) As Vector3
Dim V As Vector3
With M
V = Vec3(CSng(Math.Sqrt(.M11 * .M11 + .M12 * .M12 + .M13 * .M13)), CSng(Math.Sqrt(.M21 * .M21 + .M22 * .M22 + .M23 * .M23)), CSng(Math.Sqrt(.M31 * .M31 + .M32 * .M32 + .M33 * .M33)))
V.Y = V.Y * Math.Sign(.M21 + .M22 + .M23)
Return RoundV(V)
End With
End Function

Function PurifyMatrix(ByVal M As Matrix, ByRef vS As Vector3, ByRef vT As Vector3) As Matrix
With M
.M11 /= vS.X : .M12 /= vS.X : .M13 /= vS.X
.M21 /= vS.Y : .M22 /= vS.Y : .M23 /= vS.Y
.M31 /= vS.Z : .M32 /= vS.Z : .M33 /= vS.Z

vT = Vec3(.M41, .M42, .M43)
.M41 = 0 : .M42 = 0 : .M43 = 0
End With

Return M
End Function

Function GetMatrixRot(ByVal M As Matrix) As Vector3
Dim vRot As Vector3
With vRot
If Abs(M.M13) > 1 Then M.M13 = Sign(M.M13)
.Y = CSng(Math.Asin(M.M13))
If Math.Sin(.Y) > 0.99999 Or Math.Sin(.Y) < -0.99999 Then
.X = 0
.Z = -CSng(Math.Atan2(M.M21, M.M22))
Else
.X = CSng(Math.Atan2(M.M23, M.M33))
.Z = CSng(Math.Atan2(M.M12, M.M11))
End If
End With
Return vRot
End Function
```
SubjectAuthorViewsPosted
Ben Supnik1162March 23, 2013 12:48PM
Roland Melkert335March 23, 2013 02:27PM
Philippe Hurbain369March 23, 2013 04:02PM
Tim Gould410March 23, 2013 04:14PM
Ben Supnik387March 23, 2013 07:29PM
Tim Gould359March 24, 2013 12:06AM
Ben Supnik290March 24, 2013 08:46AM
Tim Gould436March 24, 2013 02:13PM
Roland Melkert351March 24, 2013 02:24PM
Tim Gould362March 24, 2013 02:33PM
Ben Supnik470March 24, 2013 07:44PM
Sergio Reano552March 26, 2013 03:29PM

Sorry, only registered users may post in this forum.