Lisp routine for Bounding Box?

Topics relating to AutoLisp and SDS.

Moderators: CMS Inc, avaernes

Post Reply
AJS
Contributor
Posts: 10
Joined: Tue Feb 10, 2009 11:54 am

Lisp routine for Bounding Box?

Post by AJS » Tue Feb 10, 2009 12:46 pm

Hi there,

Does anyone know if there is a Lisp routine available that I could use to create a bounding box for polylines?

There are plenty of routines out there but the ones that I have found all use VLA functions.

I need to know the max/min X and Y so that I can calculate the bounding area. I actually came up with something that worked by recording the X and Y coordinates of the various nodes but unfortunately, it won't work when an arc is part of the polyline due to the fact that the center arc vertice is not recorded; only the vertices at the beginning and end of the arc.

One note: I ran Atoms-family and there is a function called BOUNDINGBOX but I don't know whether it applies and I couldn't get it to run.

This is the last stumbling block of a program I am writing so any help would be greatly appreciated.

Thank you

---AJS
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Tue Feb 10, 2009 1:29 pm

If they’re 2d polylines, you can do something like this

Code: Select all

(DEFUN C:DOIT (/ ED PTL)
  (SETQ PTL '()
        ED (ENTGET (CAR (ENTSEL)))
  )
  (FOREACH E ED
    (IF (= (CAR E) 10)
      (SETQ PTL (CONS (CDR E) PTL))
    )
  )
  (TESTLINE(GETBOUNDINGBOX-2D PTL))
)

(DEFUN GETBOUNDINGBOX-2D (PT_LST)
  ((LAMBDA (L)
     (LIST (APPLY 'MAPCAR (CONS 'MIN L)) 
           (APPLY 'MAPCAR (CONS 'MAX L))
     )
   )
   (CONS (LIST (CAAR PT_LST) (CADAR PT_LST)) (CDR PT_LST))
  )
)

(DEFUN TESTLINE (pl)
  (ENTMAKE 
    (LIST 
        (CONS 0 "LINE") 
        (CONS 10 (CAR PL)) 
        (CONS 11 (CADR PL))
        )
     )
)
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Tue Feb 10, 2009 1:31 pm

Sorry, I didn’t see your note about the arcs, so this may not work for you :oops:
AJS
Contributor
Posts: 10
Joined: Tue Feb 10, 2009 11:54 am

Post by AJS » Tue Feb 10, 2009 1:45 pm

Thanks for giving it a shot but unfortunately, the arc is causing the same problem.

Just thinking out loud here but I wonder, is there any way to extract the height of an arc? If I could do that, I could then do a comparison to see if the coordinate of the arc's height end point was inside/outside the bounding box and if it was outside I could add the arc apex coordinate to my vertice coordinate list.

---AJS
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Tue Feb 10, 2009 4:56 pm

I was thinking about that too, but I think it would be a tough nut to crack.
How are your C skills? You could make a little sds DLL that calls sds_bbox and returns the data to lisp.
AJS
Contributor
Posts: 10
Joined: Tue Feb 10, 2009 11:54 am

Post by AJS » Tue Feb 10, 2009 6:01 pm

You know what, I'm sick of not knowing C and I'm going to take a crack at trying to do what you suggest. if it takes a while, so be it.

I always learn better when I have a project that I'm trying to solve.

Do you have any advice on a resource to learn SDS? The documentation that came with Intellicad is sketchy



As an FYI, Here was my (albeit unwieldy) plan via LISP:

1) Take my original polyline and copy it to a frozen layer.

2) Isolate the current polyline.

3) Explode the polyline and delete all lines leaving only arcs (my polylines have only arcs and lines)

4) Cycle through the arcs and collect: Start and End angles, centers and radii.

For each arc:

a) Draw a line from the center to the start angle

b) Draw a line from the center to the end angle

c) Draw a line between the endpoints of the first two lines which will give me my chord.

d) Use the following formula that I found online to calculate the arc height:

Arc height when you know the chord length and radius:

B = R - sqrt( R^2 - (A/2)^2 )
(B = Arc Height) (R = Radius) (A = Chord Length)

Said as:
B equals R minus the square root of R squared minus A over 2 squared.


5) Draw a line from the arc center to the midpoint of the chord and then use continue to project the line to the correct height as per the above formula.

6) Extract the XY coordinate of the final line's endpoint and append it to my current polyline vertice coordinate list.

7) Use MIN and MAX functions to extract my bounding box edges from my coordinate lists.

8) After all the arcs have been cycled through, (I typically have between 2 and 8 for these polylines) erase the arcs and thaw the original polyline.


---AJS
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Tue Feb 10, 2009 6:27 pm

I wrote a dll for you to tryout, since I can’t attach file here, I posted it here
http://www.intellicad.net/forum/topics/ ... x-for-lisp

let me know if it works for you.

ps don’t waste your time learning sds as IRX will replace it sometime soon
dan
AJS
Contributor
Posts: 10
Joined: Tue Feb 10, 2009 11:54 am

Post by AJS » Tue Feb 10, 2009 7:03 pm

Thanks for the info and the advice.

I've never run a single SDS program before so I don't know how to load it up. In your zip file, there were quite a few folders; amongst them, there were two DLLs; One called SDSS samples, the other was named: interop.

Which one is the actual BoundingBox program?

How do I access the program from the Lisp file you provided?

I tried dropping them both into the main lisp filepath but that didn't seem to work.

I don't want to keep bugging you so if there's a resource that will help me learn how to do this, I'll do my best to figure it out.
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Tue Feb 10, 2009 7:19 pm

The SDSSamples.DLL is the file you need to load, it’s in the root directory of SDSSamples folder.

There are two ways you can load the DLL, the first is through lisp I.e.

(arxload "C:/Documents and Settings/Daniel/Desktop/SDSSamples/release/SDSSamples.dll")

The second is choose tools->load-lisp-or-sds-application, and add and load the file.

Once the program is loaded, you use it just how you would a lisp function, the function is called GETBBOX and it returns a list of two points, min and max

Code: Select all


;(GETBBOX 'entiyname)

(GETBBOX (CAR (ENTSEL)))

(TESTLINE (GETBBOX (CAR (ENTSEL))))

(DEFUN TESTLINE (pl)
  (ENTMAKE 
    (LIST 
        (CONS 0 "LINE") 
        (CONS 10 (CAR PL)) 
        (CONS 11 (CADR PL))
        )
     )
)
AJS
Contributor
Posts: 10
Joined: Tue Feb 10, 2009 11:54 am

Post by AJS » Tue Feb 10, 2009 8:09 pm

It works great. You've saved me a huge amount of time---greatly appreciated!


---AJS
Danielm103
Valued Contributor
Posts: 52
Joined: Mon Aug 07, 2006 11:01 pm
Location: Albuquerque,NM,USA

Post by Danielm103 » Wed Feb 11, 2009 6:19 pm

Anytime, glad I could help :)
Post Reply