cumlitive TwistAngle problem

cumlitive TwistAngle problem

Anonymous
Not applicable
2,738 Views
12 Replies
Message 1 of 13

cumlitive TwistAngle problem

Anonymous
Not applicable

I have some code that gets the twistangle from the currentviewport. It's a basic rectangle viewport. All 2d stuff in model space nothing fancy.

 

 There is a North arrow in the drawing in paper space. The code I've written checks the North arrow rotation to the viewport rotation to ensure they match.

 

It all works great except for when a user rotates the viewport multiple times. Then the twistangle goes out of wack. It's like it's accumulating the angles and not resetting. I have seen twistangle values past 900 degrees!

 

VPROTATEASSOC = 1 

 

 

Any idea why this is happening?

0 Likes
Accepted solutions (1)
2,739 Views
12 Replies
Replies (12)
Message 2 of 13

Balaji_Ram
Alumni
Alumni

Hello,

 

I have seen this behavior before and I do not think the Viewport TwistAngle requires that its angle is between 0 and 360.

 

It should be possible to bring it to that range if you desire.

 

if (vp.TwistAngle > 2 * Math.PI)
{
     vp.TwistAngle = Math.Atan2(Math.Sin(vp.TwistAngle), Math.Cos(vp.TwistAngle));
}

 

Regards,

Balaji

 



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 3 of 13

Anonymous
Not applicable

Thanks Balayi for the suggestion. 

 

I'm still not getting the correct value returned from TwistAngle.  Here is a little more detail on what I am doing.

The goal of my routine is to verify that the North arrow in my drawing in paper space is rotated to the same angle as my viewport.

 

The North Arrow block points North when it has a 0 degree rotation. 

 

If I grab both the North Arrow and my viewport and rotate them together. The first time I get perfect results,

 

North Block Rotation : 324.184244255124
ViewportTwist: 324.184244255124

 

Then I rotate agan and get the following;

 

North Block Rotation : 293.240839748065
ViewportTwist: 66.7591602519352

 

In the above example the if statement you suggest does not get initiated.

 

Is there something wrong with my logic that I can't use the ViewportTwist in this way? I don't understand where it is coming up with the 66.7591602519352.

 

any help would be greatly appreciated.

Coralie

0 Likes
Message 4 of 13

Balaji_Ram
Alumni
Alumni

Sorry, I will need a sample project and the drawing to reproduce the behavior at my end.

 

Please do not share any information that you consider confidential.

 

Thanks

 

Balaji

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 5 of 13

Anonymous
Not applicable

Sorry it has taken me a long time to reply. Here is the code I'm running, and a sample drawing with the block and viewport.

 

' check north arrow
Dim myDWG As Document = DocumentManager.MdiActiveDocument
Dim database As Database = HostApplicationServices.WorkingDatabase
Dim ed As Editor = myDWG.Editor
Dim BlockRotAng As Double = 0.0 ' rotation angle of North Arrow Block
Dim UCSAngleDeg As Double = 0.0 ' UCS angle
Dim NORTHCALC As Double = 0.0
Dim vptwistInDegrees As Double = 0.0 ' viewport twist in degrees (WCS)

Using myTrans As Transaction = myDWG.TransactionManager.StartTransaction

Dim NORTHID As ObjectId = FindBlock("ntharrow")
Dim PRJNorth As Boolean = FindTxt("PROJECT NORTH")
If NORTHID.IsNull = False Then
If PRJNorth = False Then
Dim NorthBlkRef As BlockReference = NORTHID.GetObject(OpenMode.ForRead)
BlockRotAng = NorthBlkRef.Rotation
' converting Radian to degree
BlockRotAng = BlockRotAng * (180 / Math.PI)

Dim symTable As SymbolTable = CType(myTrans.GetObject(database.ViewportTableId, OpenMode.ForRead), SymbolTable)
Dim vpcount As Integer = 0

For Each id As ObjectId In symTable

Dim symbol As ViewportTableRecord = CType(myTrans.GetObject(id, OpenMode.ForRead), ViewportTableRecord)

Dim acadDoc As AcadDocument = Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(myDWG)
acadDoc.MSpace = True

Dim CVport As Viewport = DirectCast(myTrans.GetObject(myDWG.Editor.CurrentViewportObjectId, OpenMode.ForRead), Viewport)

If (CVport.TwistAngle > 2 * Math.PI) Then
CVport.UpgradeOpen()
CVport.TwistAngle = Math.Atan2(Math.Sin(CVport.TwistAngle), Math.Cos(CVport.TwistAngle))
End If

Dim vptwistInRadians As Double = CVport.TwistAngle
vptwistInDegrees = Math.Abs((vptwistInRadians * (180 / Math.PI)))


