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
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
Hellobecause of my poor old English I can not help you moretry 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
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
Helloexecute instructions like as if I were not rotated viewthen apply transformation
It will not be done wellbut 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
good morningI had the same problem long agosolved with help hereI enclose part of a macrowhere 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
for some reason the images didn't show up...here they are