HiI'm working in Microstation V8i Version 08.11.09.608 on a Windows 7 machineI found the CrossingPerpendiculars macro by DanPaul at this location: https://communities.bentley.com/products/programming/microstation_programming/f/archived-microstation-v8-xm-edition-vba-forum/20356/perpendicular-lines-to-complexstringelement-or-chainableelement
The macro does not deal with segments of the line that are vertical when looked at in Top view.
I'd be happy if a mathematically competent person could find a fix for the problem in the macro.
Sub sbExamineLine() Dim esc As ElementScanCriteria Set esc = New ElementScanCriteria esc.ExcludeAllTypes esc.IncludeType msdElementTypeLine esc.IncludeType msdElementTypeBsplineCurve esc.IncludeType msdElementTypeLineString esc.IncludeType msdElementTypeComplexString 'esc.ExcludeAllLevels 'esc.IncludeLevel oLevel Dim oEle As Element Dim ee As ElementEnumerator Dim dblSpan As Double Set ee = ActiveModelReference.Scan(esc) Dim Count As Long dblSpan = 10 Do While ee.MoveNext Set oEle = ee.Current Count = Int(oEle.AsChainableElement.Length / dblSpan) + 1 CrossingPerpendiculars oEle, Count, 20 Loop End Sub ' Side 0 means cross, 1 means left, -1 means right Sub CrossingPerpendiculars(LinearElem As Element, Count As Long, Distance As Double, Optional Side As Integer = 0) Dim bSpl As BsplineCurve Set bSpl = New BsplineCurve Dim FrenetFrame As Matrix3d, Param As Double, Curvature As Double, Torsion As Double Dim Tangent As Point3d, Normal As Point3d, BiNormal As Point3d Dim LinearNormal As Point3d: LinearNormal = Point3dFromXYZ(0, 1, 0) Dim StartPoint As Point3d, EndPoint As Point3d, Length As Double Dim oLine As LineElement Dim halfDist As Double: halfDist = Distance * 0.5 If LinearElem.IsTraversableElement Then bSpl.FromElement LinearElem Length = bSpl.ComputeCurveLength For Length = 0 To Length Step Length / (Count - 1) bSpl.EvaluatePointAtDistance Param, Length StartPoint = bSpl.EvaluatePointFrame(FrenetFrame, Curvature, Torsion, Param, LinearNormal) ' If UpVector is 0, 0, 1, then we know, that if Frenets UpVector's Z value is less than zero, ' it is up side down for us... So we can negate it's needed rows... If FrenetFrame.RowZ.z < 0 Then '' RowZ [Binormal/UpVector in 2D] is not needed negated now, so we can keep it unchanged 'FrenetFrame.RowZ = Point3dNegate(FrenetFrame.RowZ) '' RowY [Normal/SideVector in 2D] is only needed on correct side FrenetFrame.RowY = Point3dNegate(FrenetFrame.RowY) '' RowX [Tangent/DirectionVector] is not needed negated now too... 'FrenetFrame.RowX = Point3dNegate(FrenetFrame.RowX) End If If Side = 0 Then EndPoint = Point3dAddScaled(StartPoint, FrenetFrame.RowY, halfDist) StartPoint = Point3dAddScaled(StartPoint, FrenetFrame.RowY, -halfDist) Set oLine = CreateLineElement2(Nothing, StartPoint, EndPoint) ActiveModelReference.AddElement oLine oLine.Redraw Else EndPoint = Point3dAddScaled(StartPoint, FrenetFrame.RowY, Side * Distance) Set oLine = CreateLineElement2(Nothing, StartPoint, EndPoint) ActiveModelReference.AddElement oLine oLine.Redraw End If Next Length Else Debug.Print "Element is not traversable!!!" End If End Sub
Any progress in this?
I have ran into exactly the same problem. The crossing line is drawn perfectly on all other part of the complex, except for the lines running vertical in the y-axes.
The lines where the different between the x-coordinate of the start and end point is zero.
Regards,
Finn Mejding
CAD Manager
Railway and Metro
COWI
Hi,
Did a little debug and came up with this work-around.
Don't know if this gives me trouble later on in my program. But I'll take the change.
StartPoint = m_oSpline.EvaluatePointFrame(FrenetFrame, Curvature, Torsion, Param, LinearNormal)If FrenetFrame.RowX.x = 0 And FrenetFrame.RowX.Y = 1 Then FrenetFrame.RowY.x = 1 End If If FrenetFrame.RowX.x = 0 And 1 - FrenetFrame.RowX.Y = 2 Then FrenetFrame.RowY.x = -1 End If EndPoint = Point3dAddScaled(StartPoint, FrenetFrame.RowY, -50) StartPoint = Point3dAddScaled(StartPoint, FrenetFrame.RowY, 50) Set Linelem = CreateLineElement2(Nothing, StartPoint, EndPoint) ActiveModelReference.AddElement Linelem Linelem.Rewrite
The line: If FrenetFrame.RowX.x = 0 And 1 - FrenetFrame.RowX.Y = 2 Then
looks odd, but I couldn't get this to work: If FrenetFrame.RowX.x = 0 And FrenetFrame.RowX.Y = -1 Then
even though FrenetFrame.RowX.y was -1 it returned 'false'
The above code is modifications to DanPauls original code.
I was quite excited when I tested your modifications to the code, at first, but, further testing seems to indicate that it's not a complete solution. I admit that I do not have the maths capability to understand the problem, let alone find a solution. The attachment shows that, for most of the line, the modified macro worked well. The problem occurred at the 'end' of the line where 7 locations malfunctioned. The 7 yellow dots. Of course, it could be an error in my code (I'll have a look at DanPaul's original code with your modification when I get some time). It does seem strange that the code, with your modification, manages to perform perfectly on the other two 'vertical' legs. Your code is a huge improvement, without it 492 points are incorrectly calculated. Thanks for that. Regards. Paul Smith
You're welcome Paul
As I wrote "I don't know if this gives me trouble later in the code". But for my macro it works right now.
Hope you manage to figure out what wrong with the 7 points at the end of your string.
Hi Finn
In case you don't notice my reply to Jon (above) his macro works perfectly on my test line. Should you have any issues with your version, I would recommend that you have a look at Jon's macro .
Regards
Paul Smith