[V8i vba] how to tell if your cursor is to the left or right of a point in a rotated view

I have a iprimitive set up to place a text node and it has a call out box around it. I have coded it to check in the dynamcs event if the cursor is on the right side of left side of a point to figure out the justification needed. which works great. but im not trying to update the code to work with rotated views. while I have all the code to rotate everything correctly im struggling with how to tell if the cursor is on the left or right side when the view is rotated. the screen shot below shows the elements. the first click would be at the start of the call out (the bottom point in the green block). then the polygon and text elements are dynamically displayed off the cursor position (the top right point) one the cursor moves to the left of the startof the call out point(the bottom point in the green block) then it switches the justification like the second picture shows.

im just check the x values of the two points to tell if its on the left or right side but that doesn't work in a rotated view.

anyone got any advice or functions that could lead me to a solution.

thanks

  • for some reason the images didn't show up...here they are

  • good morning
    I had the same problem long ago
    solved with help here
    I enclose part of a macro
    where you see how to fix it

    Dim oView As view
    Dim mat As Matrix3d
    Dim rotation As Matrix3d
    Dim transform As Transform3d

    ' find the rotation of the view

     rotation = Matrix3dTranspose(ActiveDesignFile.Views(1).rotation) 

    ' calculating the transformation

    transform = Transform3dFromMatrix3dAndFixedPoint3d(rotation, p(0))   ' p(0)  point on which to rotate




     Set Line1 = CreateLineElement1(Nothing, p())
            Line1.transform transform                                    ' after entering the elements apply the transformation
            Line1.Color = 7
            Line1.Redraw DrawMode
            
            Pa(0) = p(0)
            Pa(1) = p(1)
            Pa(2) = p(2)
            
            
            
            
            
            rot = Matrix3dFromAxisAndRotationAngle(2, 0)
           
            origine.X = Pa(1).X
            origine.Y = Pa(1).Y + 0.015 * fsx / 100
            
            Set testo = CreateTextElement1(Nothing, Format(distmincalc, "0.00"), origine, rot)
            testo.transform transform
            testo.Color = 6
            testo.Redraw DrawMode

    I hope can help

    Ciao

    Massimo Callegher
  • Ciao,

    thank you but this code is just rotating the elements. I already have that code figured out. what I am having trouble with is how to figure out if my cursor position is to the left or right of the start of the call out polygon shape. I need this to figure out if I should left justify or right justify the text. right now im just comparing the x values for the two points. but in a rotated view I cant use the x values.

    Unless im missing something your code just creates the elements and rotates them, which is not what im after.

    thanks
  • Hello
    execute instructions like as if I were not rotated view
    then apply transformation

                         

    It will not be done well
    but it works

        Set Line1 = CreateLineElement2(Nothing, point1, point2)
         Line1.Color = 7
         Line1.LineStyle = ActiveDesignFile.LineStyles("2")
         Line1.Redraw DrawMode
         
         If (nPoints = 1) Then
        
        ' Debug.Print "ACS -----> P(1)" & Point3dToString(p(1))
                     '    AA                         AA
                     '   ____ p(1)             p(1) ____
                     '       \                    /
                     '        \                  /
                     '         p(0)           p(0)
                   
                   If p(1).X < p(0).X And p(1).Y > p(0).Y Then        '
                     AA = -AA
                     CadInputQueue.SendCommand "TEXTSTYLESET SingleLineJust RIGHTBOTTOM ""ts_distmet"""
                    
                    ElseIf p(1).X > p(0).X And p(1).Y > p(0).Y Then
                    AA = AA
                     CadInputQueue.SendCommand "TEXTSTYLESET SingleLineJust lEFTBOTTOM ""ts_distmet""" ' OK
                   
                   ElseIf p(1).X < p(0).X And p(1).Y < p(0).Y Then
                    AA = -AA
                  CadInputQueue.SendCommand "TEXTSTYLESET SingleLineJust rightBOTTOM ""ts_distmet"""   'OK
                  ElseIf p(1).X > p(0).X And p(1).Y < p(0).Y Then
                  AA = AA
                 CadInputQueue.SendCommand "TEXTSTYLESET SingleLineJust LEFTBOTTOM ""ts_distmet"""
            End If
            
               p(2).X = p(1).X + AA            '
               p(2).Y = p(1).Y + 0             '
            
            Set Line1 = CreateLineElement1(Nothing, p())
            Line1.transform transform
            Line1.Color = 7
            Line1.Redraw DrawMode

    https://communities.bentley.com/cfs-file/__key/communityserver-discussions-components-files/343173/2017_2D00_02_2D00_22_5F00_1622.swf

    I apologize but I do not speak English

    Massimo Callegher
  • Thank you, I was hoping there was a MicroStation function. but here is what I ended up doing.

    Went back to my math days...

    so I basically want to see if my cursor is to the left or right of a given point. We will call this given point StartPoint and the cursor point will just be called point.

    If we think of the start point being the origin point or 0,0 point. we can find the angle it makes with Point. So this would be unrotated and the resulting angle is relative to which quadrant you are in (thing unit circle from math days). We want the absolute angle. so if you treat start point as 0,0 then the distance in x and y from the start point to Point will tell you what quadrant you are in (positive x and positive y would be quad 1, negative x and positive y would be quad 2, negative x and negative y would be quad 3, and positive x and negative y would be quad 4)

        Dim hyp2 As Double, xprimeValue As Double, dynAngle As Double 'dynamic angle between start point and cursor point to x' axis
        hyp2 = Abs(Point3dDistance(Point, startPoint))
        'figure out what quadrint cursor is in if startpoint is origin (need this is get total angle) this is unrotated will then subtract in the rotation from the view
        'use this final angle for left of right, if angle is greater then 90 (Pi/2) and less then 270 (3/2Pi) then its on the left!
        Dim newX As Double, newY As Double
        newX = Point.x - startPoint.x
        newY = Point.Y - startPoint.Y
        If newX >= 0 And newY >= 0 Then ' quad1
           dynAngle = Arcsin((Abs(Point.Y - startPoint.Y)) / hyp2)
        ElseIf newX < 0 And newY >= 0 Then 'quad2
            dynAngle = Arcsin((Abs(Point.Y - startPoint.Y)) / hyp2)
            dynAngle = Pi - dynAngle
        ElseIf newX < 0 And newY < 0 Then ' quad3
            dynAngle = Arcsin((Abs(Point.Y - startPoint.Y)) / hyp2)
            dynAngle = Pi + dynAngle
        ElseIf newX >= 0 And newY < 0 Then ' quad4
            dynAngle = Arcsin((Abs(Point.Y - startPoint.Y)) / hyp2)
            dynAngle = (2 * Pi) - dynAngle
        End If
    
    

    now we have our absolute angle so if we subtract the rotation angle from this we will get the angle between the two points about the rotate view. If this final angle is negative then we need to add 360 or 2pi to it. this will bring all possible angles between 0 and 360. or 0 to 2pi. now if your angle is greater then 90 (0.5pi) and less then 270(1.5pi) then your cursor or Point is to the left of the startpoint.

        Dim BoolRot As Boolean, dblAngle As Double
        BoolRot = Matrix3dIsXYRotation(View.rotation, dblAngle)
        If BoolRot = False Then
            MsgBox ("Rotation angle from Active View Window count not be obtained, Process aborted!")
            Call IPrimitiveCommandEvents_Reset
        Else
            dblAngle = -1 * dblAngle ' need to get oppositive of the view angle to get the correct rotation
        End If
    
        dynAngle = dynAngle - dblAngle
        If dynAngle < 0 Then dynAngle = dynAngle + (2 * Pi)
    
        If dynAngle > (Pi / 2) And dynAngle < (1.5 * Pi) Then ' to the left of startpoint in quads 2 or 3 in rotated axis.
    
        Else ' to the right of startpoint quads 1 or 4 in rotated axis
    
        End If
    

    hopefully that made sense to everyone. kinda hard to put it to words

    in summary all I did was..

    1. get the absolute angle between two points. (treating the startpoint as 0,0)

    2. got the rotation angle.  

    3. subtracted the rotation angle from the absolute angle to get the angle about the rotated view

    4. used that final angle (3. from above) to test if im to the left of right of the start point 

    I did make a function for acrsin..

    Public Function Arcsin(x As Double) As Double
        If (Sqr(1 - x * x) <= 0.000000000001) And (Sqr(1 - x * x) >= -0.000000000001) Then
            Arcsin = Pi / 2
        Else
            Arcsin = Atn(x / Sqr(-x * x + 1))
        End If
    End Function

     

    Answer Verified By: John Drsek 

  • Hello
    because of my poor old English I can not help you more
    try to look at this post

    communities.bentley.com/.../327919


    and download the macro

     misura-and-place (3) _view_rot.mvba

    for me it was very helpful and taught me a lot

     

     

    Massimo Callegher
  • Unknown said:
    How to tell if your cursor is to the left or right of a point?

    I've written a VBA project that shows how to do that...

    The macro works in dynamics.  Start by identifying a cell.  Move the cursor, and it draws the yellow line from the cell origin to the cursor location.  At the same time, it draws the green line 'north' from the cell origin.  'North' depends on the view rotation.  As you move the cursor, it informs you whether you are left or right of 'north'.

    The macro makes use of VBA linear algebra objects: Vector3d, Matrix3d and operations on those data.  It avoids trigonometry entirely, leading to a concise implementation..

     
    Regards, Jon Summers
    LA Solutions