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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Поясните принцип работы функции Е.Елпанова lib:pline_clockwise

Поясните принцип работы функции Е.Елпанова lib:pline_clockwise

Ответ
Поиск в этой теме
Непрочитано 20.06.2011, 14:55 #1
Поясните принцип работы функции Е.Елпанова lib:pline_clockwise
swkx
 
Регистрация: 22.01.2010
Сообщений: 311

До меня не доходит, что из себя представляет список lst и как на основе его содержимого можно сделать вывод о направлении обхода вершин полилинии.

Код:
[Выделить все]
 (defun lib:pline_clockwise ( lw  / LST MAXP MINP)
;;;Eugeni Elpanov
;;; Arguments
;;;         lw - ename or vla object of polyline
;;; Return
;;;     t - clockwise
;;;    nil - counter-clockwise
  
(if (= (type lw) 'ENAME)
    (setq lw (vlax-ename->vla-object lw))
)
(vla-GetBoundingBox lw 'MinP 'MaxP)
(setq
	MinP (vlax-safearray->list MinP)
	MaxP (vlax-safearray->list MaxP)
	lst (mapcar(function(lambda(x)
			(vlax-curve-getParamAtPoint lw
			(vlax-curve-getClosestPointTo lw x))))
			(list MinP (list (car minp) (cadr MaxP))
				  MaxP (list (car MaxP) (cadr MinP))
			)
		)
)

(if(or
		(<=(car lst)(cadr lst)(caddr lst)(cadddr lst))
		(<=(cadr lst)(caddr lst)(cadddr lst)(car lst))
		(<=(caddr lst)(cadddr lst)(car lst)(cadr lst))
		(<=(cadddr lst)(car lst)(cadr lst)(caddr lst)))
   t
   nil
); if
); defun
Просмотров: 4795
 
Непрочитано 20.06.2011, 15:38
#2
TararykovDG

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


Конечно никто, кроме самого Евгения Алексеевича лучше не объяснит, но я так понял алгоритм:
1). (list MinP (list (car minp) (cadr MaxP)) MaxP (list (car MaxP) (cadr MinP))) - здесь понятно, координаты вершин прямоугольника в коротый вписана полилиния
2). lst - cписок значений параметров (vlax-curve-getParamAtPoint) для точек лежащих на нашей полилинии и являющихся ближайшими (vlax-curve-getClosestPointTo) к точкам вершин прямоугольника в коротый вписана полилиния
3). (if (or ...)) - если значения полученных параметров в списке lst увеличиваются по кругу (1-ый < 2-го, 2<3, 3<4 или 2<3 ... 4<1 и т.д.) - то полилиния идет по часовой стрелке, иначе против.

P. S. Параметром кривой для полилинии является количество предыдущих участков от начала (целая часть параметра) и доля следующего участка (в дробной части).
Таким образом, как я понял, такой алгоритм корректно работает для полилиний, которые не пересекают сами себя, выпуклость полилинии необязятельна
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 20.06.2011, 15:47
#3
swkx


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


