ShaggyDoc-у:
Спасибо за действительно инересный (и полезный) сайт
KAI:
Есть еще метод "Подсчета суммы ориентаций пересечений", я пользуюсь уже около 10 лет - пока не подводил...
Комментарии минимальны, но думаю будет понятно...
;;;-----------------------------------------------------------------------
(defun My- (x y)
(cond
((< x y) -1)
((> x y) 1)
(t 0)))
;;;-----------------------------------------------------------------------
(defun My+ (x y)
(or (zerop x) (zerop y) (zerop (+ x y)) ))
;;;-----------------------------------------------------------------------
(defun In_Figure (pt contur / pt1 pt2 pti ptl ptp ptc eps tmp)
;
; Тест - находится ли точка pt внутри контура contur.
; Алгоритм взят из статьи О.Р.Мусина в журнале
; "Программирование" 4, 91г.
; Выбран алгоритм "Сумма ориентаций пересечений"
;
; Аргументы :
; contur - список координат точек образующих контур
; в виде (pt1 pt2 ...ptn)
; pt - тестируемая точка
;
; Функции :
; _locat - проверяет находится ли пара точек в квадрантах
; ((1,4)(2,4)(1,3))
; _kk - вычисляет ориентацию отрезка
;
(setq tmp nil
pt1 (mapcar '- (car contur) pt)
ptp pt1)
;
; создается список отрезков
;
(while contur
(setq ptc (mapcar '- (car contur) pt)
contur (cdr contur))
(if (_locat ptc ptp)
(setq tmp (cons (list ptc ptp) tmp)))
(setq ptp ptc))
(if (_locat pt1 ptp)
(setq tmp (cons (list pt1 ptp) tmp)))
;
; ищем точки пересечения L+ с контуром
;
(setq pt '(0 0 0)
ptl '(1 0 0)
eps 0)
;
(while tmp
(setq pt1 (caar tmp)
pt2 (cadar tmp)
tmp (cdr tmp)
pti (inters pt1 pt2 pt ptl nil))
(cond
((< (car pti) 0) nil) ; Отрезок пересекает L-
(t (setq eps (+ (_kk pt1 pt2) eps))))) ;
;
; В eps - сформированный признак
;
(not (zerop eps)))
;;;-----------------------------------------------------------------------
(defun _Locat (pt1 pt2);
;
; Допустимая ли комбинация четвертей ?
;
(cond
((and (>= (car pt1) 0) (>= (cadr pt1) 0)) ; 1
(or (and (>= (car pt2) 0) (< (cadr pt2) 0)) ; 1-4
(and (< (car pt2) 0) (< (cadr pt2) 0)))) ; 1-3
((and (< (car pt1) 0) (>= (cadr pt1) 0)) ; 2
(and (>= (car pt2) 0) (< (cadr pt2) 0))) ; 2-4
((and (< (car pt1) 0) (< (cadr pt1) 0)) ; 3
(and (>= (car pt2) 0) (>= (cadr pt2) 0))) ; 3-1
(t ; 4
(or (and (>= (car pt2) 0) (>= (cadr pt2) 0)) ; 4-1
(and (< (car pt2) 0) (>= (cadr pt2) 0)))) )) ; 4-2
;;;-----------------------------------------------------------------------
(defun _Kk (pt1 pt2);
(if (>= (cadr pt1) (cadr pt2)) 1 -1))