# How to create boundary box with spline entity?

## Recommended Posts

Hi pro guru.

Anybody can help me how to write a lisp can create a boundary box with spline entity?:lol:

##### Share on other sites

Not sure what you mean by "boundary box" - if is about "bounding box", then please check this routine written by Lee Mac.

##### Share on other sites

Yes I mean like the routine written by Lee Mac. But this Lisp cannot correctly make the bounding box for the spline. I need is really close to the spline ==> "mean no gap".

##### Share on other sites

Indeed, the BoundingBox method is inaccurate for Splines.

An alternative approach might be to approximate the Spline using an appropriate point list, then calculate the bounds of such point list; though, this algorithm will undoubtedly be slower than the BoundingBox method.

Here is an example to demonstrate this method (you will need to download my Entity to Point List function):

```(defun BoundingBox ( ent / l )
(if (setq l (LM:Entity->PointList ent))
(mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max))
)
)```

##### Share on other sites

Alternatively may create a copy in place of the spline, apply FLATTEN command on it and use Lee’s routine for bounding box; remove helper polyline just after.

##### Share on other sites

Nice idea Mircea!

Here is another method (excuse the messy code):

```(defun SplineBoundingBox ( ent / pt1 pt2 res var )
(if (setq ent (entmakex (entget ent)))
(progn
(setq var (mapcar 'getvar '(peditaccept cmdecho)))
(mapcar 'setvar '(peditaccept cmdecho) '(1 0))
(command "_.pedit" ent 10 "")
(mapcar 'setvar '(peditaccept cmdecho) var)
(if (not (equal ent (setq ent (entlast))))
(progn
(vla-getboundingbox (vlax-ename->vla-object ent) 'pt1 'pt2)
(setq res (mapcar 'vlax-safearray->list (list pt1 pt2)))
)
)
(entdel ent)
)
)
res
)```

Test function:

