Find Actual Angle in Euclidian System

My current app has proved more “interesting” than i first thought. I need to rotate some text as part of it. Well - fine and easy in plan views, legend views, drafting views. but I’m working with odd detail views cut at all sorts of weird angles. More on that in later posts.

The issue with rotating the text is that the angle of the view could be in any weird direction, so you can’t just assume (1,0,0) is right and (0,1,0) up (on the sheet. In an elevation it is (0,0,1) and downhill from there.

Add to that: AngleTo always returns angles less than 180. So, it will always calculate the closest angle. I found a good discussion of this on adsk Inventor:
AngleTo

Here’s the code in Python and doctored up to be usable. This takes the current view as a Euclidian environment with XYZ as you would expect them and lets you return the angle of two vectors in actual 0-360 angles, either counterclockwise (standard right-hand space AutoCAD style or clockwise. d=1 counterclockwise, d=0 clockwise.

def VectorAngle(v1, v2, d):
    xvector = doc.ActiveView.RightDirection
    yvector = doc.ActiveView.UpDirection

    if d == 1:
        direction = xvector.CrossProduct(yvector)
    else:
        direction = yvector.CrossProduct(xvector)

    oCrossProd = v1.CrossProduct(v2)

    if oCrossProd.DotProduct(direction) < 0:
        angRad = 2 * math.pi - v1.AngleTo(v2)
    else:
        angRad = v1.AngleTo(v2)

    angDeg = angRad * 180 / math.pi

    return angDeg

Here’s the etxt on a oblique view at every odd angle.

And after using the actual angle returned above.

As an aside: you can see how adsk is aligning all of their API’s. This furthers my belief that adsk will stop with the software bit and simply become an API platform.