Author Topic: Bounding Box Problem  (Read 7224 times)

0 Members and 1 Guest are viewing this topic.

GOTNONE

  • Guest
Bounding Box Problem
« on: August 11, 2011, 08:02:56 PM »
Hi,
     I am trying to automate cleaning up a bunch of drawings exported from Adobe Illustrator and have been using the bounding box property to set the origin point for a block.  However, I have run into some drawings where the bounding box for the splines and then the blocks containing the splines are much larger than necessary.  I have used Lee Mac's excellent code to try to diagnose the problem
http://www.theswamp.org/index.php?topic=35192.msg404318#msg404318
and it appears that autocad will recalculate the bounding box when the spline is rotated enough, but rotations of 90 degrees fail to cause autocad to recalculate the bounding box.  Is there a way to make autocad recalculate the bounding box, or am I going to have to examine the control points of the spline and calculate the bounding box on my own?  I have attached a drawing which suffers from this oversized bounding box problem.

GOTNONE

  • Guest
Re: Bounding Box Problem
« Reply #1 on: August 12, 2011, 12:01:24 PM »
So I wrote a function to give me approximately the real bounding box for a spline (or any other curve), but I wonder if the incorrect GetBoundingBox() value will cause me trouble in the future.  I am not exactly sure how to fix this "quirk" of autocad 2012.  There is probably a better way to get these points, but for my drawings, the  GetClosestPointTo method on a "far" away point in each of the four cardinal directions will work.  I probably could have used a scale factor to set the distance to the "far" point, but this works for me.

Code: [Select]
(defun splinebbox (ent / i minx maxx miny maxy cpoint midx midy)
  (setq i '0
minx '()
maxx '()
miny '()
maxy '()
  )
  (while (< i (vlax-get-property ent "NumberOfControlPoints"))
    (setq cpoint (vlax-safearray->list (vlax-variant-value (vla-getControlPoint ent i))))
    (if (or (< (car cpoint) minx) (not minx))
      (setq minx (car cpoint))
    )
    (if (or (< (cadr cpoint) miny) (not miny))
      (setq miny (cadr cpoint))
    )
    (if (or (> (car cpoint) maxx) (not maxx))
      (setq maxx (car cpoint))
    )
    (if (or (> (cadr cpoint) maxy) (not maxy))
      (setq maxy (cadr cpoint))
    )
    (setq i (1+ i))
  )
  (setq midx (/ (+ maxx minx) 2)
midy (/ (+ maxy miny) 2))
  (list
    (list
      (car (vlax-curve-GetClosestPointTo ent (list (+ minx -100000) midy 0)))
      (cadr (vlax-curve-GetClosestPointTo ent (list midx (+ miny -100000) 0)))
      0)
    (list
      (car (vlax-curve-GetClosestPointTo ent (list (+ maxx 100000) midy 0)))
      (cadr (vlax-curve-GetClosestPointTo ent (list midx (+ maxy 100000) 0)))
      0)
  )
)

I would still love to know more about the GetBoundingBox method and why it is choking on some of my drawings.  Perhaps it is a problem with the way that Illustrator exported these splines.

ribarm

  • Gator
  • Posts: 3250
  • Marko Ribar, architect
Re: Bounding Box Problem
« Reply #2 on: August 12, 2011, 02:18:42 PM »
It seems that splines are wrong objects to use vla-getboundingbox... I also got wrong results with your block... But when I exploded block to get spline object and then created region, coordinates were correct... So if you plan to examine splines, you can convert them to regions and then use :

Code: [Select]
(defun c:bbox ( / ent obj minpt ptmin maxpt ptmax)
(vl-load-com)
(setq ent (car (entsel "\nPick object from witch to obtain bbox coordinates")))
(setq obj (vlax-ename->vla-object ent))
(vla-getboundingbox obj 'minpt 'maxpt)
(setq ptmin (vlax-safearray->list minpt))
(setq ptmax (vlax-safearray->list maxpt))
(princ "\n")
(princ ptmin)
(princ ptmax)
(command "rectangle" ptmin ptmax)
(princ)
)

Then do undo and return them back from region to spline... Or you can explode region and then join splines into single spline...
vla-getboundingbox gave me correct results for all types of objects... Only problem seems to be with your type of splines... With normal splines, CAD finds bounding box according to position of Control Vertices and not by Fit Points...
« Last Edit: August 13, 2011, 03:43:21 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3250
  • Marko Ribar, architect
Re: Bounding Box Problem
« Reply #3 on: August 12, 2011, 02:40:19 PM »
Checked again with normal splines and with converting them to regions... The results are various... Maybe the best is to use what works fine - your code...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Bounding Box Problem
« Reply #4 on: August 12, 2011, 03:26:03 PM »
I used a .NET function but it would be the same as using PEDIT ans selecting the spline which can convert it into a polyline.
 
If that can be done from LISP
 
2010 or later I think

ribarm

  • Gator
  • Posts: 3250
  • Marko Ribar, architect
Re: Bounding Box Problem
« Reply #5 on: August 13, 2011, 03:18:33 AM »
Yes, that works... Convert spline to pline - command "SPLINEDIT" -> "Polyline" and then use vla-getboundingbox method... After that you can undo conversion to be back to spline... SPLINEDIT has this option on CAD versions 2010, 2011, 2012 (2009 - not checked); 2008 doesn't support Polyline conversion option...

Thanks, Jeff for your intuitive opinion - it certainly has sense  :blank: :whistle:
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Bounding Box Problem
« Reply #6 on: August 13, 2011, 08:05:24 AM »
After that you can undo conversion to be back to spline...

I would opt to copy the Spline object (vla-copy), use SPLINEDIT then GetBoundingBox on the copy, then delete the copy.  :-)

GOTNONE

  • Guest
Re: Bounding Box Problem
« Reply #7 on: August 15, 2011, 10:37:55 AM »
Thanks for the suggestions everyone.

I wonder when Autodesk will either add a GetBoundingBox method for splines, or fix the method for blocks which contain splines.  It would seem to me that the top and bottommost points could be determined by looking either at "corner" or "end" points, or along the curve for the real zeros of the first derivative of the y(t) function of the curve falling between (0,1).  Then take the minimum and maximum y values of this set.  The left and right most points could be determined by looking at the corner  and end points and also along the curve for the real zeroes of the first derivative of the x(t) portion of the bezier function to create the set for the possible max and min x points.  I have played around with beziers in Illustrator and have found variations on this method useful to find tangents to curves.  Since all bezier splines are mathematical functions, it is possible to find the boundingbox with arbitrary precision.

I have not tried to code up a routine for this in autolisp as the method I used above works reasonably.  However, I would think that the technique described in this post should have performance advantages over the method employing GetClosestPointTo.