- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm attempting to align an entity (BlockReference or 3D Polyline) in 3D. I'm not having much luck finding sample code that works.
I've tried this post: https://adndevblog.typepad.com/autocad/2012/04/finding-transformation-matrix-for-aligning-two-entiti...
It's been linked to in other posts in this forum, but it doesn't appear to work correctly as shown in this screencast: https://autode.sk/2y4D51k
Here is the drawing information to recreate the linework, I've also attached the drawing.
3DPoly 652492.7740,367502.1323,2867.9053 652534.3375,367499.4847,2862.0912
point 652492.7740,367502.1323,2867.9053
point 652534.7389,367499.4590,2867.5313
Below is the code I've been testing with, with the trans4 corrected for what I think is a typo.
If I run the code multiple times it converges to a more correct solution, but I don't think that should be required.
<CommandMethod("S-Test")>
Sub Test()
Try
'' Put your command code here
'Using tr As Transaction = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction
' Dim pipe3dAlign As New Pipe3DAlign
' pipe3dAlign.RunCommandTest(tr)
' tr.Commit()
'End Using
Dim activeDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = activeDoc.Database
Dim ed As Editor = activeDoc.Editor
Dim per As PromptEntityResult = ed.GetEntity(New PromptEntityOptions("Select an entity : "))
If (per.Status <> PromptStatus.OK) Then
Return
End If
Dim oid As ObjectId = per.ObjectId
Dim ppr1 As PromptPointResult = ed.GetPoint(New PromptPointOptions("Select src point 1"))
If (ppr1.Status <> PromptStatus.OK) Then
Return
End If
Dim sp1 As Point3d = ppr1.Value
Dim ppr2 As PromptPointResult = ed.GetPoint(New PromptPointOptions("Select src point 2"))
If (ppr2.Status <> PromptStatus.OK) Then
Return
End If
Dim ep1 As Point3d = ppr2.Value
Dim ppr3 As PromptPointResult = ed.GetPoint(New PromptPointOptions("Select dest point 1"))
If (ppr3.Status <> PromptStatus.OK) Then
Return
End If
Dim sp2 As Point3d = ppr3.Value
Dim ppr4 As PromptPointResult = ed.GetPoint(New PromptPointOptions("Select dest point 2"))
If (ppr4.Status <> PromptStatus.OK) Then
Return
End If
Dim ep2 As Point3d = ppr4.Value
Dim resMat As Matrix3d = Matrix3d.Identity
Dim trans1 As Matrix3d = Matrix3d.Displacement(sp2 - sp1)
sp1 = sp1.TransformBy(trans1)
ep1 = ep1.TransformBy(trans1)
resMat = resMat.PreMultiplyBy(trans1)
' // Rotation about Z axis
Dim dir1 As Vector3d = ep1 - sp1
Dim dir2 As Vector3d = ep2 - sp2
Dim xy As Plane = New Plane(Point3d.Origin, Vector3d.ZAxis)
Dim trans2 As Matrix3d = Matrix3d.Rotation(dir2.AngleOnPlane(xy) - dir1.AngleOnPlane(xy), Vector3d.ZAxis, sp1)
sp1 = sp1.TransformBy(trans2)
ep1 = ep1.TransformBy(trans2)
resMat = resMat.PreMultiplyBy(trans2)
' // Rotation about X axis
dir1 = ep1 - sp1
dir2 = ep2 - sp2
Dim yz As Plane = New Plane(Point3d.Origin, Vector3d.XAxis)
Dim trans3 As Matrix3d = Matrix3d.Rotation(dir2.AngleOnPlane(yz) - dir1.AngleOnPlane(yz), Vector3d.XAxis, sp1)
sp1 = sp1.TransformBy(trans3)
ep1 = ep1.TransformBy(trans3)
resMat = resMat.PreMultiplyBy(trans3)
'// Rotation about Y axis
dir1 = ep1 - sp1
dir2 = ep2 - sp2
Dim xz As Plane = New Plane(Point3d.Origin, Vector3d.YAxis)
Dim trans4 As Matrix3d = Matrix3d.Rotation(dir2.AngleOnPlane(xz) - dir1.AngleOnPlane(xz), Vector3d.YAxis, sp1)
sp1 = sp1.TransformBy(trans4)
ep1 = ep1.TransformBy(trans4)
resMat = resMat.PreMultiplyBy(trans4)
'// Scaling
dir1 = ep1 - sp1
dir2 = ep2 - sp2
Dim trans5 As Matrix3d = Matrix3d.Scaling(dir2.Length / dir1.Length, sp1)
sp1 = sp1.TransformBy(trans5)
ep1 = ep1.TransformBy(trans5)
resMat = resMat.PreMultiplyBy(trans5)
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim ent As Entity = tr.GetObject(oid, OpenMode.ForWrite)
ent.TransformBy(resMat)
tr.Commit()
End Using
Catch EX As System.Exception
MsgBox("Error: " & EX.Message)
End Try
End Sub
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/

Solved! Go to Solution.