Hi Charles,
Inventor Matrix is not too bad even if not complete as ARX AcGe...
Every time you need a new matrix you need to ask Inventor to provide a new
one:
Public Function NewMatrix()
Set NewMatrix = oApp.TransientGeometry.CreateMatrix
End Function
To access lines and row use Cell method...
Dim oBackSys As Matrix, r As Long, c As Long
Set oBackSys = NewMatrix()
For r = 1 To 4
For c = 1 To 4
oBackSys.Cell(r, c) = oSys.Cell(r, c)
Next
Next
Into the matrix you can store all information about position, rotation, ecc.
I just noticed Autodesk guys tend to use matrices to store data in a compact
way (as array of vectors).
You can find some geom info here
http://www.jtaylor1142001.net/calcjat/CFrames/Index00.htm
Just one thing is a bit tricky... extracting rotation angle from a 3D
matrix. This is an example using quaternions (not really tested onestly!!).
Public Function PI() As Double
PI = Atn(1) * 4
End Function
Public Function Equal(ByVal val1 As Double, ByVal val2 As Double, Optional
ByVal tol As Double = 0.00001)
Equal = Abs(val1 - val2) < tol
End Function
Function Acos(x As Double) As Double
' Inverse Cosine
If Equal(x, 1) Then
Acos = 0
ElseIf Equal(x, -1) Then
Acos = PI()
'Acos = -PI()
Else
Acos = (PI() / 2#) - Atn(x / Sqr(1# - (x * x)))
'Acos = Atn(x / Sqr(-x * x + 1)) + PI() / 2
End If
End Function
Public Function GetMatrixRotationAngle(oMat As Matrix, oAxis As Vector) As
Double
' Be sure the matrix has no scale, mirror or shear...
If Not Equal(oMat.Determinant, 1#) Then
MsgBox "Unable to get piece rotation angle"
GetMatrixRotationAngle = 0#
Exit Function
End If
Dim i As Long
For i = 1 To 3
If Equal(oMat.Cell(i, i), 0#) Then
oMat.Cell(i, i) = 0#
End If
Next
Dim M11 As Double, M22 As Double, M33 As Double
M11 = oMat.Cell(1, 1)
M22 = oMat.Cell(2, 2)
M33 = oMat.Cell(3, 3)
Dim trace As Double
trace = M11 + M22 + M33
Dim s As Double
Dim quat(4) As Double
If trace > 0# Then
s = Sqr(trace + 1#)
quat(0) = s * 0.5
s = 0.5 / s
quat(1) = s * (oMat.Cell(3, 2) - oMat.Cell(2, 3))
quat(2) = s * (oMat.Cell(1, 3) - oMat.Cell(3, 1))
quat(3) = s * (oMat.Cell(2, 1) - oMat.Cell(1, 2))
Else
' find which column has the greater value
Dim j As Long, k As Long
i = 0
If M22 > M11 Then
i = 1
End If
If M33 > oMat.Cell(i + 1, i + 1) Then
i = 2
End If
j = (i + 1) Mod 3
k = (i + 2) Mod 3
s = Sqr(oMat.Cell(i + 1, i + 1) - (oMat.Cell(j + 1, j + 1) +
oMat.Cell(k + 1, k + 1)) + 1#)
quat(i + 1) = s * 0.5
s = 0.5 / s
quat(0) = s * (oMat.Cell(k + 1, j + 1) - oMat.Cell(j + 1, k + 1))
quat(j + 1) = s * (oMat.Cell(j + 1, i + 1) + oMat.Cell(i + 1, j + 1))
quat(k + 1) = s * (oMat.Cell(k + 1, i + 1) + oMat.Cell(i + 1, k + 1))
End If
' Extract the rotation angle
Dim theta As Double
theta = 2# * Acos(quat(0))
If Not Equal(theta, 0#) Then
Dim factor As Double
factor = 1# / Sin(theta * 0.5)
Dim oTmpAxis As Vector
Set oTmpAxis = NewVector(quat(1) * factor, quat(2) * factor, quat(3)
* factor)
'Flip direction if necessary
Dim dotp As Double
dotp = oTmpAxis.DotProduct(oAxis)
If dotp < 0# Then
Call oTmpAxis.ScaleBy(-1#)
theta = PI() * 2# - theta
End If
Else
theta = 0#
End If
GetMatrixRotationAngle = theta
End Function
Hope this helps,
Daniele Piazza
AutoCAD-ME10 Translator Customers Support
QS Informatica
"Charles Bliss" ha scritto nel messaggio
news:3D8FF8FE.9090604@cbliss.com...
> Still a bit foggy on the concept
> Position:
> X=.TransMat.Cell(1,4)
> Y=.TransMat.Cell(2,4)
> Z=.TransMat.Cell(3,4)
> So for Rotation, I would need?
> aX=.TransMat.Cell(1,1)
> bX=.TransMat.Cell(1,2)
> cX=.TransMat.Cell(1,3)
>
> aY=.TransMat.Cell(2,1)
> bY=.TransMat.Cell(2,2)
> cY=.TransMat.Cell(2,3)
>
> aZ=.TransMat.Cell(3,1)
> bZ=.TransMat.Cell(3,2)
> cZ=.TransMat.Cell(3,3)
> Or a total of 12 Numbers?
>
> What would I collect and how would I derive from 6?
>
> What threw me was that there are only Length, X, Y & Z showing in the
> Matrix which is shown in the Watch Window. When I use GetMatrixData, it
> is an array of 16 numbers. What are the extra 4 for? Is there anything
> I can read somewhere which explains this?
>
>
> Brian Ekins wrote:
> > Charles,
> >
> > You're assuming a very limited case in the occurrence and you actually
only
> > need three numbers for this. The assumption you're making is that the
> > occurrence does not have any rotation, it is placed so that the parts
> > coordinate systems and the assemblies are completely aligned. The only
> > thing you're defining is the position of the part within the assembly.
If
> > that's all you need then the X, Y, and Z values are enough. If you need
to
> > account for rotation then you could get by with storing an additional
six
> > numbers. (You really need 9, but the other can be derived from these
6.)
> >
> > The last column of the matrix defines the translation. You can extract
the
> > translation using the following:
> >
> > excelSheet.Cells(rownum, colnum).Value = .TransMat.Cell(1,4)
> > excelSheet.Cells(rownum, colnum).Value = .TransMat.Cell(2,4)
> > excelSheet.Cells(rownum, colnum).Value = .TransMat.Cell(3,4)
> >
> > To use these numbers later, create a new matrix using the CreateMatrix
> > method and then using the Cell property of the Matrix object assign the
> > values you saved back into the matrix. This matrix can then be used to
> > place a new occurrence or modify an existing one.
> >
> > The rotation information is stored in columns 1, 2, and 3.
> >
> > -Brian
> >
> >
> > "Charles Bliss" wrote in message
> > news:3D8EC268.2070709@cbliss.com...
> >
> >>I am trying to figure out how to take the numbers in the Transformation
> >>Matrix which is in an occurrence and use the numbers in it to create a
> >>new transformation matrix.
> >>
> >>This is easy enough to do if you can store the matrix itself but I am
> >>trying to store just the four numbers, Length, X, Y and Z then at a
> >>later date, convert these for use in placing a new component in a new
> >>assembly.
> >>
> >>pseudo code to get the matrix:
> >>Set .TransMat = IVoccur.Transformation
> >>
> >>Will get the transformation, I next write it out to an Excel Spread
> >>Sheet with:
> >>
> >>excelSheet.Cells(rownum, colnum).Value = .TransMat.Translation.Length
> >>excelSheet.Cells(rownum, colnum).Value = .TransMat.Translation.X
> >>excelSheet.Cells(rownum, colnum).Value = .TransMat.Translation.Y
> >>excelSheet.Cells(rownum, colnum).Value = .TransMat.Translation.Z
> >>
> >>Now I want to take the data from the Excel Spread sheet and convert it
> >>back into a Transformation Matrix so I can use it to place a part:
> >>
> >>oAsmCompDef.Occurrences.Add("C:\Temp\Part1.ipt", oMatrix)
> >>
> >>Where oMatrix is what I want to define from the Spread Sheet data
> >>
> >>It would be useful if there was a little more information in help on
> >>this subject. I suppose the other option would be to get all the data
> >>from GetMatrixData and use PutMatrixData
> >>
> >>Anyone know how to do this?
> >>CBliss
> >>
> >
> >
> >
>