mnemonix
ॐ मणि पद्मे हूँ
- Сообщения
- 683
- Реакции
- 202
Все, поздно, все по очереди теперь трогать будем, возможно, по нескольку раз в день и обеими руками!два дня меня не трогайте)
Sub srt_nearest()
ActiveDocument.BeginCommandGroup "Sort by Nearest"
'найти нижний
Dim sr As ShapeRange
n = 1
t = 100000000
Set sr = ActiveLayer.Shapes.All 'ActiveSelection.Shapes.All
For Each s In sr
If s.DisplayCurve.Nodes.First.PositionY < t Then
t = s.DisplayCurve.Nodes.First.PositionY
lowest = n
End If
n = n + 1
Next s
n = lowest
While sr.Count > 1
'удалить из перебора текущий
Set s = sr(n)
sr.Remove n
'перебрать шейпы найти ближайший
n = GetNearestShape(s, sr)
'change order
sr(n).OrderBackOf s
Wend
ActiveDocument.EndCommandGroup
End Sub
Function GetNearestShape(s, sr) As Long 'Shape
t = 100000000
sx = s.DisplayCurve.Nodes.First.PositionX
sy = s.DisplayCurve.Nodes.First.PositionY
n = 1
min_n = 0
For Each s1 In sr
s1x = s1.DisplayCurve.Nodes.First.PositionX
s1y = s1.DisplayCurve.Nodes.First.PositionY
dist = ((sx - s1x) * (sx - s1x) + (sy - s1y) * (sy - s1y)) 'можно без корня
If dist < t Then
t = dist
min_n = n
End If
n = n + 1
Next s1
GetNearestShape = min_n 'sr(min_n)
End Function
Возможно этоВ принципе, подобные функции уже существуют в софте для резчиков. В рамках Корела это PlotCalc, e-Cut
Тут стоимость времени станка vs стоимость работы программиста. Жадность побеждает.Коммивояжеры не нужны. Достаточно примитива.
вот на этой строке ошибку выдает.Код:Sub srt_nearest() sr(n).OrderBackOf s End Function
Какая ошибка? У меня на Х7 работает.
PosLine - забыл удалить вызов функции, рисовал тестовую линию хода режущей головки для проверки результата работы
попробуйте в функции GetNearestShape увеличить начальное значение tn там равно нулю в этом цикле.
Sub srt_nearest()
ActiveDocument.BeginCommandGroup "Sort by Nearest"
Dim sr As ShapeRange
n = 1
t = 100000000
Set sr = ActiveSelectionRange
For Each s In sr.Shapes
If s.DisplayCurve.Nodes.First.PositionY < t Then
t = s.DisplayCurve.Nodes.First.PositionY
lowest = n
End If
n = n + 1
Next s
n = lowest
While sr.Shapes.Count > 1 And n > 0
Set s = sr(n)
s.CreateSelection
sr.Remove n
n = GetNearestShape(s, sr.Shapes)
sr(n).OrderBackOf s
Wend
ActiveDocument.EndCommandGroup
End Sub
Function GetNearestShape(s, sr) As Long 'Shape
t = 100000000
sx = s.DisplayCurve.Nodes.First.PositionX
sy = s.DisplayCurve.Nodes.First.PositionY
n = 1
min_n = 0
For Each s1 In sr
s1x = s1.DisplayCurve.Nodes.First.PositionX
s1y = s1.DisplayCurve.Nodes.First.PositionY
dist = ((sx - s1x) * (sx - s1x) + (sy - s1y) * (sy - s1y))
If dist < t Then
t = dist
min_n = n
End If
n = n + 1
Next s1
GetNearestShape = min_n 'sr(min_n)
End Function
Ну это самая грубая оптимизация. На самом деле, следующий уровень будет искать ближайший шейп не по позиции, а именно по ближайшему узлу от текущего узла. И т.д. совершенству предела нет и, повторяю, все придумано за нас.перемещений пустых в три раза меньше!
немного переделал алгоритм для сортировки если объекты стоят немного не ровно (по центрам)Сортируем по верхнему левому углу
Код:Sub PosSortOrder() ActiveDocument.BeginCommandGroup "sort by pos" Set sr = ActiveLayer.Shapes.All sr.Sort "@shape1.Top * 100 - @shape1.Left > @shape2.Top * 100 - @shape2.Left" For Each s In sr.Shapes s.OrderToBack Next s ActiveDocument.EndCommandGroup End Sub
Sub sort_by_pos(Optional shft = 0) 'Lev https://forum.rudtp.ru/threads/avtomatizacija-porjadka-obektov-v-dispetchere.78746/post-1292379
Dim os As ShapeRange
Set os = ActiveSelectionRange
If os.Shapes.Count > 1 Then
ActiveDocument.BeginCommandGroup "sort by pos"
ActiveDocument.Unit = cdrTenthMicron
If shft = 1 Then srt = "<" Else srt = ">"
os.Sort "@shape1.height < @shape2.height"
mn = os.FirstShape.SizeHeight
mx = os.LastShape.SizeHeight
os.Sort "(@shape1.centery.value()/" & mn & ").ToInt * 100 * " & mn & " - @shape1.centerx.value().ToInt" & srt & _
" (@shape2.centery.value()/" & mn & ").ToInt * 100 * " & mn & " - @shape2.centerx.value().ToInt"
For Each s In os.Shapes
s.OrderToBack
Next s
ActiveDocument.EndCommandGroup
End If
End Sub