Тема: Метод Select объекта SelectionSets, порядок выделения

Здравствуйте! Имеется несколько вертикальных линий. Пользователю предлагается выбрать две точки (левее и правее) линий. После чего требуется концы (начала)линии сверху  соеденить полилинией. Кусок кода следующий:

    Dim lineObj As AcadLine
    Dim lineObj2 As AcadLine
    Dim lineObj3 As AcadLine
    Dim startPt(0 To 2) As Double
    Dim endPt As Variant
    Dim plineObj As AcadPolyline
    Dim returnPnt As Variant
    Dim returnPnt2 As Variant
    returnPnt = ThisDrawing.Utility.GetPoint(, "1:")
    endPt = ThisDrawing.Utility.GetPoint(, "2:")
    endPt(1) = returnPnt(1)
    Set lineObj = ThisDrawing.ModelSpace.AddLine(returnPnt, endPt)
    Dim ssetObj As AcadSelectionSet
    Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")
    Dim mode As Integer
    mode = acSelectionSetCrossing
    ssetObj.Select mode, returnPnt, endPt
    Dim ar() As Double
    For i = 0 To ssetObj.Count - 1
    ReDim Preserve ar(i * 3 + 2)
    Set lineObj3 = ssetObj.Item(i)
    If lineObj3.startPoint(1) > lineObj3.endPoint(1) Then
    ar(i * 3) = lineObj3.startPoint(0)
    ar(i * 3 + 1) = lineObj3.startPoint(1)
    ar(i * 3 + 2) = lineObj3.startPoint(2)
    Else
    ar(i * 3) = lineObj3.endPoint(0)
    ar(i * 3 + 1) = lineObj3.endPoint(1)
    ar(i * 3 + 2) = lineObj3.endPoint(2)
    End If
 Set plineObj = ThisDrawing.ModelSpace.AddPolyline(ar)

Все бы ничего, но перебирая линии, попавшие в выделение, и строя по их верхним точкам полилинию, получается так, что линии в выделении ssetObj нумеруются не по порядку следования слева направо или справо налево, а в порядке их создания на чертеже. Это значительно ухудшает дело. Если массив точек полилинии еще можно отсортровать, то вторую задачу, стоящую передо мной, а именно - вычисления расстояниями между линиями, становится не так-то просто решить, если порядок создания не слева направо или наоборот.
Есть какие-нибудь идеи?
Заранее благодарю

Re: Метод Select объекта SelectionSets, порядок выделения

> Smog
Если вертикальные линии, то это проще
Выбери нужные линии любым способом, переделай
как тебе нужно

'~~~~~~~~~~~~~~~~Sort two-dimensional array~~~~~~~~~~~~'
' written by Fatty T.O.H. (c)2006 * all rights removed '
' SourceArr - two dimensional array                    '
' iPos - column number to sort by (starting from 1)    '
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Public Function ColSort(SourceArr As Variant, iPos As Integer) As Variant
     Dim Check As Boolean
     ReDim tmpArr(UBound(SourceArr, 2)) As Variant
     Dim iCount As Integer
     Dim jCount As Integer
     Dim nCount As Integer
     iPos = iPos - 1
     Check = False
     Do Until Check
          Check = True
          For iCount = LBound(SourceArr, 1) To UBound(SourceArr, 1) - 1
               If SourceArr(iCount, iPos) > SourceArr(iCount + 1, iPos) Then
                    For jCount = LBound(SourceArr, 2) To UBound(SourceArr, 2)
                         tmpArr(jCount) = SourceArr(iCount, jCount)
                         SourceArr(iCount, jCount) = SourceArr(iCount + 1, jCount)
                         SourceArr(iCount + 1, jCount) = tmpArr(jCount)
                         Check = False
                    Next
               End If
          Next
     Loop
     ColSort = SourceArr
