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

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

Как определить, персекаются ли две фигуры

Ответ
Поиск в этой теме
Непрочитано 23.07.2012, 13:34 #1
Как определить, персекаются ли две фигуры
swkx
 
Регистрация: 22.01.2010
Сообщений: 311

День добрый.

Подскажите самый простой метод. Фигуры - всегда замкнутые плоские полилинии с непересекающимся контуром.
Признак пересекающихся фигур - одна (или несколько) точек одной фигуры лежит внутри контура (не на границе!) другой.
Частичное совпадение сторон или частей сторон пересечением не считается.

Возможно, есть какие-нибудь готовые функции применительно к целым полилиниям ?
Или нужно задачу свести к определению принадлежности точки контуру, которое тут уже обсуждалось: VVA - трассировка луча и т.п.
Просмотров: 4128
 
Непрочитано 23.07.2012, 14:02
#2
VH_


 
Регистрация: 20.05.2010
Сообщений: 26


Площадь фигуры, полученной объединением данных фигур, меньше суммы площадей данных фигур.
VH_ вне форума  
 
Автор темы   Непрочитано 23.07.2012, 14:06
#3
swkx


 
Регистрация: 22.01.2010
Сообщений: 311


В теории оно конечно так. Но это же плоские полилинии, их объединять нельзя, насколько мне помнится.
swkx вне форума  
 
Непрочитано 23.07.2012, 14:36
#4
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 575


Цитата:
Сообщение от swkx Посмотреть сообщение
Возможно, есть какие-нибудь готовые функции применительно к целым полилиниям ?
swkx, а что vla-IntersectWith не подойдет?
Ну с небольшими доработками для отслеживания
Цитата:
Сообщение от swkx Посмотреть сообщение
Частичное совпадение сторон или частей сторон пересечением не считается.
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 23.07.2012, 14:47
#5
swkx


 
Регистрация: 22.01.2010
Сообщений: 311


