Author |
Topic |
|
bdfy
Belarus
267 Posts |
Posted - 03/29/2010 : 16:45:10
|
Есть схема - план цеха с нанесенной сетью освещения. точнее много схем разных. см. рис 10, 20
сеть освещения рисуется макросом в принципе и выходит неплохо - но коннекторы от щитка освещения (ЩО, ЩАО на схеме) до светильников визио рисует как попало. а нужно аккуратно по стенам/тросам. помещения определены как специальные смарт шейпы box'ы. тросы - тоже как шейпы. щитки освещения - тоже спец. шейпы.
необходимо растащить коннекторы по стенам/тросам с минимальным количеством пересечений. как на рис. 20_0 поставить выключатели в помещениях и протянуть к ним проводку. вот тут незадача ибо дверные проемы определены не всегда однозначно. а ставятся они рядом с дверями.
пример файлика прилагаю в архиве 10test. там же и все скриншоты. http://rapidshare.com/files/369588617/___________________.rar.html
вот и думаю - реально ли эту работу автоматизировать ? ибо стоит задача либо платить людям за эту тупую механическую работу либо заплатить программисту за универсальное решение... и я бы предпочел второй вариант. ибо у меня идеи закончились (
|
|
Tumanov
Russia
1198 Posts |
Posted - 03/30/2010 : 04:50:01
|
1. А что служит исходными данными для макроса, который сейчас рисует сеть освещения? 2. Вообще без ручной работы едва ли получится. Будут, например, случаи, когда дверей две и надо указать, у какой из них выключатель ставить. Логично было бы человеку как-то "мазнуть", наметить путь, а макрос красиво уложил бы все в намеченный след. |
|
|
bdfy
Belarus
267 Posts |
Posted - 03/30/2010 : 22:45:19
|
quote: 1. А что служит исходными данными для макроса, который сейчас рисует сеть освещения?
схема вручную размечается прямоугольниками задающими границы помещений. щитки ЩО ЩАО выставляются руками. светильники "выход" тоже руками. потом на основании размеров помещений и ряда других свойств по заданной методике идет расчет и выбор светильников. развешиваются светильники, тянутся связи к одной точке щитка ЩО/ЩАО. потом макрос сортирует присоединения на щитке - но даже здесь алгоритм толковый не выходит - все равно бывает некорректная сортировка.
quote: 2. Вообще без ручной работы едва ли получится. Будут, например, случаи, когда дверей две и надо указать, у какой из них выключатель ставить. Логично было бы человеку как-то "мазнуть", наметить путь, а макрос красиво уложил бы все в намеченный след.
насчет дверей это просто ) если две - лепить к примеру к любой ) "Логично было бы человеку как-то "мазнуть", наметить путь" вот это совсем неясно. читал вот про path find алгоритмы с учетом "весов" квадратов... в игрушках используется. если считать участки сетки близкие к стене-тросу участками с меньшим весом... может чего и вышло. но реализацию не представляю пока. |
|
|
Tumanov
Russia
1198 Posts |
Posted - 03/31/2010 : 16:00:14
|
quote: "Логично было бы человеку как-то "мазнуть", наметить путь" вот это совсем неясно.
Это я подумал, нельзя ли что-то выжать из перекрытия шейпов... Например, толстой ломаной грубо наносим желательный путь, некий виртуальный кабельный канал. Потом вычисляем стены, тросы, дверные проемы, светильники (выводы), которые он накрыл (или пересек), и имеем информацию, что надо соединять и по рядом с какими шейпами вести соединения. То есть грубо "мазнули", нажали кнопку, получили уложенные провода. Но это пока голая идея, поэкспериментировать надо... |
|
|
bdfy
Belarus
267 Posts |
Posted - 04/01/2010 : 21:43:08
|
вот макрос сортировки который сейчас использую. и тот далек от совершенства ((
Public Function ConnectedShapes(ByVal Sh As Visio.Shape)
Dim Passive() As Visio.Shape
Dim Active() As Visio.Shape
'Set sh = ActiveWindow.Selection.Item(1) 'выделенный шейп
'Активные связи 2D-шейпа
If Sh.Connects.Count > 0 Then 'условие наличия активных связей
For i = 1 To Sh.Connects.Count 'цикл перебора всех активных связей
ReDim Preserve Active(i)
Set Active(i - 1) = Sh.Connects(i).ToSheet 'активные связи (к чему приклеен)
' Debug.Print "active " & Active(I - 1).Name
Next
End If
'Пассивные связи 2D-шейпа
If Sh.FromConnects.Count > 0 Then 'условие наличия пассивных связей
For i = 1 To Sh.FromConnects.Count 'цикл перебора всех пассивных связей
ReDim Preserve Passive(i)
Set Passive(i - 1) = Sh.FromConnects(i).FromSheet 'пассивные связи (какие шейпы приклеены к выделенному)
' Debug.Print "passive " & Passive(I - 1).Name
Next
End If
ConnectedShapes = Array(Active, Passive)
End Function
Sub сортировать_присоединения()
dx_con = 0
For Each vid In Array("ЩО", "ЩАО")
Set sho = найти_шкаф(vid) 'находим щит освещения на схеме
ar = ConnectedShapes(sho)
Active = ar(0)
Passive = ar(1)
Debug.Print "щиток " & shape0 & " " & имеет & UBound(Passive) & " присоедениний"
Dim svet() As Variant
Dim y() As Variant
Dim room() As Variant
Dim num() As Variant
Dim dx(), dy(), atan(), qvadr() As Variant
ReDim svet(UBound(Passive)), y(UBound(Passive)), room(UBound(Passive)), num(UBound(Passive)), _
atan(UBound(Passive)), dx(UBound(Passive)), dy(UBound(Passive)), atan(UBound(Passive)), qvadr(UBound(Passive))
For i = 0 To UBound(Passive) - 1 'Passive присоединения к щитку все пассивные
Set svet(i) = ConnectedShapes(Passive(i))(0)(1)
y(i) = Round(svet(i).Cells("pinY"), 2)
room(i) = Getroom(svet(i))
num(i) = i
'угол от -180 до 180 найдем
dx(i) = svet(i).Cells("pinX") - sho.Cells("pinX")
dy(i) = svet(i).Cells("pinY") - sho.Cells("pinY")
atan(i) = Round(Atn(dy(i) / dx(i)) * 180 / 3.14, 2) - sho.Cells("angle")
If dx(i) < 0 Then
If dy(i) >= 0 Then
atan(i) = atan(i) + 180
ElseIf dy(i) < 0 Then
atan(i) = atan(i) - 180
End If
End If
'против часовой из нижнего левого угла 4-3-2-1
If atan(i) >= -180 And atan(i) <= -90 Then
qvadr(i) = 1
ElseIf atan(i) > -90 And atan(i) <= 0 Then
qvadr(i) = 2
ElseIf atan(i) > 0 And atan(i) <= 90 Then
qvadr(i) = 3
ElseIf atan(i) > 90 And atan(i) <= 180 Then
qvadr(i) = 4
Else
qvadr(i) = 0
End If
Debug.Print svet(i).NameU & " " & dx(i) & " - " & dy(i) & " " & atan(i) & " " & qvadr(i)
' svet(i).Characters.text = CStr(atan(i))
' Debug.Print Passive(i) & " " & svet(i).Name & " " & y(i) & " " & room(i)
Next i
Debug.Print "---------------sort-------------"
For i = 0 To UBound(Passive) - 1
For j = i + 1 To UBound(Passive) - 1
If qvadr(i) > qvadr(j) Then
Set temp = Passive(i)
Set Passive(i) = Passive(j)
Set Passive(j) = temp
temp = room(i)
room(i) = room(j)
room(j) = temp
temp = atan(i)
atan(i) = atan(j)
atan(j) = temp
temp = num(i)
num(i) = num(j)
num(j) = temp
temp = qvadr(i)
qvadr(i) = qvadr(j)
qvadr(j) = temp
ElseIf qvadr(i) = qvadr(j) Then
If Passive(i).Cells("pinY") - Passive(j).Cells("pinY") > 0.2 Then
Set temp = Passive(i)
Set Passive(i) = Passive(j)
Set Passive(j) = temp
temp = room(i)
room(i) = room(j)
room(j) = temp
temp = num(i)
num(i) = num(j)
num(j) = temp
temp = atan(i)
atan(i) = atan(j)
atan(j) = temp
temp = qvadr(i)
qvadr(i) = qvadr(j)
qvadr(j) = temp
ElseIf Passive(i).Cells("pinY") - Passive(j).Cells("pinY") <= 0.2 Then
If Passive(i).Cells("pinX") > Passive(j).Cells("pinX") Then
Set temp = Passive(i)
Set Passive(i) = Passive(j)
Set Passive(j) = temp
temp = room(i)
room(i) = room(j)
room(j) = temp
temp = num(i)
num(i) = num(j)
num(j) = temp
temp = atan(i)
atan(i) = atan(j)
atan(j) = temp
temp = qvadr(i)
qvadr(i) = qvadr(j)
qvadr(j) = temp
End If
End If
End If
Next j
Next i
delta_x = 1.5
dx_con = 0
dx_con = dx_con + delta_x
If sho.Cells("angle") < -3.14 * 0.95 Or sho.Cells("angle") > 3.14 * 0.95 Then
endI = 0
startI = UBound(Passive) - 1
stepi = -1
Else
startI = 0
endI = UBound(Passive) - 1
stepi = 1
End If
Debug.Print formi
For i = startI To endI Step stepi 'Passive присоединения к щитку все пассивные
Debug.Print Passive(i) & " " & room(i) & " " _
& Round(Passive(i).Cells("pinY"), 1) & " " & Round(Passive(i).Cells("pinX"), 1) _
& " " & qvadr(i) & " " & atan(i)
'место на шейпе ЩО
If stepi = 1 Then sho.Cells("Connections.Y" & num(i) + 1).FormulaU = "=height*" & (i + 1) * (1 / (UBound(Passive) + 1))
If stepi = -1 Then sho.Cells("Connections.Y" & num(i) + 1).FormulaU = "=height*(1-" & (i + 1) * (1 / (UBound(Passive) + 1)) & ")"
' Passive(i).Cells("Geometry1.X3").FormulaU = "=" & dx_con & " mm"
' Passive(i).Cells("Geometry1.X2").FormulaU = "=" & dx_con & " mm"
' dx_con = dx_con + delta_x
Next
ActiveWindow.DeselectAll
ActiveWindow.Select sho, visSelect
Application.ActiveWindow.Selection.Move -0.01, 0#
Application.ActiveWindow.Selection.Move 0.01, 0#
Next vid
Debug.Print "---------------------------------"
End Sub для начала хоть его бы отладить )
quote: Потом вычисляем стены, тросы, дверные проемы, светильники (выводы), которые он накрыл (или пересек)
не ясна идея. есть - границы комнат по ним надо бы вычислить положение дверей. как ? по идее надо пройтись по периметру проверяя "есть прямая ли линия (читай стена) в непосредственно близости". если нет - это дверь. вопрос как выполнить эту проверку ?
Логично было бы человеку как-то "мазнуть", наметить путь, а макрос красиво уложил бы все в намеченный след. на каком основании макрос бы уложил красиво то ? ибо если можно уложить по намеченному руками пути - можно потом попробовать путь вычислить машинно. в принципе при верной сортировке на щитке (см. макрос выше) все ручное укладывание шейпов заключается в смещении буквально двух трех прямых отрезков ближе к стене/другим линиям... вот думаю может в эти ворота сыграть...
|
|
|
bdfy
Belarus
267 Posts |
Posted - 04/02/2010 : 09:35:35
|
все идет к тому что делать все придется руками (( что выливается в несколько человеко суток (( что не нравится в визио - коннектор можно тащить только за сгиб или за середину линии. а можно ли сделать так чтобы прямую коннектора можно было оттянуть в сторону взявшись в любом месте ? |
|
|
Tumanov
Russia
1198 Posts |
Posted - 04/02/2010 : 16:21:14
|
quote: все идет к тому что делать все придется руками
Ну, как-то слишком пессимистично... Я, в общем-то, давно собирался поисследовать возможности Visio в графической навигации, да все повода не было. Вот может как раз случай представился :) Глядишь, что-нибудь и получится. Смотрю, из инструментов есть функция шейп-листа, позволяющая определить точку пересечения прямых. =INTERSECTY(PinX,PinY,Angle,Sheet.2!PinX,Sheet.2!PinY,Sheet.2!Angle) Может помочь для прогнозирования возможных точек пересечения. Это если вместо коннекторов самому строить соединительные линии. Есть возможность вычислить особенности взаимного расположения шейпов, например, факт пересечения. В том числе и коннекторов. Debug.Print sh1.SpatialRelation(sh2, 0.1, 0) при пересечении коннекторов возвращает 8, для непересекающихся - 0. То есть наблюдая реальную ситуацию, можно найти пересекающиеся коннекторы. Затем, переключая один из концов коннектора, добиться отсутствия перемещений. В определении положения дверей скорее всего может помочь имеющийся шейп типа дверного проема (название не помню). Выглядит, как дырка в стене, но на самом деле является шейпом. Нужно только использовать их при рисовании, если это допускает технология. С коннекторами, помнится, тоже был момент, когда не удавалось добиться нужного поведения. Так я после проводки коннекторов превращал их макросом в обычные ломаные (с той же геометрией) и потом уже перетаскивал нужные куски. То есть, можно еще поискать варианты :) А предварительная наметка пути, как мне кажется, может помочь вот в чем. Если просто взять пару соединений (четыре точки в помещении), то в зависимости от того, по какой стене идти (по часовой или против), коннекторы либо перекрестятся, либо нет. Поэтому путь важен. Хочу извлечь из него последовательность шейпов, мимо которых нужно пройти. А потом последовательно от одного шейпа до другого (рядом) тянуть свои связи. Можно, наверно, и без предварительной наметки обойтись, но тогда придется путь вычислять алгоритмически. А значит, отрабатывать для этого еще один алгоритм, может быть не очень простой. Короче, результаты пока прогнозировать рано, но в целом задача видится разрешимой. |
|
|
bdfy
Belarus
267 Posts |
Posted - 04/02/2010 : 17:24:28
|
quote: Ну, как-то слишком пессимистично...
дедлайн просто числа 15-20 - а схем сейчас уже под 50,а будет больше ( пока я задачу вижу из 3 пунктов - разместить выключатели (это я примерно представляю еще как сделать). только вот использовать какие то шейпы нельзя для дверей - схемы все были изначально рисованы в автокаде, потом конвертированы. сейчас их править таким образом достаточно сложно. - отсортировать соединения на самом щитке ЩО/ЩАО. наработки есть - но работает не всегда корректно. - провести проводники по тросам/стенам. вот это наиболее сложная и трудоемкая часть. я сегодня чертежей пять сделал - убил наверное часа полтора и удовольствия не получил никакого (( quote: А предварительная наметка пути, как мне кажется, может помочь вот в чем. Если просто взять пару соединений (четыре точки в помещении), то в зависимости от того, по какой стене идти (по часовой или против), коннекторы либо перекрестятся, либо нет. Поэтому путь важен. Хочу извлечь из него последовательность шейпов, мимо которых нужно пройти. А потом последовательно от одного шейпа до другого (рядом) тянуть свои связи.
а если просто засечь ближайшие стены,тросы и уже уложенные коннекторы и просто максимально "прижать" коннектор к ним ? только как это запускаться то хотя бы будет ? "предварительный путь" можно словить через Document_ShapeAdded предположим, а как указать какой из коннекторов по нему ложить ? если просто по порядку, то порядок еще надо определить... quote: С коннекторами, помнится, тоже был момент, когда не удавалось добиться нужного поведения. Так я после проводки коннекторов превращал их макросом в обычные ломаные (с той же геометрией) и потом уже перетаскивал нужные куски.
у коннектора есть свойство line routing - reroute - never если верить справке - это автоматические смещения прекращает.
в любом случае еще недельку в принципе можно подергатся ) все же ведь "лучше день потерять... потом за пять минут долететь". могу залить на мыло проект целиком если это поможет. все файлы метров в 10 уложатся думаю. мыло только подскажите )
|
|
|
bdfy
Belarus
267 Posts |
Posted - 04/02/2010 : 17:28:34
|
была еще идея закрыть "условно непроходимые зоны", т.е центральную часть помещений большим шейпом со свойством route around - тогда по идее визио обязан был бы просчитать вокруг него пути, но не выходит из этого ничего пока (( бывает дейсвительно более менее корректно отталкивает коннекторы - потом сам улетает... как то странно эта фича работает. .... а ведь даже работает )) даже почти похоже на правду получается. только надо шейпами фейковыми закрыть еще и просветы между комнатами - а то коннекторы уходят туда. .... вот что получилось если их закрыть ручками: http://rapidshare.com/files/371217425/__________________10.rar.html вопрос как закрыть подобными псевдношейпами все промежутки между комнатами ? и как отсортировать шейпы внутри "каналов" между шейпами. хотя может это и тупиковое решение... |
Edited by - bdfy on 04/02/2010 18:29:45 |
|
|
Tumanov
Russia
1198 Posts |
Posted - 04/04/2010 : 12:08:50
|
1. Да, сроки слишком жесткие. Я в них (на фоне других работ) точно не уложусь :( Разве что в следующий раз когда-нибудь пригодится... 2. Сортировка коннекторов. Сейчас видится ряд функций, которые могли бы помочь в работе: 2.1. Выбрать коннекторы, касающиеся заданного коннектора (например, селектированного). Функция работает на основе SpatialNeighbors. Причем за счет параметра Tolerance можно ловить как непосредственно касающиеся (и пересекающие), так и близко проходящие. 2.2. Функция перестановки двух соседних коннекторов. На том участке, где линии коннекторов идут рядом, пытается обвести второй коннектор вокруг первого. В зависимости от направления поворота первого коннектора в очередной точке излома смещает сегмент второго коннектора в нужную сторону. Результат контролируется функцией 2.1. Если коннекторы все равно касаются, значит меняются местами их подключения к ЩО и операция повторяется. Сегмент коннектора вроде тянется без проблем за две точки. Типа, вот так: sh1.Cells("Geometry1.X2") = sh1.Cells("Geometry1.X2") + 0.2 sh1.Cells("Geometry1.X3") = sh1.Cells("Geometry1.X3") + 0.2 Скорее всего по ходу дела тут еще несколько мелких вспомогательных функций сформируется. Типа вычисления направления поворота, поиска близлежащих сегментов двух коннекторов и т.д. 3. Идея закрыть "непроходимые зоны" вроде хорошая. Для закрытия промежутков между помещениями можно ведь и просто слепить шейп, пользуясь операциями Subtract и Union. Если еще и стены в нескольких цехах совпадают, то такой шейп можно применять на нескольких листах. Или слегка изменять при необходимости. А если все-таки не получится, можно попробовать провести несколько направляющих и пытаться тянуться к ним. В принципе, они обсчитываются, как обычные шейпы. Удается определить расстояние до них и т.д. quote: могу залить на мыло проект целиком если это поможет. все файлы метров в 10 уложатся думаю. мыло только подскажите
С учетом того, что я в срок задачу не решу, вроде как и смысла нет заливать. А если с учетом перспективы, то реальные данные никогда не помешают. Больше особенностей можно учесть. Так что, смотрите сами. почта ttt@post.rzn.ru В несколько Мб письма вроде проходили. |
|
|
bdfy
Belarus
267 Posts |
Posted - 04/04/2010 : 15:53:47
|
сроки уже не горят - хлопчыка раскидывать это дело вручную я уже нанял , но нормально автоматическое решение все равно интересно. ибо хлопчыки девайс в общем случае менее надежный и менее производительный чем программа ) да и задачи подобные мне попадаются периодически. quote: 3. Идея закрыть "непроходимые зоны" вроде хорошая. Для закрытия промежутков между помещениями можно ведь и просто слепить шейп, пользуясь операциями Subtract и Union. Если еще и стены в нескольких цехах совпадают, то такой шейп можно применять на нескольких листах.
все таки решение ищется автоматическое ) внутри комнат заполнить пространство легко, вот между ними сложнее - если комнаты вложены одна в другую - да субстракт поможет. а если просто рядом стоят с просветами ? как эти просветы посчитать и заполнить ? а так если фигуры эти корректно поставить - остается только отсортировать коннекторы в "коридорах" образаванных этими шейпами. тут правда опять стоит вопрос как... quote: Сегмент коннектора вроде тянется без проблем за две точки. Типа, вот так:
вообще говоря я спрашивал можно ли при ручном редактировании коннектор тянуть за точки отличные от перегибов и середин отрезков.
на прожект ссылка на почте. будет время, скажите пару добрых ) не уверен правда что разберетесь в этом комбайне ) |
|
|
|
Topic |
|
|
|