
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi all,
I am not ashamed to admit this is well outside my understanding and am begging for help...
We draw polylines in model space and some users rotate their UCS (for viewport purposes) and all of a sudden, the polyline no longer consists of linesegments and the pick point becomes the endpoint of the polyline. I have found some code that has helped me sort of understand, but although the line works rotating correctly, it still goes to the end of the line.
Is there anyone here who can help me (not necessarily by giving me the answer) with the following things:
1. Why when the ucs is rotated around the Z axis, does the pick point not work and
2. Why does the polyline suddenly not consist of the same line segments it did when the ucs is not rotated?
My code is below (feel free to criticise):
Public Sub GetRot(ByVal sHType As String) Dim oid As ObjectId Dim iRot As Double Dim pickPt As Point3d Dim sp As Point2d Dim ep As Point2d Dim fine As Boolean = True Dim isBlk As Boolean = False Dim locked As New ObjectIdCollection() Dim acLine As New Line Dim pKeyOpts As PromptKeywordOptions = New PromptKeywordOptions("") pKeyOpts.Message = vbLf & "Up (U) or Down (D) ? " pKeyOpts.Keywords.Add("U") pKeyOpts.Keywords.Add("D") pKeyOpts.Keywords.Default = "U" pKeyOpts.AllowNone = False Dim pKO2 As PromptKeywordOptions = New PromptKeywordOptions("") pKO2.Message = vbLf & "Invert (Y/N) ? " pKO2.Keywords.Add("Y") pKO2.Keywords.Add("N") pKO2.Keywords.Default = "N" pKO2.AllowNone = False Using doc.LockDocument() Dim pno As PromptNestedEntityOptions = New PromptNestedEntityOptions("" & vbLf & "Select Line ") Dim nres As PromptNestedEntityResult = ed.GetNestedEntity(pno) If (nres.Status <> PromptStatus.OK) Then ed.WriteMessage("" & vbLf & "Selection failed") Return End If Using tr As Transaction = db.TransactionManager.StartTransaction() ' try to unlock layers Dim lt As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable) For Each ltId As ObjectId In lt If ltId.IsValid AndAlso ltId.IsResident AndAlso Not ltId.IsErased Then Dim ltr As LayerTableRecord = DirectCast(tr.GetObject(ltId, OpenMode.ForRead), LayerTableRecord) If ltr.IsLocked Then locked.Add(ltId) ltr.UpgradeOpen() ltr.IsLocked = False End If End If Next oid = nres.ObjectId oEntHook = CType(tr.GetObject(oid, OpenMode.ForWrite), Entity) Dim ctnIds() As ObjectId = nres.GetContainers() If Not ctnIds.Length = 0 Then If Not UCase(oEntHook.BlockName).Equals("*MODEL_SPACE") Then Dim br As BlockReference = DirectCast(tr.GetObject(ctnIds(0), OpenMode.ForRead), BlockReference) iRot = br.Rotation isBlk = True End If End If Try Dim UCS As CoordinateSystem3d = ed.CurrentUserCoordinateSystem.CoordinateSystem3d Dim OcsPlane As Plane = New Plane(Point3d.Origin, UCS.Zaxis) Dim OCS As CoordinateSystem3d = Matrix3d.PlaneToWorld(OcsPlane).CoordinateSystem3d Dim ucsRotation As Double = OCS.Xaxis.GetAngleTo(UCS.Xaxis) Dim vec1 As Vector3d Dim aa As Double Select Case isBlk Case False Select Case True Case TypeOf oEntHook Is Line Dim oLine As Line = DirectCast(tr.GetObject(oEntHook.ObjectId, OpenMode.ForRead), Line) pickPt = oLine.GetClosestPointTo(nres.PickedPoint, False) vec1 = oLine.StartPoint.GetVectorTo(oLine.EndPoint) aa = vec1.AngleOnPlane(OcsPlane) ed.WriteMessage(vbLf & "Aa IS " & aa.ToString) iRot = aa Case TypeOf oEntHook Is Polyline Dim pline As Polyline = DirectCast(tr.GetObject(oEntHook.ObjectId, OpenMode.ForRead, False), Polyline) If pline IsNot Nothing Then pickPt = pline.GetClosestPointTo(nres.PickedPoint, False) Dim param As Double = pline.GetParameterAtPoint(pickPt) Dim index As Integer = CInt(Math.Truncate(param)) Dim stype As SegmentType = pline.GetSegmentType(index) ed.WriteMessage(stype.ToString) If stype = SegmentType.Line Then Dim lineseg As LineSegment2d = pline.GetLineSegment2dAt(index) ed.WriteMessage(vbLf & index) sp = lineseg.StartPoint ep = lineseg.EndPoint acLine = New Line(New Point3d(sp.X, sp.Y, 0), New Point3d(ep.X, ep.Y, 0)) 'iRot = acLine.Angle vec1 = acLine.StartPoint.GetVectorTo(acLine.EndPoint) aa = vec1.AngleOnPlane(OcsPlane) iRot = aa Else ed.WriteMessage("Why is it suddenly no longer a lineseg???") End If End If End Select ed.WriteMessage(vbLf & "PP = {0}", pickPt.ToString) If iRot > funcGetRads(180) Then iRot -= funcGetRads(180) ElseIf iRot = 0 Then '' I need a function to ask whether it is up or down on a zero line Dim pKeyRes As PromptResult = ed.GetKeywords(pKeyOpts) Select Case UCase(pKeyRes.StringResult) Case "U" Select Case sHType Case "R" : iRot += funcGetRads(180) End Select Case "D" Select Case sHType Case "L" : iRot += funcGetRads(180) End Select End Select ElseIf iRot = funcGetRads(180) Then Dim pKeyRes As PromptResult = ed.GetKeywords(pKeyOpts) Select Case UCase(pKeyRes.StringResult) Case "U" Select Case sHType Case "L" : iRot -= funcGetRads(180) End Select Case "D" Select Case sHType Case "R" : iRot -= funcGetRads(180) End Select End Select End If End Select iRot -= funcGetRads(90) 'End Select ed.WriteMessage(vbLf & "LINE ANGLE IS " & funcGetDegrees(iRot).ToString) Catch ex As System.Exception ed.WriteMessage(vbLf & "Error: {0}" & vbLf & "Trace: {1}", ex.Message, ex.StackTrace) Finally For Each ltId As ObjectId In locked Dim ltr As LayerTableRecord = DirectCast(tr.GetObject(ltId, OpenMode.ForWrite), LayerTableRecord) ltr.IsLocked = True Next tr.Commit() End Try End Using End Using dHRot = iRot ptH3d = pickPt Return End Sub
I am failing to wrap my head around why the rotation of the ucs affects these entities the way it is. What am I doing wrong here? The program works perfectly if the ucs is not rotated.
Thank you all in advance.
Solved! Go to Solution.