LDraw.org Discussion Forums

Full Version: 3 decimals is not a lot of precision for rotation matrices
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
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
Ben Supnik Wrote: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
Code:
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
Pages: 1 2