Finding a rounded coordinate in a rotated view along Element, MST8i SS4, VBA

Dear All,

I'm drawing a square in rotated View and want to create horizontal lines every X-m. But i'am getting a not rounden X-Cooordinate on the Start of Lines.
So I have perhaps to calculate more Distance, because each line must start with a rounded X-Coordinate.
Only Rounding the coordinate moves the point along the other axis. How can this problem be solved if there is a view rotation angle, a point of displacement of the axes.

I'am Using a Method form John Summers with IPrimitiveCommandEvents for Creating a of Square and other Elements.

Thanks for your Ideas.

Parents Reply Children
  • Is it correct?

    No idea!  I have difficulty visualising what you want to do.  Perhaps it would help if you draw manually what you want to achieve, then post the DGN file here?

     
    Regards, Jon Summers
    LA Solutions

  • Hi Mikha,

    the problem is that your picture is not well connected to the code.

    Plus, when you do not bother to share a code in a proper way (to use Insert > Insert Code tool to ensure it will be displayed as the code), I assume not many people is willing to invest time to analyze the problem.

    Another problem is that you are trying to solve two different problems in one step:

    • How to work in rotated view
    • How to implement specific rounding

    I recommend to implement the rounding at first (for not rotated view, so there will be no matrices used) and provide more complete code, that can be tested (it means it has to be sub, containing input values and some output). It allows to move from pure theory to something testable.

    When it will work, it makes sense to start another discussion how to extend the code to work in rotated view.

    With regards,

      Jan

    1. Create your geometry using unrotated Cartesian coordinates
    2. Determine your target point
    3. Group the elements into a cell: the origin of your cell is your target point
    4. Rotate the cell about its origin (your target point) by the inverse view rotation
    5. Drop the cell and add its components to your active DGN model

     
    Regards, Jon Summers
    LA Solutions

  • I will follow your Recommendations Jan and prepare a Code for a Rounding in unrotated View. 

  • This is my Code for unrotated View. In This case i need round Y-Coordinates.

    Option Explicit
    Option Base 0
    
    Implements IPrimitiveCommandEvents
    
    Dim k As Long, nPnts As Long
    Dim Origin As Point3d                               'Ursprungpunkt
    Dim obAccudrawAn As Boolean
    Dim PtsShapInnen() As Point3d                       'Punkte zur Bildung Fläche des Zaunes
    Dim Plane As Plane3d                                'Projektion auf Plan
    Dim Rot As Matrix3d, Hyp As Double                  'Matrize zur Ansicht, Hypotenuse zw. Ursprung und Point
    Dim DoubleX As Double, DoubleY As Double            'Katheten
    Dim Xv As Point3d, Yv As Point3d                    'Projektion auf X,Y-Achsen
    Dim Alfa As Double, Beta As Double, dAngle As Double         'Winkeln
    Dim Sh As element, LineLinkeKo() As LineElement
    
    
    Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d, ByVal View As View)
    If nPnts = 0 Then
        Origin = Point
        Plane.Origin = Point
        nPnts = nPnts + 1
        CommandState.StartDynamics
    Else
        CommandState.StopDynamics
        CommandState.StartDefaultCommand
        If Not Sh Is Nothing Then Sh.Level = ActiveSettings.Level: ActiveModelReference.AddElement Sh
        For k = LBound(LineLinkeKo) To UBound(LineLinkeKo)
            If Not LineLinkeKo(k) Is Nothing Then LineLinkeKo(k).Level = ActiveSettings.Level: ActiveModelReference.AddElement LineLinkeKo(k)
        Next k
    End If
    End Sub
    
    Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, _
     ByVal View As View, ByVal DrawMode As MsdDrawingMode)
    
    On Error GoTo err
    If DrawMode = msdDrawingModeTemporary Then
        'Ansichtdrehung auslesen
         If CommandState.AccuDrawHints.IsEnabled Then
            Rot = Matrix3dInverse(CommandState.AccuDrawHints.GetRotation(View))    'Matrix3dInverse
         Else
            Rot = Matrix3dInverse(View.Rotation)
         End If
         If Matrix3dIsXYRotation(View.Rotation, dAngle) Then
         End If
         
         'auf Plan projezieren
         Plane.Normal = Point3dFromMatrix3dColumn(Rot, 2)
         Xv = Point3dFromMatrix3dColumn(Rot, 0)
         Yv = Point3dFromMatrix3dColumn(Rot, 1)
         Point = Point3dProjectToPlane3d(Point, Plane)
         Hyp = Point3dDistance(Point, Origin)
         
         Alfa = Point3dAngleBetweenVectors(Xv, Point3dSubtract(Point, Origin))
         Beta = Point3dAngleBetweenVectors(Yv, Point3dSubtract(Point, Origin))
        
    '     If (Alfa > (135 * Pi / 180)) Or (Beta > (135 * Pi / 180)) Or (Beta > 1.5) Or (Alfa > 1.5) Then Exit Sub
        
         ReDim PtsShapInnen(0 To 3)
         PtsShapInnen(0) = Origin
         PtsShapInnen(1) = Point3dAddScaled(Origin, Xv, Hyp * Cos(Alfa))
         PtsShapInnen(2) = Point
         PtsShapInnen(3) = Point3dAddScaled(Origin, Yv, Hyp * Cos(Beta))
         Set Sh = CreateShapeElement1(Nothing, PtsShapInnen, msdFillModeNotFilled)
        
         'Rahmen als Rechteck erstellen
         If dAngle = 0 Then Call CreateLinesRounded(View, Origin)
    
        'Breite/Höhe
         DoubleX = Point3dDistanceXY(PtsShapInnen(0), PtsShapInnen(1))
         DoubleY = Point3dDistanceXY(PtsShapInnen(0), PtsShapInnen(3))
    End If
    
    Sh.Redraw DrawMode
    For k = LBound(LineLinkeKo) To UBound(LineLinkeKo)
        If Not LineLinkeKo(k) Is Nothing Then LineLinkeKo(k).Redraw DrawMode
    Next k
    
    Exit Sub
    err:
        Select Case err
        Case Else
            MsgBox "Error in [clsFenceElement] // Dynamics " & _
            vbCrLf & err.Description, vbCritical, err.Number
    '        Resume
        End Select
    End Sub
    
    Private Sub CreateLinesRounded(oView As View, Origin As Point3d)
    Dim dblSegDist As Double, Delta_Y As Double, i As Long, OriginRound As Point3d, DivPoints() As Point3d, lngDivisionsY As Long, PntsLinkeKo(1) As Point3d
    
    'Linke Linien-Koordinaten
    ReDim LineLinkeKo(0) As LineElement
    dblSegDist = 1000
    OriginRound = Origin
    OriginRound.Y = Runden(CDbl(CLng(Origin.Y + 100)), -2)
    Delta_Y = Point3dDistance(OriginRound, PtsShapInnen(3))
    lngDivisionsY = Int((Delta_Y - 15) / 1000)
    If lngDivisionsY > 0 Then
        lngDivisionsY = lngDivisionsY + 1
        ReDim DivPoints(0 To lngDivisionsY - 1) As Point3d: ReDim LineLinkeKo(0)
        DivPoints(0) = PtsShapInnen(0)
        DivPoints(UBound(DivPoints)) = Point3dAddScaled(PtsShapInnen(3), Yv, -15)
        For i = (LBound(DivPoints) + 1) To (UBound(DivPoints))
            If i = 1 Then
                DivPoints(i) = DivPoints(0)
                DivPoints(i).Y = Runden(CDbl(CLng(DivPoints(0).Y + 1100)), -2)
            Else
                DivPoints(i) = Point3dAddScaled(DivPoints(i - 1), Yv, 1000)
            End If
            PntsLinkeKo(0) = DivPoints(i)
            PntsLinkeKo(1) = Point3dAddScaled(DivPoints(i), Xv, 25)
            If Not LineLinkeKo(UBound(LineLinkeKo)) Is Nothing Then ReDim Preserve LineLinkeKo(UBound(LineLinkeKo) + 1)
            Set LineLinkeKo(UBound(LineLinkeKo)) = CreateLineElement2(Nothing, PntsLinkeKo(0), PntsLinkeKo(1))
        Next i
    End If
    End Sub
    
    Public Function Runden(ByVal Number As Double, ByVal Digits As Integer) As Double
        Runden = Int(Number * 10 ^ Digits + 0.5) / 10 ^ Digits
    End Function    
    
    
    Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String)
        'not used
    End Sub
    
    Private Sub IPrimitiveCommandEvents_Reset()
        CommandState.StopDynamics
        CommandState.StartDefaultCommand
    End Sub
    
    Private Sub IPrimitiveCommandEvents_Cleanup()
        nPnts = 0
        CommandState.StopDynamics
    End Sub
    
    Private Sub IPrimitiveCommandEvents_Start()
        Set Sh = Nothing
        obAccudrawAn = CommandState.AccuDrawHints.IsEnabled
        If obAccudrawAn = False Then CadInputQueue.SendKeyin "accudraw activate"
    End Sub
    
    

  • Hi Jon,

    if you see on my Code, you will see that i need a Elements in Inverted View. How can i get a unrotated Cartesian coordinates from Elements of inverted View for case with rotated View. Thanks.

  • How can i get a unrotated Cartesian coordinates from Elements

    In general, elements don't have any rotation.  The exceptions are cell elements, text elements and perhaps some others.  A line or line-string, for example, is a set of coordinates with no intrinsic rotation.  You can rotate the line, which then has a new set of coordinates.

    If you have created elements in a no-rotation Cartesian system, then they have no rotation.

    You can rotate an element by applying a transform.  Element.Rotate is a shortcut that applies a rotation transform to most elements.

     
    Regards, Jon Summers
    LA Solutions

  • How can i get a unrotated Cartesian coordinates from Elements of inverted View for case with rotated View

    I occurs to me that you are not comfortable when discussing geometric algebra.  Here are some reading suggestions that may help.

     
    Regards, Jon Summers
    LA Solutions

  • Jon thank you for your advices. My Problem is in this diskussing, that my dynamic must be beginning with inverted Matrix, becase my Elements as rectangular  and other mus be orthogonal created. If i begin include of my Dynamics my Objects to transform with unrotated Matrix, i dont getting my results. 

    I will try get this books, it would be interesting for me i hope. Have a Nice Weekend. With Regards, Mikha