Jump to content
Jen

Detect objects near other objects

Recommended Posts

Jen

Hi there. 

 

I'm working on a lisp that, in part, detects whether there are blocks within a certain distance of a block or how close those other blocks are. For example, I may check to see if there are blocks within 60' to the North or South or between 20' and 40' to the East or West of the block I'm analyzing. Is there anything in autolisp or vlisp that would detect objects in proximity to a given object like this? Or do I need to keep doing it the long way.

 

So far, what I've been doing is this:

1. Determine coordinates of the corners of the area I want to check for nearby objects.

2. Create a selection set of all blocks within a box formed by those coordinates.

3. Check the selection set to see if it has any of the blocks I'm looking for. 

 

This works ok, but takes a long time to process as many blocks as I'm checking. I'd like to be able to then check exactly how far away those nearby blocks are from the original block. Before I add code to do that, I wanted to see if there's a way for lisp to basically "see" the nearby objects instead of using my current long method. 

 

Thanks in advance for any pointers in the right direction.

Share this post


Link to post
Share on other sites
BIGAL

Thinking two WP within polygon ssget the first is blocks inside your desired area, 2nd is all blocks within larger area. Ok now subtract the inside blocks from outside blocks selection. Using a getclosestpointto would give the distance from the inside outline to each outer block, A bit unstable as shape of block will effect some of the answers. What happens with a block just crossing the inner boundary in or out ?

 

Can you post a sample  dwg ?

Share this post


Link to post
Share on other sites
Jen

Thanks for the reply BIGAL. 

My current approach uses selection sets similarly to what you're suggesting. It's finding the objects ok, but I was hoping there might be an easier/faster way for CAD to "see" if there's anything near an object. I did not know about getclosestpointo through, and I think that may be key. Most of my lisp experience is not with vlisp, but I'm working on learning vlisp.  Block shape is always a perfect rectangle, so no concern there. Block crossing boundary is in the ss. I use CP rather than WP for my selections because I want to know if any part of the block is near. 

 

End goal of this is illustrated in example drawing. Red block is block being analyzed. Goal is to see if it is within distance D1 from the edge. Since blocks are typically evenly spaced, I've been checking for blocks incremental distances away and counting how many are there based on how far apart they should be. If there are enough, it's not the edge yet. If there aren't, it might be the edge. Problem I'm running into is incremental distances are discrete, so it's estimating D1 and assuming how many blocks should be included. If it estimates D1 too high, it expects too many blocks and thinks it found the edge. It would be better if I could somehow determine D1. 

Sample1.dwg

Share this post


Link to post
Share on other sites
BIGAL

Hmmmm

 

Pick bottom  point of gap pick top point block below drag a line across

 

the two points establish D1

The line across gets all the entities using ssget "f" 

Compare D1 to blocks  using closestpointto and 2nd pick point

 

no idea if it works a random idea.

Share this post


Link to post
Share on other sites
Roy_043
Posted (edited)

If the rectangular blocks are always positioned orthogonally then using the vla-getboundingbox function would be my way to approach this.

Edited by Roy_043

Share this post


Link to post
Share on other sites
Roy_043

Example code:

(defun KGA_Geom_ObjectBoundingbox (obj / ptBL ptTR)
  (vla-getboundingbox obj 'ptBL 'ptTR)
  (list (vlax-safearray->list ptBL) (vlax-safearray->list ptTR))
)

(defun KGA_Conv_Pickset_To_EnameList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (ssname ss (setq i (1- i))) ret))
    )
  )
)

(defun c:Test ( / base basePt box eastDis southDis ss ssOut xMax xMin yMax yMin)
  (if
    (and
      (setq ss (ssget "_X" '((0 . "INSERT") (410 . "Model"))))
      (or
        (< 1 (sslength ss))
        (prompt "\nOnly one block found ")
      )
      (setq base (car (entsel "\nSelect base block: ")))
      (= "AcDbBlockReference" (vla-get-objectname (vlax-ename->vla-object base)))
      (setq eastDis (getdist "\nEast distance: "))
      (setq southDis (getdist "\nSouth distance: "))
    )
    (progn
      (setq basePt (car (KGA_Geom_ObjectBoundingbox (vlax-ename->vla-object base)))) ; BL point of base block.
      (setq xMin (car basePt))
      (setq xMax (+ xMin eastDis))
      (setq yMax (cadr basePt))
      (setq yMin (- yMax southDis))
      (ssdel base ss)
      (setq ssOut (ssadd))
      (foreach enm (KGA_Conv_Pickset_To_EnameList ss)
        (setq box (KGA_Geom_ObjectBoundingbox (vlax-ename->vla-object enm))) ; Format: (BLpoint TRpoint).
        (if
          (and
            (<= xMin (caar box) xMax)   ; Check X coord of BL point.
            (<= yMin (cadadr box) yMax) ; Check Y coord of TR point.
          )
          (ssadd enm ssOut)
        )
      )
    )
  )
  (sssetfirst nil ssOut)
  (princ)
)

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...