AutoCAD’s ActiveX API (VBA) does not come with the full complement of matrix manipulation functionality. That’s one of the benefits of switching to one of the .NET languages – C# or VB.NET.
Painstakingly, though, the functions can be reproduced for VBA. The attached routine has one – the Inverse Matrix function. That allows me to copy an object from a UCS to the WCS. The object can then be reoriented to another UCS. Additional matrix’s arithmetic function could allow moves from one UCS directly to another.
The Code below was used for the linked screencast. See the attached file and examine the Named UCSs.
https://autode.sk/3bhRCo2
Sub CopySolidToUCS()
Dim entEnt As AcadEntity
Dim entCopy As AcadEntity
Dim varPkPt As Variant
Dim dblUCSMatrix() As Double
Dim dblInvMatrix() As Double
Dim strWorkingUcsName As String
Dim FromUCS As AcadUCS
Dim ToUCS As AcadUCS
With ThisDrawing
On Error Resume Next
.Utility.GetEntity entEnt, varPkPt, "Select an Entity: "
If Err <> 0 Then Exit Sub
strWorkingUcsName = .Utility.GetString(0, "Input ""From"" UCS name: ")
Set FromUCS = .UserCoordinateSystems.Item(strWorkingUcsName)
If Err <> 0 Then
.Utility.Prompt ("UCS of that name could not be found: Terminating Sub!" & vbLf)
On Error GoTo 0
Exit Sub
End If
Set entCopy = entEnt.Copy()
entCopy.Visible = False
dblUCSMatrix = FromUCS.GetUCSMatrix()
dblInvMatrix = InverseMatrix(dblUCSMatrix)
entCopy.TransformBy dblInvMatrix
strWorkingUcsName = .Utility.GetString(0, "Input ""To"" UCS name: ")
Set ToUCS = .UserCoordinateSystems.Item(strWorkingUcsName)
If Err <> 0 Then
.Utility.Prompt ("UCS of that name could not be found: Terminating Sub!" & vbLf)
entCopy.Delete
On Error GoTo 0
Exit Sub
End If
entCopy.TransformBy ToUCS.GetUCSMatrix()
entCopy.Visible = True
On Error GoTo 0
End With
End Sub
Function InverseMatrix(m() As Double) As Double()
Dim dblDeterm As Double
Dim dblInvMat(3, 3) As Double
dblDeterm = (m(0, 0) * ((m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(1, 2) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))))) + (-m(0, 1) * ((m(1, 0) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(1, 3) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))))) + (m(0, 2) * ((m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (-m(1, 1) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))))) + (-m(0, 3) * ((m(1, 0) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))) + (-m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))) + (m(1, 2) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)))))
If dblDeterm = 0 Then Exit Function 'Some error checking required
dblDeterm = 1 / dblDeterm
dblInvMat(0, 0) = dblDeterm * ((m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(1, 2) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))))
dblInvMat(0, 1) = dblDeterm * -((m(0, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(0, 2) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (m(0, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))))
dblInvMat(0, 2) = dblDeterm * ((m(0, 1) * (m(1, 2) * m(3, 3) - m(1, 3) * m(3, 2))) + (-m(0, 2) * (m(1, 1) * m(3, 3) - m(1, 3) * m(3, 1))) + (m(0, 3) * (m(1, 1) * m(3, 2) - m(1, 2) * m(3, 1))))
dblInvMat(0, 3) = dblDeterm * -((m(0, 1) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2))) + (-m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1))) + (m(0, 3) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1))))
dblInvMat(1, 0) = dblDeterm * -((m(1, 0) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(1, 3) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))))
dblInvMat(1, 1) = dblDeterm * ((m(0, 0) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2))) + (-m(0, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(0, 3) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))))
dblInvMat(1, 2) = dblDeterm * -((m(0, 0) * (m(1, 2) * m(3, 3) - m(1, 3) * m(3, 2))) + (-m(0, 2) * (m(1, 0) * m(3, 3) - m(1, 3) * m(3, 0))) + (m(0, 3) * (m(1, 0) * m(3, 2) - m(1, 2) * m(3, 0))))
dblInvMat(1, 3) = dblDeterm * ((m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2))) + (-m(0, 2) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0))) + (m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0))))
dblInvMat(2, 0) = dblDeterm * ((m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (-m(1, 1) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))))
dblInvMat(2, 1) = dblDeterm * -((m(0, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1))) + (-m(0, 1) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0))) + (m(0, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))))
dblInvMat(2, 2) = dblDeterm * ((m(0, 0) * (m(1, 1) * m(3, 3) - m(1, 3) * m(3, 1))) + (-m(0, 1) * (m(1, 0) * m(3, 3) - m(1, 3) * m(3, 0))) + (m(0, 3) * (m(1, 0) * m(3, 1) - m(1, 1) * m(3, 0))))
dblInvMat(2, 3) = dblDeterm * -((m(0, 0) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1))) + (-m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0))) + (m(0, 3) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))))
dblInvMat(3, 0) = dblDeterm * -((m(1, 0) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))) + (-m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))) + (m(1, 2) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))))
dblInvMat(3, 1) = dblDeterm * ((m(0, 0) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))) + (-m(0, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0))) + (m(0, 2) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))))
dblInvMat(3, 2) = dblDeterm * -((m(0, 0) * (m(1, 1) * m(3, 2) - m(1, 2) * m(3, 1))) + (-m(0, 1) * (m(1, 0) * m(3, 2) - m(1, 2) * m(3, 0))) + (m(0, 2) * (m(1, 0) * m(3, 1) - m(1, 1) * m(3, 0))))
dblInvMat(3, 3) = dblDeterm * ((m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1))) + (-m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0))) + (m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))))
InverseMatrix = dblInvMat
End Function
************************************************************
May your cursor always snap to the location intended.