Author |
Topic |
|
bdfy
Belarus
267 Posts |
Posted - 09/29/2010 : 03:01:44
|
Необходимо выполнить ряд графических расчетов. Расчет упирается в необходимость находить координаты точек пересечения прямых и прямой с окружностью. Сделать это чисто аналитически сложно ( для прямых еще представляю - с окружностью плохо ). Как решить подобную задачу ? |
|
bdfy
Belarus
267 Posts |
Posted - 09/29/2010 : 14:56:47
|
все что нашел в сети по сути http://msdn.itags.org/microsoft-visio/20432/ предлагают использовать trim функцию. т.е рассекать прямую - потом смотреть координаты получившихся отрезков. в принципе идея неплохая... еще может есть ? |
|
|
Tumanov
Russia
1198 Posts |
Posted - 09/29/2010 : 15:37:44
|
Я пару лет назад действовал примерно так же, лучше не придумал. Создавал копию шейпов, использовал Trim, вычислял точки, а потом откатывал изменения. При этом весь мусор пропадал, а координаты оставались. Делал не для себя, значит возможно, что в форуме об это написано. |
|
|
Tumanov
Russia
1198 Posts |
|
bdfy
Belarus
267 Posts |
Posted - 09/30/2010 : 11:52:00
|
попробовал реализовать. не совсем получилось. Предположим есть прямая A0F2 (A0 начало F2 конец), есть окружность okr причем они не пересекаются. надо A0F2 продлить. и найти точку пересечения с окружностью со стороны F2 quote: UndoScopeID1 = Application.BeginUndoScope("temp") ActiveWindow.DeselectAll A0F2.Cells("width") = 10 * A0F2.Cells("width")
ActiveWindow.Select A0F2, visSelect ActiveWindow.Select okr, visSelect ActiveWindow.Selection.Trim Set temp = ActiveWindow.Selection(1) x = temp.Cells("endX") y = temp.Cells("endY") Application.EndUndoScope UndoScopeID1, True 'false все отменит
Set A2 = точка(x, y, "A_2") 'ставим точку в координатах
проблема в чем. Отрезок окружность пересечет дважды. соотв. разобьется на три отрезка. надо бы найти средний - будут координаты trim quote: The original shapes are deleted and no shapes are selected when the operation is complete.
Fragment quote: The original shapes are deleted and there aren't any shapes selected when the operation is complete.
на самом деле врет хелп - один последний шейп все таки выделяется. только это координат то не дает. как получить координаты новых шейпов то ? |
|
|
bdfy
Belarus
267 Posts |
Posted - 09/30/2010 : 13:34:31
|
еще чуть подумал
UndoScopeID1 = Application.BeginUndoScope("temp")
ActiveWindow.DeselectAll
A0F2.Cells("width") = 10 * A0F2.Cells("width") 'extend 10 times to get 100% intersection
ActiveWindow.Select A0F2, visSelect
ActiveWindow.Select okr, visSelect
shapeCount0 = ActivePage.Shapes.Count
ActiveWindow.Selection.Trim
shapeCount = ActivePage.Shapes.Count
Debug.Print shapeCount - shapeCount0
ActiveWindow.DeselectAll
For i = shapeCount0 - 1 To shapeCount
Set vsoShape1 = ActivePage.Shapes(i)
Debug.Print vsoShape1.name
ActiveWindow.Select vsoShape1, visSelect
Next в итоге имею все фигуры новые. пересечения вот только как сейчас искать ? координаты попарно у всех сравнивать ? |
|
|
Tumanov
Russia
1198 Posts |
Posted - 09/30/2010 : 16:02:01
|
Относительно старой окружности использовать Shape.SpatialNeighbors с отношением visSpatialContainedIn. При этом в Selection войдут три новых шейпа: две дуги и одна прямая. Прямую среди них можно будет найти по типу строки в геометрии - LineTo в отличие от EllipticalArcTo. Останется только прочитать координаты BeginX,Y и EndX,Y. |
|
|
bdfy
Belarus
267 Posts |
Posted - 10/03/2010 : 15:03:01
|
вот что получилось. ищет первую точку пересечения в направлении конца отрезка fig1
Function пересечение(ByVal fig1 As Object, ByVal fig2 As Object, Optional ByVal удлинять As Boolean = True) As Variant
x = 0
y = 0
UndoScopeID1 = Application.BeginUndoScope("temp")
ActiveWindow.DeselectAll
If удлинять Then
ang = fig1.Cells("angle")
fig1.Cells("endX") = fig1.Cells("endX") + 100 * Cos(ang)
fig1.Cells("endY") = fig1.Cells("endY") + 100 * Sin(ang)
End If
ActiveWindow.Select fig1, visSelect
ActiveWindow.Select fig2, visSelect
shapeCount0 = ActivePage.Shapes.Count
ActiveWindow.Selection.Trim
shapeCount = ActivePage.Shapes.Count
'Debug.Print "*******************"
'Debug.Print shapeCount - shapeCount0 + 2
ActiveWindow.DeselectAll
k = 0
Dim shsi() As Variant
Dim sh0, sh1 As Visio.Shape
For i = shapeCount0 - 1 To shapeCount 'две стартовые удаляются - остальные новые
Set sh1 = ActivePage.Shapes(i)
geom_c = sh1.GeometryCount 'число секций
geom1_r = sh1.RowCount(visSectionFirstComponent) 'рядов в секции
h = Round(sh1.Cells("height").Result("mm"), 1) 'рядов в секции
' Debug.Print h
If h = 0 Then
ReDim Preserve shsi(k + 1)
shsi(k) = i
' Debug.Print shsi(k)
k = k + 1
ActiveWindow.Select sh1, visSelect
End If
Next
Set sh0 = ActivePage.Shapes(shsi(0))
Debug.Print k
For i = 1 To k - 1
' Debug.Print shsi(k)
Set sh1 = ActivePage.Shapes(shsi(i))
If (sh0.Cells("beginX") = sh1.Cells("beginX") And _
sh0.Cells("beginY") = sh1.Cells("beginY")) Then
x = sh0.Cells("beginX")
y = sh0.Cells("beginY")
Exit For
End If
If (sh0.Cells("beginX") = sh1.Cells("endX") And _
sh0.Cells("beginY") = sh1.Cells("endY")) Then
x = sh0.Cells("beginX")
y = sh0.Cells("beginY")
Exit For
End If
If (sh0.Cells("endX") = sh1.Cells("beginX") And _
sh0.Cells("endY") = sh1.Cells("beginY")) Then
x = sh0.Cells("beginX")
y = sh0.Cells("beginY")
Exit For
End If
If (sh0.Cells("endX") = sh1.Cells("endX") And _
sh0.Cells("endY") = sh1.Cells("endY")) Then
x = sh0.Cells("beginX")
y = sh0.Cells("beginY")
Exit For
End If
'ActiveWindow.Select sh1, visSelect
Next
Application.EndUndoScope UndoScopeID1, False
'Debug.Print x & "-" & y
пересечение = Array(x, y)
End Function средняя часть правда быдлокод какой то... не покидает меня мысть что можно написать грамотнее. и заодно находить все точки пересечения если их несколько. |
|
|
GDK
Russia
90 Posts |
Posted - 10/27/2010 : 10:04:32
|
Для прямых совсем просто, для окружности может чуть сложнее, а может нет. Для прямых просто решается система уравнений (каждая прямая имеет ур-е). Окружности тоже можно описать уравнением. Затем программа должна проверить принадлежит ли полученная точка отрезку, если нет, то отрезки не пересекаются, если система не имеет решений, то прямые параллельны. Систему удобно решать и проч. с помощью матрицы.
Ур-е прямой для отрезков - составляем систему Ax(нач)+By(нач)+C=0 Ax(кон)+By(кон)+C=0 , получаем коэффициенты A,B,C, для второго отрезка аналогично. Затем решаем систему полученный ур-й и находим x и y - это коорд. точки пересечения. Решение с помощью матрицы лучше вынести в отдельную процедуру, она используется неоднократно.
|
Edited by - GDK on 10/27/2010 10:23:54 |
|
|
bdfy
Belarus
267 Posts |
Posted - 10/27/2010 : 17:35:45
|
имхо привлекать сюда сложную математику с геометрией... несколько нецелесообразно. особенно что каждую фигуру придется описывать своей мат. моделью. а так все работает при любой форме фигур. даже самой дикой зигзагообразной |
|
|
|
Topic |
|