| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как определить, лежит ли точка внутри контура

Как определить, лежит ли точка внутри контура

Ответ
Поиск в этой теме
Непрочитано 02.12.2010, 21:36
Как определить, лежит ли точка внутри контура
swkx
 
Регистрация: 22.01.2010
Сообщений: 311

Контур - замкнутая 2D-полилиния неправильной формы.
Как программно определить, лежит ли точка с координатами X и Y внутри контура ?
Нужна не готовая функция, а просто подходы к решению.
А может уже есть стандартная из серии VLA-....?
Просмотров: 26073
 
Непрочитано 01.06.2016, 14:34
#61
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,550


Цитата:
Сообщение от VVA Посмотреть сообщение
В таком случае синий и зеленый квадрат будут считаться не в контуре. Это правильно?
Да, вопрос именно в этом, что мы понимаем под словом "внутри" и "снаружи". Как вариант можно рассмотреть игнор пограничных точек, но тогда нужно проверять принцип погрраничности, а затраты на это действие зависят от многоугольника границы
gomer вне форума  
 
Непрочитано 01.06.2016, 18:41
#62
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,906
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Если немного переписать функцию, то можно анализировать все варианты
Код:
[Выделить все]
 
 
(defun C:TEST2 ( / str)
  (SSSETFIRST nil nil)
  (setq Boundary1 (car (entsel "\nВыберите контур (полилиния): ")))
  (SSSETFIRST nil (ssadd Boundary1))
  (setq rect1 (car (entsel "\nВыберите прямоугольник (полилиния): ")))
  (SSSETFIRST nil (ssadd Boundary1 (ssadd rect1)))
  (setq Boundary (coords Boundary1))
  (setq rect (coords rect1))
  (setq ret
         (mapcar 'mip_IsPointInside1
                 rect
                 (mapcar '(lambda (x) Boundary) rect)
         ) ;_ end of mapcar
  ) ;_ end of setq
  (cond
    ((equal (apply '+ ret) 4 1e-3)(setq str "Прямоугольник целиком в контуре"))
    ((equal (apply '+ ret) 3.1 1e-3)(setq str "Прямоугольник 3 точки в контуре, одна на границе"))
    ((equal (apply '+ ret) 2.2 1e-3)(setq str "Прямоугольник 2 точки в контуре, ДВЕ на границе"))
    ((equal (apply '+ ret) 1.3 1e-3)(setq str "Прямоугольник 1 точка в контуре, ТРИ на границе"))
    ((equal (apply '+ ret) 0.4 1e-3)(setq str "Прямоугольник ЧЕТЫРЕ точки на границе"))
    ((equal (apply '+ ret) 3 1e-3)(setq str "Прямоугольник 3 точки в контуре, одна за пределами"))
    ((equal (apply '+ ret) 2 1e-3)(setq str "Прямоугольник 2 точки в контуре, ДВЕ за пределами"))
    ((equal (apply '+ ret) 1 1e-3)(setq str "Прямоугольник 1 точка в контуре, ТРИ за пределами"))
    ((equal (apply '+ ret) 0.1 1e-3)(setq str "Прямоугольник 1 точка на границе, ТРИ за пределами"))
    ((equal (apply '+ ret) 0.2 1e-3)(setq str "Прямоугольник 2 точки на границе, ДВЕ за пределами"))
    ((equal (apply '+ ret) 0.3 1e-3)(setq str "Прямоугольник 3 точки на границе, ОДНА за пределами"))
    ((zerop (apply '+ ret))(setq str "Прямоугольник за пределами"))
    (t (setq str "Не опознано"))
  ) ;_ end of cond
  (princ)
  (vla-sendcommand (vlax-get-property(vlax-get-acad-object) 'activedocument) (strcat "(alert " "\"" str "\"" ")\n"))
) ;_ end of defun
;* алгоритм взят на http://algolist.manual.ru/maths/geom/belong/poly2d.php
;* На основе vk_IsPointInside
;* Опубликовано  http://www.caduser.ru/forum/index.php...&TID=36191
;               http://forum.dwg.ru/showthread.php?p=1538162#post1538162
;* Boundary - список нормализованных [т.е. только либо (X Y) либо (X Y Z)] точек
(defun mip_IsPointInside1 (Point Boundary / FarPoint)
  ;_Проверяет Boundary на условие car и last одна и та же точка
  (if (not (equal (car Boundary)(last Boundary) 1e-6))
    (setq Boundary (append Boundary (list(car Boundary)))))
  (setq FarPoint (cons (+ (apply 'max (mapcar 'car Boundary)) 1.0)
                       (list(+ (apply 'max (mapcar 'cadr Boundary)) 1.0 (cadr Point)))
                 ) ;_ end of cons
  ) ;_ end of setq
  (cond
    ((vl-some (function (lambda (x)   ;_На границе
                         x
                       ) ;_ end of lambda
             ) ;_ end of function
             (mapcar
               (function (lambda (p1 p2)
                           (equal (+ (distance Point p1)
                                     (distance Point p2)
                                  ) ;_ end of +
                                  (distance p1 p2)
                                  1e-3
                           ) ;_ end of equal
                         ) ;_ end of lambda
               ) ;_ end of function
               Boundary
               (cdr Boundary)
             ) ;_ end of mapcar
    ) ;_ end of vl-some
     (setq ret 0.1)
     )
    ((not    ;_Внутри
      (zerop
        (rem
          (length
            (vl-remove
              nil
              (mapcar
                (function (lambda (p1 p2) (inters Point FarPoint p1 p2))
                ) ;_ end of function
                Boundary
                (cdr Boundary)
              ) ;_ end of mapcar
            ) ;_ end of vl-remove
          ) ;_ end of length
          2
        ) ;_ end of rem
      ) ;_ end of zerop
    ) ;_ end of not
     (setq ret 1)
     )
    (t (setq ret 0)) ;_Снаружи
  ) ;_ end of cond
) ;_ end of defun
(defun coords (en)
  (mapcar 'cdr
	  (vl-remove-if-not
	    (function (lambda (x) (= 10 (car x))))
	    (entget en)
	  )
  )
)
----- добавлено через ~15 ч. -----
Единственное улучшение - возвращать можно целые числа:
0 - не в контуре
100 - в контуре
1 - на границе
И сравнивать целые числа
400 - 4 точти внутри контура
300 - 3 точки внутри, одна снаружи
301 - 3 точки внутри, одна на границе
и т.д.
Вложения
Тип файла: dwg
DWG 2007
test.dwg (67.0 Кб, 13 просмотров)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 27.04.2022, 14:33
#63
АлексЮстасу

топограф, технолог
 
Блог
 
Регистрация: 24.05.2009
Москва
Сообщений: 2,963


Хорошо действует Принадлежность точки криволинейному контуру VVA.
Действует для линейных объектов, образующих контуры:
Код:
[Выделить все]
 ("AcDb2dPolyline" "AcDbPolyline" "AcDb3dPolyline"
  "AcDbCircle" "AcDbArc" "AcDbEllipse"
  "AcDbSpline" "AcDbLine")
Но не для площадных, которым такая функция нужна не меньше, и которые линейные контуры косвенно представляют.
Для штриховок, регионов, мультиполигонов. В т.ч. для площадных объектов с отверстиями в них.
Можно ли расширить эту функцию для площадных объектов?
__________________
количество моих сообщений не говорит о знании Автокада
АлексЮстасу на форуме  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как определить, лежит ли точка внутри контура

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Справка по форуму Admin FAQ: Часто задаваемые вопросы 13 04.03.2014 11:12
У меня вопрос по Ansys, как правильно оформить контакт с жестким телом? Цветочек ANSYS 17 10.11.2013 09:41
Проектирование человека. FOXAL Разное 283 25.05.2010 09:52
Вопрос: Интерактивное построение полилинии внутри lisp-программы Tonic LISP 5 26.04.2010 15:50
Как определить, что точка за пределами видимой области? VBA den001 Программирование 6 20.01.2007 20:48