Вариант, основанный на идее Valeri. Чисто AutoCAD-овское решение, далекое от математики. Есть некоторые ограничения:
1. Набор объектов-границ должен быть таким, чтобы убирание любого из граничных объектов приводило бы к разрыву контура.
2. В набор могут входить любые объекты, кроме точек и блоков (можно добавить и исключение линий нулевой длины).
3. Если есть уверенность, что точка не лежит на одной из границ, то границы могут и пересекать друг друга и выходить за пределы контура, лишь бы выполнялся пункт 1.
4. "Блымание" экрана, и если это нужно выполнять в цикле, то не очень приятно
5. Вариант универсальный для любых объектов, но если контур состоит из прямых, предложение ShaggyDoc лучше и быстрее.
;*********************************************************************************
; Функция возвращает список ((список_имен) (список_уровней)) в данном чертеже.
; Если переданный параметр t - имена в нижнем регистре, если nil - в верхнем.
;*********************************************************************************
(defun get_all_layer (param / lst_lr lst_lrnm lrobj)
(setq lst_lr '() lst_lrnm '())
(setq lrobj (tblnext "layer" t))
(while lrobj
(setq lst_lrnm (cons (strcase (cdr (assoc 2 lrobj)) param) lst_lrnm))
(setq lst_lr (cons lrobj lst_lr))
(setq lrobj (tblnext "layer"))
);while
(list lst_lrnm lst_lr)
);defun
;*********************************************************************************
; Функция возвращает имя уровня, которого нет в чертеже.
; Передается исходное имя и список всех имен.
;*********************************************************************************
(defun get_free_layer_name (name lst_lrnm / nmb new_name)
(setq nmb 1 new_name name)
(while (member (strcase new_name t) lst_lrnm)
(setq new_name (strcat name (itoa nmb)))
(setq nmb (1+ nmb))
);while
new_name
);defun
;*********************************************************************************
; Функция гасит все уровни из списка, кроме одного.
; Передается имя уровня и список уровней.
; Возвращает список уровней, которые были погашены.
;*********************************************************************************
(defun off_layers (name lst_lr / lr_off current_lr status lstobj lrnm)
(command "_.point" '(0 0))
(setq current_lr (cdr (assoc 8 (entget (entlast)))))
(command "_erase" (entlast) "")
(setq lr_off '())
(while lst_lr
(setq lstobj (car lst_lr))
(setq status (cdr (assoc 62 lstobj)))
(setq lrnm (cdr (assoc 2 lstobj)))
(if (and (>= status 0) (/= (strcase name t) (strcase lrnm t)))
(progn
(setq lr_off (cons lrnm lr_off))
(if (= (strcase lrnm t) (strcase current_lr t))
(command "_.layer" "_off" lrnm "_yes" "")
(command "_.layer" "_off" lrnm "")
);if
);progn
);if
(setq lst_lr (cdr lst_lr))
);while
(setq lst_lr lst_lr)
lr_off
);defun
;*********************************************************************************
; Функция отображает все уровни из списка.
;*********************************************************************************
(defun on_layers (lr_off / )
(while lr_off
(command "_.layer" "_on" (car lr_off) "")
(setq lr_off (cdr lr_off))
);while
);defun
;*********************************************************************************
; Функция проверяет, станет ли контур разомкнутым, если убрать любую из границ.
; Возвращает t - если станет, иначе nil
;*********************************************************************************
(defun test_bound_objects (lst_copy pt / answer ckl obj obj_last obj2 lstmus)
(setq answer t)
(setq ckl t)
(while ckl
(setq obj (car lst_copy))
(entdel obj)
(setq obj_last (entlast))
(command "_.boundary" "_a" "_o" "_r" "" pt "")
(setq obj2 (entlast))
(setq lstmus '())
(while (not (equal obj2 obj_last))
(setq lstmus (cons obj2 lstmus))
(entdel obj2)
(setq obj2 (entlast))
);while
(if lstmus
(progn
(command "_.erase" lstmus "")
(setq answer nil ckl nil)
);progn
(progn
(setq lst_copy (cdr lst_copy))
(if (not lst_copy)
(setq ckl nil)
(entdel obj)
);if
);progn
);if
);while
answer
);defun
;*********************************************************************************
; Функция возвращает t, если точка pt - внутри контура,
; ограниченного объектами ss_obj, 1 - если точка на границе, nil - если снаружи
;*********************************************************************************
(defun inside_point (ss_obj pt / lst_objects nmb obj lstmus lst_lrnm lst_lr lrnm lr_off old_osmode
lstobj lst_copy obj_last obj2 answer ss_del ss_pnt old_pickbox)
(setq nmb 0 lst_objects '())
(repeat (sslength ss_obj)
(setq obj (ssname ss_obj nmb))
(setq lstobj (entget obj))
(if (and (/= (cdr (assoc 0 lstobj)) "INSERT")
(/= (cdr (assoc 0 lstobj)) "POINT")
);and
(setq lst_objects (cons obj lst_objects))
);if
(setq nmb (1+ nmb))
);repeat
(if lst_objects
(progn
(setq lstmus (get_all_layer t))
(setq lst_lrnm (car lstmus))
(setq lst_lr (cadr lstmus))
(setq lrnm (get_free_layer_name "test" lst_lrnm))
(command "_.layer" "n" lrnm "")
(setq old_osmode (getvar "OSMODE"))
(setvar "OSMODE" 0)
(setq lst_copy '())
(repeat (length lst_objects)
(command "_.copy" (car lst_objects) "" '(0 0) '(0 0))
(setq obj (entlast))
(setq lstobj (entget obj))
(setq lstobj (subst (cons 8 lrnm) (assoc 8 lstobj) lstobj))
(entmod lstobj)
(setq lst_copy (cons obj lst_copy))
(setq lst_objects (cdr lst_objects))
);repeat
(setq lr_off (off_layers lrnm lst_lr))
(command "_.zoom" "_e")
(setq old_pickbox (getvar "PICKBOX"))
(setvar "PICKBOX" 0)
(setq ss_pnt (ssget pt))
(if ss_pnt
(setq answer 1)
(progn
(setq obj_last (entlast))
(command "_.boundary" "_a" "_o" "_r" "" pt "")
(setq obj2 (entlast))
(setq lstmus '())
(while (not (equal obj2 obj_last))
(setq lstmus (cons obj2 lstmus))
(entdel obj2)
(setq obj2 (entlast))
);while
(if (/= (length lstmus) 1)
(setq answer nil)
(progn
(command "_.erase" (car lstmus) "")
(setq answer (test_bound_objects lst_copy pt))
);progn
);if
);progn
);if
(command "_.zoom" "_p")
(setvar "PICKBOX" old_pickbox)
(setvar "OSMODE" old_osmode)
(setq ss_del (ssget "_X" (list (cons 8 lrnm))))
(if ss_del
(command "_.erase" ss_del "")
);if
(on_layers lr_off)
(command "_.purge" "_la" lrnm "_n")
answer
);progn
nil
);if
);defun
(defun c:test ( / ss_obj pt answer)
(prompt "\nВыберите объекты, ограничивающие контур:")
(setq ss_obj (ssget))
(if ss_obj
(progn
(setq pt (getpoint "\nУкажите точку:"))
(if pt
(progn
(setq answer (inside_point ss_obj pt))
(cond
((= answer t)
(alert "Точка внутри!")
)
((= answer 1)
(alert "Точка на границе!")
)
((= answer nil)
(alert "Точка снаружи или выбраны некорректные границы!")
)
);cond
);progn
);if
);progn
);if
(princ)
);defun