NORTHCALC = BlockRotAng

ed.WriteMessage([String].Format(vbLf & "North Block Rotation : {0}", NORTHCALC.ToString))
ed.WriteMessage([String].Format(vbLf & "ViewportTwist: {0}", vptwistInDegrees.ToString))

myTrans.Commit()

acadDoc.MSpace = False
vpcount = vpcount + 1
Next

If NORTHCALC = 360 Then
NORTHCALC = 0
End If

If vptwistInDegrees = 360 Then
vptwistInDegrees = 0
End If

If vpcount = 1 And UCSAngleDeg > 0 Then
If (NORTHCALC - UCSAngleDeg) > 1 Or (UCSAngleDeg - NORTHCALC) > 1 Then
MsgBox("Check the angle of the North Arrow", , "NORTH ARROW ROTATION")
End If
End If
If vpcount = 1 And UCSAngleDeg = 0 Then
If (NORTHCALC - vptwistInDegrees) > 1 Or (vptwistInDegrees - NORTHCALC) > 1 Then
MsgBox("Check the angle of the North Arrow", , "NORTH ARROW ROTATION")
End If
End If
End If
End If
End Using

 

 

0 Likes
Message 6 of 13

Balaji_Ram
Alumni
Alumni

Hi,

 

Sorry, I could not reproduce the problem.

 

Here is a recording of what i am trying using AutoCAD 2015.

In the recording you can also find two other methods - one to set the viewport twist and the other to print the viewport twist value

http://autode.sk/1zLGM6w

 

Please let me know if there is any additional step to reproduce the behavior.

 

Regards,

Balaji

 



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 7 of 13

Anonymous
Not applicable

Thanks so much Balaji!

 

That was great, and definately the more "normal" way to rotate the view. My user's however, sometimes use the  basic "rotate" command from paperspace and rotate the viewport object with the North Arrow block at the same time to get the view they want. Then use the grips of the viewport to change it's shape back to a rectangle to fit the page. This option came out with 2010 if I recall, and my user's take advantage of it in some situations. That's when the code fails after a couple of rotates. Hope that makes sense. We only deal in 2D so this option works for them.

 

Rotate the first time say ~45 degrees, then another ~45, then another ~-30, etc. the viewtwist angle will be correct for the first couple, then goes off.

 

Hope you can reproduce the error that way.

 

thanks again for your help

 

cj

0 Likes
Message 8 of 13

Balaji_Ram
Alumni
Alumni

Hi CJ,

 

Can you please record the steps ?  I still cannot reproduce the behavior. 

 

The only time i find a mismatch is when i skip or forget to select the North block while rotating.

 

Here is a recording :

 

http://autode.sk/1Kn82sa

 

Regards,

Balaji

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 9 of 13

Anonymous
Not applicable

I tried using Screencast for the first time...pretty cool.

 

Here is the recording, I rotate the viewport the first time, everything ok, after the second rotation, the values are different.

 

http://autode.sk/1KpXYhU

 

Thanks so much for your continued effort!

 

cj

0 Likes
Message 10 of 13

Balaji_Ram
Alumni
Alumni
Accepted solution

Thanks for recording a video.

 

I did reproduce the behavior at my end.

 

It seems the ViewTwist is including multiples of 360 when rotated in clockwise and counter clockwise directions.

Although it does not affect the actual viewport twist as any angle when rotated 360 degrees in either direction should not affect its numerical value.

 

But in your code it does affect as you require comparison with the block reference's rotation value.

 

