Identifying entities along a rectangular border

Identifying entities along a rectangular border

SORONW
Advocate Advocate
798 Views
5 Replies
Message 1 of 6

Identifying entities along a rectangular border

SORONW
Advocate
Advocate

Lets say I have a shape with a notch removed:

zxc.PNG

of the objects in this shape, I want to isolate any entity that doesn't lie entirely on an orthogonal bounding box, and return them as a select set.

(defun C:Testing (/)
 (vl-load-com)
	(setq fabdata nil)
	(setq p1 (getpoint "\nSelect First Corner of window: "))
	(setq p2 (getcorner p1 "\nSecond Corner: "))
	(setq result (lineminmax (ssget "_w" p1 p2 '((0 . "Line")(8 . "OBJ") ))))
	(if (setq cutsel (ssget "_w" p1 p2 '((0 . "Line")(8 . "OBJ") )))
		(progn
			(setq i 0)
			(setq X (abs (- (car (car result))(car (cadr result)))))
			(setq Y (abs (- (cadr (car result))(cadr (cadr result)))))
			(if (> Y X)
				(setq 	x (abs (- (cadr (car result))(cadr (cadr result))))
						y (abs (- (car (car result))(car (cadr result)))))
			)
			(while (< i (sslength cutsel))
				(setq ent (entget (ssname cutsel i)))
				(setq 	start 	(trans (cdr (assoc 10 ent)) 0 1))
				(setq 	end 	(trans (cdr (assoc 11 ent)) 0 1))
				;(if (= i 1) (quit))
				(if (or 
						(= (abs (car start)) (abs (car end)) (car (car result))) 
						(= (abs (car start)) (abs (car end)) (car (cadr result))) 
						(= (abs (cadr start)) (abs (cadr end)) (cadr (car result))) 
						(= (abs (cadr start)) (abs (cadr end)) (cadr (cadr result)))
					) 
					(ssdel (ssname cutsel i) cutsel)
				)	
				(setq i (1+ i))
			;(princ fabdata)
			)
		)
	)
	(princ)
)

(defun lineminmax ( s / e i l s x )
    ;(if (setq s (ssget '((0 . "LINE"))))
        (progn
            (repeat (setq i (sslength s))
                (setq e (entget (ssname s (setq i (1- i))))
                      l (vl-list* (cdr (assoc 10 e)) (cdr (assoc 11 e)) l)
                )
            )
            (mapcar '(lambda ( x ) (apply 'mapcar (cons x l))) '(min max))
        )
   ; )
)

I haven't been able to puzzle out why this doesn't work consistantly. Adding a little notch to the shape only confuses it even more. 

 

Anyone here have any suggestions? 

0 Likes
799 Views
5 Replies
Replies (5)
Message 2 of 6

Kent1Cooper
Consultant
Consultant

Just a quick comment or two:

 

Why the (abs) functions?  If you're working with things drawn in negative X and/or Y territory, won't those spoil the comparisons?

 

In comparing the point coordinates [whether the (abs) functions should be involved or not], try using (equal) with a small fuzz factor, rather than (=), which requires absolute-and-exact  equality down to 16 significant figures, which often is not there with calculated real-number values.

Kent Cooper, AIA
0 Likes
Message 3 of 6

john.uhden
Mentor
Mentor

I really didn't read all the code, but if those lines were one polyline, you could use it in a fence selection.

John F. Uhden

0 Likes
Message 4 of 6

dlanorh
Advisor
Advisor

Use LeeMac's Selection Set Bounding Box

 

Construct a rectangle (rectangle command) using the returned min max points. This will give you a polyline, and then test the start, end and mid points of all lines to see if

 

 

 

(setq test (vlax-curve-getparamatpoint polyline_ent pt))

 

 

 

returns a value or nil.

 

A value means it lies on the polyline nil means it doesn't. Pseudo code below

 

 

 

(setq lst nil)
(foreach x (s_pt m_pt e_pt);;the order of the points doesn't matter
  (setq lst (cons (vlax-curve-getparamatpoint poly_ent x) lst)
)
(if (vl-every '(lambda (x) x) lst)
  (princ "\nEntirely on Line")
  (princ "\nNOT Entirely on Line")
)

 

 

I am not one of the robots you're looking for

0 Likes
Message 5 of 6

Kent1Cooper
Consultant
Consultant

Another thing I notice:  In setting the 'start' and 'end' variables, you are applying (trans) to translate them from the World Coordinate System [raw entity-data] locations to the Current UCS.  But you don't  apply the same in the (lineminmax) function or therefore to the 'result' variable.  If you don't work in other-than-World coordinates, it shouldn't matter [and you shouldn't need the (trans) functions, either], but if you do, the comparisons will be off accordingly.

Kent Cooper, AIA
0 Likes
Message 6 of 6

Kent1Cooper
Consultant
Consultant

Here's my take on it, without the (abs) functions and using (equal) instead of (=), using a different way to find the overall bounding box [taken from another routine of mine], and without the need to draw  the perimeter rectangle as some have suggested.  Minimally tested:

 

(defun C:LNOB (/ minpt maxpt eLL eUR LL UR lin start end); = Lines Not On Bounding-box
  (prompt "\nTo find Lines that do Not lie On selection's Bounding perimeter rectangle,")
  (if (setq ss (ssget '((0 . "LINE")))); not localized, to remain at end
    (progn ; then
      (repeat (setq n (sslength ss))
        (vla-getboundingbox (vlax-ename->vla-object (ssname ss (setq n (1- n)))) 'minpt 'maxpt)
        (setq
          eLL (vlax-safearray->list minpt); entity's Lower Left
          eUR (vlax-safearray->list maxpt); entity's Upper Right
          LL (if LL (mapcar 'min eLL LL) eLL); selection's Lower Left
          UR (if UR (mapcar 'max eUR UR) eUR); selection's Upper Right
        ); setq
      ); repeat
      (repeat (setq n (sslength ss))
        (setq
          lin (ssname ss (setq n (1- n)))
          start (vlax-curve-getStartPoint lin)
          end (vlax-curve-getEndPoint lin)
        )
        (if
          (or
            (and (equal (car start) (car LL) 1e-4) (equal (car end) (car LL) 1e-4)); on left edge
            (and (equal (car start) (car UR) 1e-4) (equal (car end) (car UR) 1e-4)); on right edge
            (and (equal (cadr start) (cadr LL) 1e-4) (equal (cadr end) (cadr LL) 1e-4)); on bottom edge
            (and (equal (cadr start) (cadr UR) 1e-4) (equal (cadr end) (cadr UR) 1e-4)); on top edge
          ); or
          (ssdel lin ss); then -- it lies along an edge; remove it from ss
        ); if
      ); repeat
      (sssetfirst nil ss); select/highlight/grip remaining object(s) [set remains in ss variable]
    ); progn
    (prompt "\nNo Line(s) selected."); else
  ); if
  (princ)
); defun
(vl-load-com)
(prompt "\nType LNOB to identify Lines Not On selection's Bounding perimeter.")

 

 

If all selected Lines do  lie along the overall perimeter, it simply doesn't select/highlight/grip anything at the end, and the 'ss' variable has nothing in it.  It could be made to notify  the User in such a case, instead.

Kent Cooper, AIA
0 Likes