Rotation and transformation matrix

Hi,

I'm struggling with placing a cell along an arc in VBA.

I have a Complex Chain where I will place a cell along the whol chain with a fixed distance.

I have solved the rotation on the "Line" part of the chainm but having trouble with the arc.

The rotation is almost correct, but almost doesn't count :-)

Any one have a suggestion?

The code snippet for placing the cell:

Sub showLineElm(LinElm As ComplexStringElement)
  Dim elm As ElementEnumerator
  Dim aelm As ArcElement
  Dim lelm As LineElement
  Dim oPH As PropertyHandler
  Dim lastsegment As String
  Dim streng As String, streng1 As String
  Dim start As Point3d
  Dim skala As Point3d
  Dim oCell As CellElement
  Dim z As Integer
  Dim ant_cell As Double, distance As Double
  Dim vinkel As Double
  Dim mtrxRotation As Matrix3d
 
  skala.X = 1
  skala.Y = 1
  skala.z = 1
  If LinElm.Type = msdElementTypeComplexString Then
    If LinElm.IsTraversableElement Then
      Set elm = LinElm.GetSubElements
      Do While elm.MoveNext

        Select Case elm.Current.Type
          Case msdElementTypeLine
            Set lelm = elm.Current.AsLineElement
            lastsegment = "Segments[" & (lelm.VerticesCount - 2) & "]."
            Set oPH = CreatePropertyHandler(lelm)
            oPH.SelectByAccessString (lastsegment & "Start")
            start = oPH.GetValueAsPoint3d
            oPH.SelectByAccessString (lastsegment & "Direction")
            streng = oPH.GetValue
            vinkel = Degrees(CDbl(streng))
            mtrxRotation = Matrix3dFromAxisAndRotationAngle(2, CDbl(streng))
            Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
            ActiveModelReference.AddElement oCell
            ant_cell = lelm.Length / 0.854
            ant_cell = ant_cell \ 1
            distance = 0
            For z = 1 To ant_cell
              distance = distance + 0.854
              If distance > lelm.Length Then
                Exit For
              End If
              start = lelm.PointAtDistance(distance)
              Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
              ActiveModelReference.AddElement oCell
            Next z

          Case msdElementTypeArc
            Set aelm = elm.Current.AsArcElement
            Set oPH = CreatePropertyHandler(aelm)
            oPH.SelectByAccessString ("SweepAngle")
            vinkel = oPH.GetValue
            mtrxRotation = Matrix3dFromAxisAndRotationAngle(2, vinkel)
            start = aelm.StartPoint
            Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
            distance = 0
            oCell.Transform Transform3dFromMatrix3dAndFixedPoint3d(mtrxRotation, start)
            ActiveModelReference.AddElement oCell
            ant_cell = aelm.Length / 0.854
            ant_cell = ant_cell \ 1
            For z = 1 To ant_cell
              distance = distance + 0.854
              If distance > aelm.Length Then
                Exit For
              End If
              start = aelm.PointAtDistance(distance)
              Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
              oCell.Transform Transform3dFromMatrix3dAndFixedPoint3d(mtrxRotation, start)
              ActiveModelReference.AddElement oCell
            Next z
        End Select
      Loop
    End If
  End If
errExit:
End Sub    'showLineElm

Parents Reply Children
  • Jan,

    Thought I was OK by tagging the post with MicroStation V8i Open mouth

    My version is: 08.11.09.459 (SelectSeries 3).

    This is what I mean by "Close, but no cigar", the blue ones are placed manually with the correct rotation, the black cells are drawn by my program.

    The code:

    Sub showLineElm(LinElm As ComplexStringElement)
      Dim elm As ElementEnumerator
      Dim aelm As ArcElement
      Dim lelm As LineElement
      Dim oPH As PropertyHandler
      Dim lastsegment As String
      Dim streng As String, streng1 As String
      Dim start As Point3d
      Dim skala As Point3d
      Dim oCell As CellElement
      Dim z As Integer
      Dim ant_cell As Double, distance As Double
      Dim vinkel As Double
      Dim mtrxRotation As Matrix3d
      
      skala.X = 1
      skala.Y = 1
      skala.z = 1
      If LinElm.Type = msdElementTypeComplexString Then
        If LinElm.IsTraversableElement Then
          Set elm = LinElm.GetSubElements
          Do While elm.MoveNext
            Select Case elm.Current.Type
              Case msdElementTypeLine
                Set lelm = elm.Current.AsLineElement
                lastsegment = "Segments[" & (lelm.VerticesCount - 2) & "]."
                Set oPH = CreatePropertyHandler(lelm)
                oPH.SelectByAccessString (lastsegment & "Start")
                start = oPH.GetValueAsPoint3d
                oPH.SelectByAccessString (lastsegment & "Direction")
                streng = oPH.GetValue
                vinkel = Degrees(CDbl(streng))
                mtrxRotation = Matrix3dFromAxisAndRotationAngle(2, CDbl(streng))
                Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
    '            oCell.GraphicGroup = ggNum
                ActiveModelReference.AddElement oCell
                ant_cell = lelm.Length / 0.854
                ant_cell = ant_cell \ 1
                distance = 0
                For z = 1 To ant_cell
                  distance = distance + 0.854
                  If distance > lelm.Length Then
                    Exit For
                  End If
                  start = lelm.PointAtDistance(distance)
                  Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
                  ActiveModelReference.AddElement oCell
                Next z
              Case msdElementTypeArc
                Set aelm = elm.Current.AsArcElement
                Set oPH = CreatePropertyHandler(aelm)
                oPH.SelectByAccessString ("SweepAngle")
                vinkel = oPH.GetValue
                mtrxRotation = Matrix3dFromAxisAndRotationAngle(2, vinkel)
                start = aelm.StartPoint
                Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
    '            oCell.GraphicGroup = ggNum
                distance = 0
                oCell.Transform Transform3dFromMatrix3dAndFixedPoint3d(mtrxRotation, start)
               
                ActiveModelReference.AddElement oCell
                ant_cell = aelm.Length / 0.854
                ant_cell = ant_cell \ 1
                For z = 1 To ant_cell
                  distance = distance + 0.854
                  If distance > aelm.Length Then
                    Exit For
                  End If
                  start = aelm.PointAtDistance(distance)
                  Set oCell = CreateCellElement2("cellname", start, skala, True, mtrxRotation)
                oCell.Transform Transform3dFromMatrix3dAndFixedPoint3d(mtrxRotation, start)
                  ActiveModelReference.AddElement oCell
                Next z
            End Select
          Loop
        End If
      End If
    errExit:
    End Sub 'showLineElm
    

    The code is still "Work in Progress" and therefor not that pretty yet.

    Regards,

     

    Finn Mejding

    CAD Manager

    Railway and Metro

    COWI

  • Thought I was OK by tagging the post with MicroStation V8i

    Ok, you did it, but it's not accordingly the forum best practices, so a probability anybody will check tags in the first place is close to zero in my opinion.

    As defined in the article I linked, the version and language should be noted in subject like "[V8i VBA] Rotation and transformation matrix" and it's what frequent visitors of this group expect, not tags.

    The code is still "Work in Progress" and therefor not that pretty yet.

    In my opinion (but it's really subjective personal ;-) "the code prettiness" is a way how to write code quickly and efficiently, not the final state how code looks like when it's finished.

    What about my question about PropertyHandlers, this is something I recommend to remove in the first step (or to argue why this non standard construction is needed).

    With regards,

      Jan