All Forums
 Категория Visio
 Форум Вопросы и ответы
 Найти точку пересечения линий/окружностей
Author Previous Topic Topic Next 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 функцию. т.е рассекать прямую - потом смотреть координаты получившихся отрезков. в принципе идея неплохая... еще может есть ?
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 09/29/2010 :  15:37:44
Я пару лет назад действовал примерно так же, лучше не придумал.
Создавал копию шейпов, использовал Trim, вычислял точки, а потом откатывал изменения. При этом весь мусор пропадал, а координаты оставались.
Делал не для себя, значит возможно, что в форуме об это написано.
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 09/29/2010 :  15:40:27
Ага :) topic.asp@TOPIC_ID=392.html
Go to Top of Page

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.

на самом деле врет хелп - один последний шейп все таки выделяется.
только это координат то не дает. как получить координаты новых шейпов то ?
Go to Top of Page

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

в итоге имею все фигуры новые. пересечения вот только как сейчас искать ? координаты попарно у всех сравнивать ?
Go to Top of Page

Tumanov

Russia
1198 Posts

Posted - 09/30/2010 :  16:02:01
Относительно старой окружности использовать Shape.SpatialNeighbors с отношением visSpatialContainedIn. При этом в Selection войдут три новых шейпа: две дуги и одна прямая. Прямую среди них можно будет найти по типу строки в геометрии - LineTo в отличие от EllipticalArcTo. Останется только прочитать координаты BeginX,Y и EndX,Y.
Go to Top of Page

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

средняя часть правда быдлокод какой то... не покидает меня мысть что можно написать грамотнее. и заодно находить все точки пересечения если их несколько.
Go to Top of Page

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
Go to Top of Page

bdfy

Belarus
267 Posts

Posted - 10/27/2010 :  17:35:45
имхо привлекать сюда сложную математику с геометрией... несколько нецелесообразно. особенно что каждую фигуру придется описывать своей мат. моделью. а так все работает при любой форме фигур. даже самой дикой зигзагообразной
Go to Top of Page
  Previous Topic Topic Next Topic  
Данный сайт является архивом форума visio.artberg.ru, который был закрыт в связи с переходом на новую платформу visio.getbb.ru
Все материалы доступны только для чтения! Если у вас появились вопросы, или вы хотите что-то обсудить, связанное с Visio, обращайтесь на новый форум!
Архив был создан благодаря совместным усилиям Генадия Туманова @Tumanov (visio.artberg.ru), Александра ака @Surrogate (visio.getbb.ru), и Николая Белых @nbelyh (unmanagedvisio.com)