п. 3). непонятен, хоть убей((
Цитата:
Сообщение от TararykovDG Посмотреть сообщение
если значения полученных параметров в списке lst увеличиваются по кругу
Это до меня не доходит.
swkx вне форума  
 
Непрочитано 20.06.2011, 16:07
#4
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Мне больше непонятно связка (я ее видел не только у Евгения) в 25 строке - (if .... t nil)
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 20.06.2011 в 16:13.
Дима_ вне форума  
 
Непрочитано 20.06.2011, 16:10
#5
Лиспер


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


Господи, ну снимите if...
Код:
[Выделить все]
 (defun lib:pline_clockwise (lw / lst maxp minp)
;;;Eugeni Elpanov
;;; Arguments
;;;         lw - ename or vla object of polyline
;;; Return
;;;     t - clockwise
;;;    nil - counter-clockwise

  (if (= (type lw) 'ename)
    (setq lw (vlax-ename->vla-object lw))
    ) ;_ end of if
  (vla-getboundingbox lw 'minp 'maxp)
  (setq
    minp (vlax-safearray->list minp)
    maxp (vlax-safearray->list maxp)
    lst  (mapcar (function (lambda (x)
                             (vlax-curve-getparamatpoint
                               lw
                               (vlax-curve-getclosestpointto lw x)
                               ) ;_ end of vlax-curve-getParamAtPoint
                             ) ;_ end of lambda
                           ) ;_ end of function
                 (list minp
                       (list (car minp) (cadr maxp))
                       maxp
                       (list (car maxp) (cadr minp))
                       ) ;_ end of list
                 ) ;_ end of mapcar
    ) ;_ end of setq

  (or
    (<= (car lst) (cadr lst) (caddr lst) (cadddr lst))
    (<= (cadr lst) (caddr lst) (cadddr lst) (car lst))
    (<= (caddr lst) (cadddr lst) (car lst) (cadr lst))
    (<= (cadddr lst) (car lst) (cadr lst) (caddr lst))
    ) ;_ end of or
  ) ;_ end of defun
ИМХО что в лоб, что по лбу - результат будет тот же
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 20.06.2011, 16:12
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Лиспер Посмотреть сообщение
Господи, ну снимите if...
Вот это мне и не понятно - зачем его ставить
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 20.06.2011, 16:22
#7
TararykovDG

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


swkx, см. рисунок. В результате список lst = (4.0 0.409426 1.69041 2.82796) и мы проверяем:
4.0 < 0.409426 < 1.69041 < 2.82796 - нет
0.409426 < 1.69041 < 2.82796 < 4.0 - да, значит полилиния по часовой стрелке
Вложения
Тип файла: pdf 111.pdf (11.1 Кб, 130 просмотров)
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 20.06.2011, 16:28
#8
swkx


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


Да черт с ним, с if
Объясните лучше, какая связь между контуром и описанным вокруг неё прямоугольником.
Физический смысл всего этого действа не доходит.
swkx вне форума  
 
Непрочитано 20.06.2011, 16:31
#9
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Рад, что вы стремитесь не только использовать библиотечные функции, но и понимать их суть!
По сути вопроса:
Во первых, спасибо TararykovDG за оперативную помощь.

Действительно, алгоритм довольно прост, но он оказался гораздо более эффективным и применимым, чем альтернативные.
1. находим vla объект кривой
Код:
[Выделить все]
(if (= (type lw) 'ENAME)
    (setq lw (vlax-ename->vla-object lw))
)
2. находим габаритный контейнер, описанный вокруг кривой, т.е левую нижнюю и правую верхнюю точки габаритного контейнера
Код:
[Выделить все]
(vla-GetBoundingBox lw 'MinP 'MaxP)
3. Здесь, чуть сложнее, для начала преобразуем габариты контейнера из вариантов в лисповое представление точек, как списков чисел.
Код:
[Выделить все]
(setq
	MinP (vlax-safearray->list MinP)
	MaxP (vlax-safearray->list MaxP))
4. формируем список точек - всех вершин габаритного контейнера идущих по часовой стрелке, начиная с левого нижнего угла, далее вверх, потом вправо итд.
Код:
[Выделить все]
(list MinP (list (car minp) (cadr MaxP))
				  MaxP (list (car MaxP) (cadr MinP))
			)
5. здесь получаем точки лежащие на кривой, но ближайшие к заданной точке и сразу получаем параметр полученной точки.
Стоит пояснить физический смысл параметра для полилинии - это номер сегмента, которому принадлежит точка, т.е начальная точка и весь сегмент до следующей - это первый сегмент, т.е начальная точка имеет нулевой параметр, середина первого сегмента - 0.5 три четверти первого сегмента - 0.75, а вторая точка полилинии, всегда 2.0 и так далее, т.е каждый сегмент имеет в целых числах номер равный номеру сегмента, а в дроби, это какая часть от начала сегмента. Возможно я пояснил слишком подробно, но надеюсь понятно!
Код:
[Выделить все]
(lambda(x)
			(vlax-curve-getParamAtPoint lw
			(vlax-curve-getClosestPointTo lw x))))
			(list MinP (list (car minp) (cadr MaxP))
				  MaxP (list (car MaxP) (cadr MinP))
			)
		)
Другими словами, мы получаем в этом коде весь список параметров, например, если взять прямоугольник, то получим один из восьми возможных списков:
(0 1 2 3)
(1 2 3 0)
(2 3 0 1)
(3 0 1 2)
(3 2 1 0)
(2 1 0 3)
(1 0 3 2)
(0 3 2 1)
Для более сложных полииний, да еще с дуговыми сегментами, списки будут другие, цифры могут быть дробные и даже несколько цифр может быть на одном сегменте и отличаться только в дроби. Для некоторых треугольников, возможно совпадение двух последовательных параметров. Но суть полученного списка, для непересекающегося контура будет именно такой!
6. теперь рассматриваем список параметров и разбираемся, числа идут по возрастанию или убыванию.
Код:
[Выделить все]
(if(or
		(<=(car lst)(cadr lst)(caddr lst)(cadddr lst))
		(<=(cadr lst)(caddr lst)(cadddr lst)(car lst))
		(<=(caddr lst)(cadddr lst)(car lst)(cadr lst))
		(<=(cadddr lst)(car lst)(cadr lst)(caddr lst)))
   t
   nil
); if

ps. осталось добавить, что у других контуров, те. не lwpolyline, а 2d полилиний, сплайнов итд, так же есть свои параметры, они могут иметь другой физический смысл, но все равно они будут правильно обрабатываться этой программой!


Цитата:
Сообщение от Дима_
Вот это мне и не понятно - зачем его ставить
Все очень просто объясняется, к вам попал код, который я писал примерно 2003 - 2004 годы, те. сейчас, вы пишете более оптимальные коды, чем я тогда...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/

Последний раз редактировалось Елпанов Евгений, 20.06.2011 в 16:36.
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 20.06.2011, 16:39
#10
swkx


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


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
формируем список точек - всех вершин габаритного контейнера идущих по часовой стрелке, начиная с левого нижнего угла, далее вверх, потом вправо итд.
Этого мне не хватало, чтобы уловить суть - вершины габаритного контейнера идут всегда по часовой стрелке.
Теперь дошло.
Спасибо всем большое!
swkx вне форума  
 
Непрочитано 20.06.2011, 16:44
#11
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


swkx, мы так сформировали список - можно и наоборот...
К тому же, никто не мешает использовать в алгоритме другой контейнер, например другой внешний контур и определять направленны ли они в одну сторону или нет.
Удачи!
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 20.06.2011, 16:56
#12
swkx


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


Елпанов Евгений,
да, я уже окончательно врубился, направление-то мы сами и задаём:
Код:
[Выделить все]
 (list MinP (list (car minp) (cadr MaxP)) MaxP (list (car MaxP) (cadr MinP)))
swkx вне форума  
 
Непрочитано 20.06.2011, 17:16
#13
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
те. сейчас, вы пишете более оптимальные коды, чем я тогда...
Offtop: ИХМО оптимальность кода определяется в первую очередь временем в течении которого им пользуются - все остальное вторично
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 20.06.2011, 21:39
#14
VVA

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


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
Все очень просто объясняется, к вам попал код, который я писал примерно 2003 - 2004 годы,
Добавлю, что первая публикация относится к 2005 году
Еще пару алгоритмов и познавательная дискуссия: LISP, VBA. Изменение направления обхода точек в полилинии

Цитата:
Сообщение от Дима_ Посмотреть сообщение
Offtop: ИХМО оптимальность кода определяется в первую очередь временем в течении которого им пользуются - все остальное вторично
С 2005 года ф-ция не давала сбоев и пользуюсь ей регулярно.
Недавно на cadtutor.net появилась подобная тема all polylinienrichtungen counterclockwise, где поучавствовала вышеприведенная ф-ция. Там опубликован еще один алгоритм, он более "затратный", но, по заявлению автора, позволяет обрабатывать пересекающиеся полилинии.
Код:
[Выделить все]
;;; Function to test if polyline is counter-clock-wise
;;; obj= vla-object / ename of the polyline
;;; Result is nil if clockwise, T if counter-clockwise
;;; get from irneb
;;; http://www.cadtutor.net/forum/showthread.php?59671&p=405007&viewfull=1#post405007
(defun PL-CounterClockWise-p (obj / ang ang1 ang2 angT param)
  (setq param 1.5
        angT  0.0
        ang1  (angle '(0.0 0.0 0.0) (vlax-curve-getFirstDeriv obj 0.5))
  )
  (while (< param (vlax-curve-getEndParam obj))
    (setq ang2 (angle '(0.0 0.0 0.0) (vlax-curve-getFirstDeriv obj param)))
    (setq ang (- ang2 ang1))
    (if (> (abs ang) pi)
      (setq ang (* (if (< ang 0.0) -1.0 1.0) (- (abs ang) (* pi 2))))
    )
    (setq angT  (+ angT ang)
          ang1  ang2
          param (1+ param)
    )
  )
  (>= angT 0.0)
)
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 20.06.2011 в 23:06. Причина: орфография
VVA вне форума  
 
Непрочитано 20.06.2011, 22:13
#15
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от VVA Посмотреть сообщение
но, по заявлению автора, позволяет обрататывать пересекающиеся полилинии.
А куда направленна линия начинающиеся по часовой стрлке, а заканчивающиеся против (даже без самопересечений)?
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 21.06.2011, 01:00
#16
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от VVA Посмотреть сообщение
Добавлю, что первая публикация относится к 2005 году
Действительно, до 2005 года, я редко выкладывал свои коды. Нормальный интернет у меня появился только в 2004 году...
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Поясните принцип работы функции Е.Елпанова lib:pline_clockwise



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DwgRuLispLib: Функции работы со строками VVA Библиотека функций 8 31.05.2012 14:19
Принцип работы расширительной камеры DK Разное 23 16.05.2009 17:38
Поиск работы Perezz!! Разное 46 21.03.2008 12:50
функции для работы с ini-файлами ivspec Программирование 4 08.08.2006 11:43
Особенности работы функции TRANS kp+ Программирование 10 31.05.2006 00:55