HI i am looking if there is a code in .net to create a polyline that always reshapes itself to keep a 90 degree angle.
That means in case we move the first point of polyline up, down, right or left the second point of polyline move automatically or stretch to keep the 90 degree angle for the polyline.
Because i am trying to make the polyline behave like Visio line when creating a diagram.
I tried a lot of coding and many researches but couldn't find any solution.
So appreciate any help in case there is a solution for this case.
Best Regards, jack
Hi, Jack
Here is a bad code example but I think
it would be get you started
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.Colors ''named Imports acApp = Autodesk.AutoCAD.ApplicationServices.Application Imports acGiTm = Autodesk.AutoCAD.GraphicsInterface.TransientManager Imports acGiTdm = Autodesk.AutoCAD.GraphicsInterface.TransientDrawingMode ''_____________________________________________________________________'' <CommandMethod("dop")> _ Sub drawOrthoPline() Dim db = HostApplicationServices.WorkingDatabase Dim doc = acApp.DocumentManager.MdiActiveDocument Dim ed = doc.Editor Dim pts As Point3dCollection = New Point3dCollection() Dim wcs As Matrix3d = ed.CurrentUserCoordinateSystem Dim var1 = acApp.GetSystemVariable("ORTHOMODE") acApp.SetSystemVariable("ORTHOMODE", 0) Using tr As Transaction = db.TransactionManager.StartTransaction() Try tr.TransactionManager.QueueForGraphicsFlush() Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) Dim pres As PromptPointResult Dim opts As PromptPointOptions = New PromptPointOptions("") opts.Message = vbLf & "Enter the start point of the line: " pres = ed.GetPoint(opts) Dim p1 As Point3d = pres.Value If pres.Status = PromptStatus.Cancel Then Exit Sub opts.UseBasePoint = True opts.BasePoint = p1 opts.UseDashedLine = True opts.Message = vbLf & "Enter the end point of the line: " pres = ed.GetPoint(opts) Dim p2 As Point3d = pres.Value If pres.Status = PromptStatus.Cancel Then Exit Sub Dim ln1 As Line = New Line() ln1.StartPoint = p1 ln1.EndPoint = p2 acGiTm.CurrentTransientManager.AddTransient(ln1, acGiTdm.Main, 128, New IntegerCollection()) SetUcsBy2Points(p1, p2) pts.Add(p1) pts.Add(p2) acApp.SetSystemVariable("ORTHOMODE", 0) doc.SendStringToExecute("<90 ", False, False, True) Dim nucs As Matrix3d = ed.CurrentUserCoordinateSystem opts.UseBasePoint = True opts.BasePoint = p2.TransformBy(nucs.Inverse) opts.UseDashedLine = True opts.Message = vbLf & "Enter the end point of the second line:" pres = ed.GetPoint(opts) Dim p3 As Point3d = pres.Value If pres.Status = PromptStatus.Cancel Then Exit Sub Dim ln2 As Line = New Line() ln1.StartPoint = p1 ln1.EndPoint = p3.TransformBy(nucs) pts.Add(p3.TransformBy(nucs)) acGiTm.CurrentTransientManager.AddTransient(ln2, acGiTdm.Main, 128, New IntegerCollection()) acGiTm.CurrentTransientManager.EraseTransient(ln1, New IntegerCollection()) MsgBox("Write the rest of code to continue to specify the points here") Dim poly As New Polyline Dim i As Integer = 0 For i = 0 To pts.Count - 1 poly.AddVertexAt(i, New Point2d(pts(i).X, pts(i).Y), 0, 0, 0) Next btr.AppendEntity(poly) tr.AddNewlyCreatedDBObject(poly, True) acGiTm.CurrentTransientManager.EraseTransient(ln2, New IntegerCollection()) poly.ColorIndex = 2 tr.Commit() Catch ex As Exception acApp.ShowAlertDialog(ex.Message & vbLf & ex.StackTrace) Finally ed.CurrentUserCoordinateSystem = wcs acApp.SetSystemVariable("ORTHOMODE", var1) End Try End Using End Sub
~'J~
HI halex,
thanks for the reply, but my problem is more complex because i need to keep the polyline reshaping on 90 degree after the polyline is drawn not before and when user move start point or stretch it up or down i need that the second point move automatically to form a 90 degree polyline. because by that user won't need to realign the polyline points to be othoganal and that will save too much time . and it will be targeted to create a schematic drawings.
Best regards, jack
Hi Jack, try another one, though not tested enough,
but I think you need to use custom polyline jig in this case
Public Function RadiansToDegrees(ByVal radians As Double) As Double Return (180 / Math.PI) * radians End Function <CommandMethod("ord")> _ Public Sub PickMultiplePoints() Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim db As Database = HostApplicationServices.WorkingDatabase Dim ed As Editor = doc.Editor Dim pts As Point3dCollection = New Point3dCollection() Dim osm As Int16 = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("osmode") Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("osmode", 0) Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("orthomode", 0) Try Using tr As Transaction = db.TransactionManager.StartTransaction() Dim btr As BlockTableRecord = TryCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord) Dim n As Integer = 0 Dim strang As String = "" Dim ang As Double = 0 Dim fstPnt As Point3d = ed.GetPoint(vbLf & "Pick first point: ").Value Dim plan As New Plane(fstPnt, Vector3d.ZAxis) pts.Add(fstPnt) While True Dim ppo As New PromptPointOptions(vbLf & "Pick Next Point (or hit ""Enter"" to Exit): ") ppo.AllowNone = True Dim ppr As PromptPointResult ppo.UseDashedLine = True ppo.UseBasePoint = True ppo.BasePoint = fstPnt ppr = ed.GetPoint(ppo) If (Not (ppr.Status = PromptStatus.OK)) Or (ppr.Status = PromptStatus.None) Then Exit While End If Dim endPnt As Point3d = ppr.Value pts.Add(endPnt) ed.DrawVector(fstPnt, endPnt, 1, True) If n = 0 Then ang = RadiansToDegrees((fstPnt - endPnt).AngleOnPlane(plan)) + 90 Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("orthomode", 1) strang = String.Format("<{0} ", ang) doc.SendStringToExecute(strang, False, False, True) Else ang = RadiansToDegrees((fstPnt - endPnt).AngleOnPlane(plan)) + 90 strang = String.Format("<{0} ", ang) doc.SendStringToExecute(strang, False, False, True) End If n += 1 fstPnt = endPnt tr.TransactionManager.QueueForGraphicsFlush() End While Dim poly As New Polyline Dim i As Integer = 0 For i = 0 To pts.Count - 1 poly.AddVertexAt(i, New Point2d(pts(i).X, pts(i).Y), 0, 0, 0) Next btr.AppendEntity(poly) tr.AddNewlyCreatedDBObject(poly, True) doc.TransactionManager.FlushGraphics() ed.Regen() tr.Commit() End Using Catch ex As System.Exception Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & ex.Message & vbLf + ex.StackTrace) Finally Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("orthomode", 0) Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("osmode", osm) End Try End Sub
~'J'~