A way to workaround it would be to handle it as in this code :

 

    <CommandMethod("Test1")> _
    Public Sub Test1Method()
        ' check north arrow
        Dim myDWG As Document = Application.DocumentManager.MdiActiveDocument
        Dim database As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = myDWG.Editor
        Dim BlockRotAng As Double = 0.0 ' rotation angle of North Arrow Block
        Dim UCSAngleDeg As Double = 0.0 ' UCS angle
        Dim NORTHCALC As Double = 0.0
        Dim vptwistInDegrees As Double = 0.0 ' viewport twist in degrees (WCS)
        Using myTrans As Transaction = myDWG.TransactionManager.StartTransaction
            Dim bt As BlockTable = CType(myTrans.GetObject(database.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim btr As BlockTableRecord = CType(myTrans.GetObject(bt("ntharrow"), OpenMode.ForRead), BlockTableRecord)
            Dim objIdColl As ObjectIdCollection = btr.GetBlockReferenceIds(True, True)
            Dim NORTHID As ObjectId = objIdColl(0)
            If NORTHID.IsNull = False Then
                Dim NorthBlkRef As BlockReference = NORTHID.GetObject(OpenMode.ForRead)
                BlockRotAng = NorthBlkRef.Rotation
                ' converting Radian to degree
                BlockRotAng = BlockRotAng * (180 / Math.PI)
                Dim symTable As SymbolTable = CType(myTrans.GetObject(database.ViewportTableId, OpenMode.ForRead), SymbolTable)
                Dim vpcount As Integer = 0
                For Each id As ObjectId In symTable
                    Dim symbol As ViewportTableRecord = CType(myTrans.GetObject(id, OpenMode.ForRead), ViewportTableRecord)
                    Dim acadDoc As AcadDocument = Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(myDWG)
                    acadDoc.MSpace = True
                    Dim CVport As Autodesk.AutoCAD.DatabaseServices.Viewport = DirectCast(myTrans.GetObject(myDWG.Editor.CurrentViewportObjectId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Viewport)
                    'If (CVport.TwistAngle > 2 * Math.PI) Then
                    '    CVport.UpgradeOpen()
                    '    CVport.TwistAngle = Math.Atan2(Math.Sin(CVport.TwistAngle), Math.Cos(CVport.TwistAngle))
                    'End If
                    Dim vptwistInRadians As Double = CVport.TwistAngle
                    vptwistInDegrees = Math.Abs((vptwistInRadians * (180 / Math.PI)))

                    NORTHCALC = BlockRotAng
                    ed.WriteMessage([String].Format(vbLf & "North Block Rotation : {0}", NORTHCALC.ToString))
                    ed.WriteMessage([String].Format(vbLf & "ViewportTwist: {0}", vptwistInDegrees.ToString))
                    myTrans.Commit()
                    acadDoc.MSpace = False
                    vpcount = vpcount + 1
                Next
                'If NORTHCALC = 360 Then
                '    NORTHCALC = 0
                'End If
                'If vptwistInDegrees = 360 Then
                '    vptwistInDegrees = 0
                'End If

                If vptwistInDegrees >= 360 Then
                    Dim fullCircles As System.Int32
                    fullCircles = CType(Math.Floor(vptwistInDegrees / 360), Integer)
                    vptwistInDegrees = vptwistInDegrees - 360 * fullCircles
                End If

                If vpcount = 1 And UCSAngleDeg > 0 Then
                    If (NORTHCALC - UCSAngleDeg) > 1 Or (UCSAngleDeg - NORTHCALC) > 1 Then
                        MsgBox("Check the angle of the North Arrow", , "NORTH ARROW ROTATION")
                    End If
                End If
                If vpcount = 1 And UCSAngleDeg = 0 Then
                    If (NORTHCALC - vptwistInDegrees) > 1 Or (vptwistInDegrees - NORTHCALC) > 1 Then
                        MsgBox("Check the angle of the North Arrow", , "NORTH ARROW ROTATION")
                    End If
                End If
            End If
        End Using
    End Sub

Hope this helps

 

Regards,

Balaji

 

 

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 11 of 13

Anonymous
Not applicable

Thanks so much Balaji.

 

I quickly tried your code, but it is failing on 

Dim NORTHID As ObjectId = objIdColl(0)

I gen an unhandled exception.

 

Will need to take some time to look into that. I'm a part time programmer and have gotten tied up with some other work. Hopefully next week I will get a chance to determine why the error.

 

thanks again

cj

 

0 Likes
Message 12 of 13

Balaji_Ram
Alumni
Alumni

Hi CJ,

 

Not a problem, please feel free to update when you get a chance to work on it.

 

The line that is giving an error is a replacement for "FindBlock" that you had in your original code.

Since during my tests north arrow was the only blockreference in the drawing, i simply got hold of it without the "FindBlock". 

 

Please feel free to use your original code to find the NORTHID instead of that line.

i.e., Dim NORTHID As ObjectId = FindBlock("ntharrow")

 

Regards,

Balaji



Balaji
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 13 of 13

Anonymous
Not applicable

Got it to work! Thanks Balaji!

To cover both scenerio's if the user rotates both the viewport and the north arrow together, the code worked great, BUT if they did it the "traditional" way of rotating within the viewport, the routine did not show the correct North Arrow rotation due to the counterclockwise measurement, so I added the following if the original value of the north arrow does not match, then adjust it and try the match again.

 

 

' check for match, if not adjust North angle based on counterclockwise measurement
Dim angledif As Single = NORTHCALC - vptwistInDegrees

If angledif > 1 Then
If NORTHCALC > 180 Then
NORTHCALC = 360 - NORTHCALC
Else
NORTHCALC = NORTHCALC + 180
End If
End If

0 Likes