```(defun c:test ( / bb en )
(princ "\nSelect a Spline: ")
(if (setq en (ssget "_+.:E:S:L" '((0 . "SPLINE"))))
(if (setq bb (SplineBoundingBox (ssname en 0)))
(entmakex
(list
(cons 0 "LWPOLYLINE")
(cons 100 "AcDbEntity")
(cons 100 "AcDbPolyline")
(cons 90 4)
(cons 70 1)
(list 10 (caar  bb) (cadar  bb))
)
)
(princ "\nUnable to retrieve Bounding Box.")
)
)
(princ)
)

##### Share on other sites

I think that Lee's code won't be correct for earlier versions of ACAD... If you don't need exactly but approx result, try this...

```(defun SplineBoundingBox ( ent / xmin xmax ymin ymax res cmde )
(setq cmde (getvar 'cmdecho))
(setvar 'cmdecho 0)
(vl-cmdf "_.ucs" "w")
(vl-cmdf "_.plan" "")
(vl-cmdf "_.zoom" "o" ent "")
(setq ymin (- (cadr (getvar 'viewctr)) (/ (getvar 'viewsize) 2.0)) ymax (+ (cadr (getvar 'viewctr)) (/ (getvar 'viewsize) 2.0)))
(vl-cmdf "_.ucs" "z" 90)
(vl-cmdf "_.plan" "")
(vl-cmdf "_.zoom" "o" ent "")
(setq xmax (- (car (trans (getvar 'viewctr) 1 0)) (/ (getvar 'viewsize) 2.0)) xmin (+ (car (trans (getvar 'viewctr) 1 0)) (/ (getvar 'viewsize) 2.0)))
(vl-cmdf "_.zoom" "p")
(vl-cmdf "_.zoom" "p")
(vl-cmdf "_.zoom" "p")
(vl-cmdf "_.zoom" "p")
(vl-cmdf "_.zoom" "p")
(vl-cmdf "_.ucs" "p")
(vl-cmdf "_.ucs" "p")
(setvar 'cmdecho cmde)
(setq res (list (list xmin ymin 0.0) (list xmax ymax 0.0)))
res
)

(defun c:test ( / bb en )
(princ "\nSelect a Spline: ")
(if (setq en (ssget "_+.:E:S:L" '((0 . "SPLINE"))))
(if (setq bb (SplineBoundingBox (ssname en 0)))
(entmakex
(list
(cons 0 "LWPOLYLINE")
(cons 100 "AcDbEntity")
(cons 100 "AcDbPolyline")
(cons 90 4)
(cons 70 1)
(list 10 (caar  bb) (cadar  bb))
)
)
(princ "\nUnable to retrieve Bounding Box.")
)
)
(princ)
)
```

If you want exact results, consider converting SPLINE to POLYLINE like Mircea suggested or if you have A2010 or above (not sure for A2009) A2008 doesn't support - try SPLINEDIT -> Convert to polyline and obtain Bounding Box from pline - after remove dummy pline... If you have A2010 or above, then try also Lee's code - just checked on my A2012 and it worked...

Also check this thread from theswamp...

M.R.

Edited by marko_ribar

##### Share on other sites

Thank for Lee Mac and Marko Ribar Lisp. After try on my AutoCAD 2007, still cannot work well. Maybe my AutoCAD are version are too old. Both of your code cannot support. Anyway thank you both of you. I still need to find out how to break though it.

##### Share on other sites
Thank for Lee Mac and Marko Ribar Lisp. After try on my AutoCAD 2007, still cannot work well. Maybe my AutoCAD are version are too old. Both of your code cannot support. Anyway thank you both of you. I still need to find out how to break though it.

kwwong6,

As far as I know, the solution that I posted in reply#4 should work in AutoCAD 2007.

##### Share on other sites

Lee, I'm afraid that PEDIT command of version 2007 doesn't support spline as input.

Command: PEDIT

Select polyline or [Multiple]:

Object selected is not a polyline

I think the programmatically alternative is to parse the spline entity with an appropriate defame and trace it with a polyline. Not sure to how to establish that defame size.

##### Share on other sites

Ya! Lee Mac of course can work. But result are having small gap. I attach a drawing for you so see.

Thanks.

spline.zip

##### Share on other sites

```
(defun tracecurve ( obj di / cycle st )
(defun cycle ( st stp seg l )
(cond
( (< (+ st seg) stp )
(cycle (+ seg st) stp seg
(cons (vlax-curve-getPointAtParam obj st) l)
)
)
( t
(and (< st stp)
(setq l
(cons (vlax-curve-getPointAtParam obj st) l)
)
)
(reverse
(cons (vlax-curve-getPointAtParam obj stp) l)
)
)
)
)
(if
(and (not (minusp di))(not (zerop di))
(vl-position
(vla-get-objectname
(cond
( (eq 'ENAME (type obj))(vlax-ename->vla-object obj ))
( obj )
)
) '("AcDbCircle" "AcDbArc" "AcDbEllipse" "AcDbSpline")
)
)
(cycle
(setq st (vlax-curve-getStartParam obj))
(vlax-curve-getEndParam obj)
(- (vlax-curve-getParamAtDist obj 0.125) st)
nil
)
)
)
```

Modifying Lee Mac's suggestion, though I don't know why his way wouldn't work for you.

```
(defun BoundingBox ( ent / l )
(if (setq l (tracecurve ent 0.125))
(mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max))
)
)
```

##### Share on other sites

@kwwong6 and Lt Dan's legs: Are you both saying that Lee's code from post 6 is working on your AutoCAD 2007?!?

##### Share on other sites
@kwwong6 and Lt Dan's legs: Are you both saying that Lee's code from post 6 is working on your AutoCAD 2007?!?

Yes, no problem running on AutoCAD 2007. Just having small gap as I upload the attached drawing from post 12.

Thank you very much for LT Dan's Legs. Your code really work!!!!! But if for multi select the spline, Can you modify your code?

##### Share on other sites
Lee, I'm afraid that PEDIT command of version 2007 doesn't support spline as input.

I think the programmatically alternative is to parse the spline entity with an appropriate defame and trace it with a polyline. Not sure to how to establish that defame size.

MSasu,

I was referring to post#4 in my last post, this solution does not involve the use of PEDIT

##### Share on other sites
Modifying Lee Mac's suggestion' date=' though I don't know why his way wouldn't work for you.

```
(defun BoundingBox ( ent / l )
(if (setq l (tracecurve ent 0.125))
(mapcar '(lambda ( a ) (apply 'mapcar (cons a l))) '(min max))
)
)
```

[/quote']

But your 'tracecurve' is using linear steps; this will be far less accurate than the method used in my Entity to Point List function

##### Share on other sites
Ya! Lee Mac of course can work. But result are having small gap. I attach a drawing for you so see.

Thanks.

kwwong,

You could never achieve an exact bounding box using this method since this method is approximating a continuous curve with a discrete number of points; for true accuracy, you would need an infinite number of points. You could of course increase the accuracy by increasing the number of points in the approximation, but at a severe loss in performance.

##### Share on other sites
MSasu,I was referring to post#4 in my last post, this solution does not involve the use of PEDIT

My mistake then. Sorry for inconvenience!

##### Share on other sites

Thank you Lee Mac for you information. But code done by Lt Dan's legs really can work well for me. Anybody can make this code to multi select spline?