Может и подойдёт, сейчас попробую.
Не знал про такой(...

Похоже, вполне подойдет
TararykovDG, спасибо!

Последний раз редактировалось swkx, 23.07.2012 в 14:53.
swkx вне форума  
 
Непрочитано 24.07.2012, 11:38
#6
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


я делал как-то так:
Код:
[Выделить все]
 


(defun C:inpr (/)


  (inpr	(SL_GET_FOUR_BY_BB_ (car (entsel)))
	(SL_GET_FOUR_BY_BB_ (car (entsel)))
  )
)

(defun inpr (sl_1pr	  sl_2pr       /	    sl_inspt_
	     sl_inspt_n	  sl_temp_     sl_temppr    sl_temp_list_
	    )

;;;(setq sl_1pr '((1992.54 1123.41) (1992.54 1127.65) (1994.39 1127.65) (1994.39 1123.41))) 
;;;(setq sl_2pr '((1994.51 1123.41) (1994.51 1127.36) (1996.48 1127.36) (1996.48 1123.41)))

					;  Функция нахождения накладываются или нет два прямоугольника с параллельными гранями (углы прямые и грани одинаково ориентированы)
					; Возвращаемое значение - 1 если накладываются, nil если не накладываются
					; Аргументы
					; sl_1pr - список точек вида '((206.06 101.357) (244.368 101.357) (244.368 85.3698) (206.06 85.3698))
					; sl_1pr - список точек вида '((230.848 94.155) (263.875 94.155) (263.875 78.9937) (230.848 78.9937))

  
;;;					 (princ "\n первый прямоугольник")
;;;					 (princ sl_1pr)
;;;					 (princ "\n второй прямоугольник")
;;;					 (princ sl_2pr)
  (if (and sl_1pr sl_2pr)

    (progn
      (setq sl_1pr (sl_round_real_ sl_1pr 4))
      (setq sl_2pr (sl_round_real_ sl_2pr 4))

      (if (equal sl_1pr sl_2pr)
	1.
	(progn
	  (setq
	    sl_inspt_ (mapcar (function	(lambda	(x)
					  (SL_ISPOINTINSIDE x sl_1pr)
					)
			      )
			      sl_2pr
		      )
	  )

	 (setq sl_inspt_  (cons (SL_ISPOINTINSIDE

				  (list 
				  (/ (+ (car (car sl_2pr))
				  (car (caddr sl_2pr))) 2.)
				  (/ (+ (cadr (car sl_2pr))
				  (cadr (caddr sl_2pr))) 2.)
				  )
				  			  
				  
				  sl_1pr) sl_inspt_))
	  

	  (setq sl_inspt_n (sl_remove_nil_ sl_inspt_))

	  (if (equal sl_inspt_n nil)
	    (progn
	      (setq
		sl_temppr sl_1pr
		sl_1pr sl_2pr
		sl_2pr sl_temppr
	      )
	      (setq sl_inspt_
		     (mapcar (function (lambda (x)
					 (SL_ISPOINTINSIDE x sl_1pr)
				       )
			     )
			     sl_2pr
		     )
	      )

	      (setq sl_inspt_  (cons (SL_ISPOINTINSIDE

				  (list 
				  (/ (+ (car (car sl_2pr))
				  (car (caddr sl_2pr))) 2.)
				  (/ (+ (cadr (car sl_2pr))
				  (cadr (caddr sl_2pr))) 2.)
				  )
				  			  
				  
				  sl_1pr) sl_inspt_))

	      (setq sl_inspt_n (sl_remove_nil_ sl_inspt_))

	    )
	  )
	  (if sl_inspt_n
	    1.
	    nil
	  )
	)
      )
    )
    nil
  )					; if

)

(defun sl_IsPointInside
		(Point Boundary / FarPoint Check)
	  


 ;_Проверяет Boundary на условие car и last одна и та же точка 

					;* алгоритм взят на http://algolist.manual.ru/maths/geom/belong/poly2d.php 
					;* На основе vk_IsPointInside 
					;* Опубликовано 
					;* http://www.caduser.ru/forum/index.php?PAGE_NAME=message&FID=23&TID=36191&MID=205580&sessid=79096aca9605acaa6da486d593128e41&order=&FORUM_ID=23 
					;* Boundary — список нормализованных [т.е. только либо (X Y) либо (X Y Z)] точек 
					;* Point - проверяемая точка 
	    (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)
	      (cdr Point)
	     ) ;_ end of cons 
	    ) ;_ end of setq 
	    (or
	     (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 
	     (vl-some
	      (function (lambda (x) x))
	      (mapcar
	       (function
		(lambda	(p1 p2)
		  (or
		   Check
		   (if
		    (equal
		     (+
		      (distance Point p1)
		      (distance Point p2)
		     ) ;_ end of + 
		     (distance p1 p2)
		     1e-3
		    ) ;_ end of equal 
		    (setq Check T)
		    nil
		   )
		  )
		) ;_ end of lambda 
	       ) ;_ end of function 
	       Boundary
	       (cdr Boundary)

	      ) ;_ end of mapcar 
	     ) ;_ end of vl-some 
	    ) ;_ end of or 
	   )

(defun sl_remove_nil_ (lst /)

  (vl-remove-if
    (function (lambda (x)
		(equal nil x)
	      )
    )
    lst
  )
)

(defun sl_round_real_ (lst
		       num
		       /
		      )
					; функция округления списка точек до нужного знака во избежании ошибки точности на функции equal
					; lst любого вида список вида '((-13850.3 -6846.28) (-13850.3 -6843.28) (-13850.3 -6843.28))
					; num число знаков до скольки округлять
  (mapcar (function
	    (lambda (x)

	      (if (equal (type x) 'list)
		(sl_round_real_ x num)
		(/ (float (fix (* x (expt 10 num)))) (expt 10 num))
	      )

	    )
	  )
	  lst
  )
)

Последний раз редактировалось Sleekka, 24.07.2012 в 11:39. Причина: забыл функцию
Sleekka вне форума  
 
Непрочитано 24.07.2012, 15:40
#7
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


VxGetInters - Returns all intersection points between two objects
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 24.07.2012, 16:42
#8
swkx


 
Регистрация: 22.01.2010
Сообщений: 311


Спасибо, всем.
Штатной Vla-IntersectWith с небольшими дополнительными проверками хватило.
swkx вне форума  
 
Непрочитано 24.07.2012, 17:00
#9
gomer

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


Цитата:
Сообщение от swkx Посмотреть сообщение
Штатной Vla-IntersectWith с небольшими дополнительными проверками хватило.
swkx, посмотрите еще раз #8! если применить библиотечные функции,то весь код уложится в 2 строчки
например
Код:
[Выделить все]
 
(defun c:test ( / en1 en2 *error*) (vl-load-com) (defun *error* (msg) nil)
  (if (and (setq en1 (car (entsel "1st ent: "))) (setq en2 (car (entsel "2nd ent: "))))
  (_kpblc-conv-list-to-3dpoints (vlax-invoke (_dwgru-conv-ent-to-vla en1) 'intersectwith (_dwgru-conv-ent-to-vla en2) acExtendNone))))
а вот так выглядит с Vla-IntersectWith
http://forum.dwg.ru/showthread.php?t=12489
VVA знает матчасть на отлично!

Последний раз редактировалось gomer, 24.07.2012 в 17:20.
gomer вне форума  
 
Автор темы   Непрочитано 24.07.2012, 21:08
#10
swkx


 
Регистрация: 22.01.2010
Сообщений: 311


gomer,

признаюсь честно - уже лень что-либо смотреть. Задача решена, на данный момент мне этого достаточно.
Еще раз спасибо за оперативную помощь.
swkx вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как определить, персекаются ли две фигуры



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как определить скорость ветра по СП 20.13330? карлсонъетка Конструкции зданий и сооружений 67 12.02.2019 11:03
Как соединить две фигуры AAction AutoCAD 29 25.02.2015 15:45
Как определить соответствует ТУ требованиям нормативных документов Aragorn Прочее. Архитектура и строительство 1 09.06.2012 21:28
Как определить диаметр трубопровода? OlegAC Инженерные сети 14 25.01.2012 11:41
Как определить площадь боковой поверхность сложной 3Д фигуры Georg AutoCAD 2 31.10.2004 14:52