End Function
Sub DrawOnTops()
     Dim oSset As AcadSelectionSet
     Dim ftype(0) As Integer
     Dim fData(0) As Variant
     Dim oEnt As AcadEntity
     Dim oLine As AcadLine
     Dim oPline As AcadPolyline
     Dim stPt As Variant
     Dim endPt As Variant
     Dim sortedArr As Variant
     Dim i As Integer
     On Error Resume Next
     If Not IsNull(ThisDrawing.SelectionSets.Item("$SortLines$")) Then
          Set oSset = ThisDrawing.SelectionSets.Item("$SortLines$")
          oSset.Delete
     End If
     Set oSset = ThisDrawing.SelectionSets.Add("$SortLines$")
     ftype(0) = 0: fData(0) = "LINE"
     oSset.SelectOnScreen ftype, fData
     ReDim ptarr(0 To oSset.Count - 1, 0 To 2) As Variant
     For Each oEnt In oSset
          Set oLine = oEnt
          stPt = oLine.StartPoint
          endPt = oLine.EndPoint
          If stPt(1) > endPt(1) Then
               ptarr(i, 0) = stPt(0): ptarr(i, 1) = stPt(1): ptarr(i, 2) = stPt(2)
          Else
               ptarr(i, 0) = endPt(0): ptarr(i, 1) = endPt(1): ptarr(i, 2) = endPt(2)
          End If
          i = i + 1
     Next
     sortedArr = ColSort(ptarr, 1)     '<--sort by first subitem (by X coordinate)
     ReDim coordArr((UBound(sortedArr, 1) + 1) * 3 - 1) As Double
     Dim n As Integer
     For i = 0 To UBound(sortedArr, 1)
          coordArr(n) = sortedArr(i, 0): coordArr(n + 1) = sortedArr(i, 1): coordArr(n + 2) = sortedArr(i, 2)
          n = n + 3
     Next
     Set oPline = ThisDrawing.ModelSpace.AddPolyline(coordArr)
     oSset.Delete
     Set oSset = Nothing
End Sub

~'J'~

Re: Метод Select объекта SelectionSets, порядок выделения

Fatty, спасибо, да линии всегда вертикальные. Я написал тоже сортировку массива, правда не так универсально :)
Но

вторую задачу, стоящую передо мной, а именно — вычисления расстояниями между линиями, становится не так-то просто решить, если порядок создания не слева направо или наоборот.

как быть с этим?
Под рукой нет кода, который работает, если линии по-порядку. Чуть позже напишу.

Re: Метод Select объекта SelectionSets, порядок выделения

Sub ris()
    Dim ssetObj As AcadSelectionSet
    Dim returnPnt As Variant
    Dim returnPnt2 As Variant
    Dim ent As Object
    Dim intPoints As Variant
    Dim textObj As AcadText
    Dim insertionPoint(0 To 2) As Double
    Dim i As Integer, j As Integer, n As Integer, k As Integer, s As Integer
    Dim rast As Double, s2 As Double
    Dim height, posx, otm As Double
    returnPnt = ThisDrawing.Utility.GetPoint(, "Ukazgite tochku levee 1 ordinaty: ")
    endPt = ThisDrawing.Utility.GetPoint(, "Ukazgite tochku pravee posledney ordinaty: ")
    endPt(1) = returnPnt(1)
    Set lineObj = ThisDrawing.ModelSpace.AddLine(returnPnt, endPt)
    Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")
    Dim mode As Integer
    mode = acSelectionSetCrossing
    ssetObj.Select mode, returnPnt, endPt
    returnPnt2 = ThisDrawing.Utility.GetPoint(, "Ukazgite tochku raspologeniya texta: ")
    For Each ent In ssetObj
       If j < ssetObj.Count Then intPoints = lineObj.IntersectWith(ent, acExtendNone)
        '__________________________________________________________
       If VarType(intPoints) <> vbEmpty Then
        For i = LBound(intPoints) To UBound(intPoints)
            usl_g(0) = intPoints(0) + 0.8
            If k > LBound(intPoints) Then
            rast = Round((s2 - intPoints(s)) * masht, 1)
            insertionPoint(0) = (posx - intPoints(0)) / 2 + intPoints(0) + 0.9
            insertionPoint(1) = returnPnt(1)
            Set textObj = ThisDrawing.ModelSpace.AddText(Format(rast, "##,##0.0"), insertionPoint, height)
            textObj.Rotation = 1.57079633
            textObj.color = acRed
            textObj.ScaleFactor = 0.6
            textObj.Update
            End If
            i = i + 2
            k = k + 1
            s2 = intPoints(s)
            posx = intPoints(0)
        Next
    End If
       j = j + 1
    Next
End Sub

Re: Метод Select объекта SelectionSets, порядок выделения

> Smog
Ну так тебе только осталось отсортировать
точки пересечения по Х:
ColSort(intPoints, 1) и все
надеюсь сам справишься
~'J'~

Re: Метод Select объекта SelectionSets, порядок выделения

Блин, допер, но там еще одна проблема - еще и вычисляется длинна пересекаемых линий. Но, видемо занесу X, Y и длинну в массив, потом отсортирую, предварительно исправив функцию, а потом опять в цикле построю все, что надо :)
Спасибо за помощь! :)