Visual LISP, AutoLISP and General Customization

Reply
*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 11 of 26 (181 Views)

Re: Polyline areas

03-22-2013 05:27 AM in reply to: sean.keohane

<untested>

 

(defun c:ATL (/ round data ClosePolylines i e maxarea l) ; Area To Layer
(vl-load-com)  
;;		pBe MAr2013			;;
;;	Kent Cooper for round fucntion	 	;;

  (defun round (num near) (* (fix (/ (+ num (/ near 2.0)) near)) near))

  (if (And (Setq data nil
                 l nil
                 ClosedPolylines
                  (ssget "_X"
                         '((0 . "LWPOLYLINE,POLYLINE")
                           (-4 . "<OR")
                           (70 . 1)
                           (70 . 5)
                           (70 . 129)
                           (70 . 133)
                           (-4 . "OR>")
                          )
                  )
           )
           (setq range (getint "\nEnter Range: "))
      )
    (progn (repeat (setq i (sslength ClosedPolylines))
             (setq e (ssname ClosedPolylines (setq i (1- i))))
             (setq Data (cons (list (vlax-curve-getArea e) e) Data))
           )
           (setq maxarea (apply 'max (mapcar 'car data)))
           (setq n (+ (round (/ maxarea range) range) range))
           (repeat range
             (setq l     (cons (* n range) l)
                   range (1- range)
             )
           )
           (foreach itm data
             (setq lay (vl-some '(lambda (j k)
                                   (if (<= j (car itm) k)
                                     k
                                   )
                                 )
                                (cons 0 l)
                                l
                       )
             )
             (setq e (entget (cadr itm)))
             (entmod (subst (cons 8 (itoa lay)) (assoc 8 e) e))
           )
    )
  )
  (princ)
)

 

HTH

 

*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 12 of 26 (179 Views)

Re: Polyline areas

03-22-2013 05:42 AM in reply to: sean.keohane

sean.keohane wrote:

Hi,

I need to segregate closed polylines in my drawing by area range. Ideally, I would input the number of ranges I need.

Then somehow find the smallest and largest pline area to determine the range values (rounding up to a sensble number)

Then with the ranges determined the polylines would be segregated and moved to new layers.

I've been trying to hobble together pieces but with no joy.

Can someone set me going with the correct approach, I'd appreciate it.

Regards

Sean


I was playing with this, and came up with the attached.  It works a little differently from the descriptions in some of your later posts, but can be adjusted easily enough, which I will do later if you don't beat me to it.

 

The differences are that it divides the range in sizes of the existing closed Polylines, from the smallest to the largest, into the number of sub-ranges, rather than dividing the range from zero to the largest one.  And it doesn't round the largest value up to base the range division on, but uses the size of the largest Polyline.

 

Anyway, see what you think, and I can make those changes later if you want.

Kent Cooper
*Expert Elite*
braudpat
Posts: 1,837
Registered: ‎12-15-2006
Message 13 of 26 (173 Views)

Re: Polyline areas

03-22-2013 06:11 AM in reply to: Kent1Cooper

 

Hello

 

BRAVO for pbejse and for Kent Cooper !

 

Bye, Pat

 

PS: Both routines tested on ACAD 2013 32 bits French

 

Bye, Pat

*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 14 of 26 (164 Views)

Re: Polyline areas

03-22-2013 07:27 AM in reply to: pbejse

pbejse wrote:

.... 

....
  (defun round (num near) (* (fix (/ (+ num (/ near 2.0)) near)) near))
....
(setq n (+ (round (/ maxarea range) range) range)) ....

It would have been a little more efficient of me to do one thing the way you did, namely to use 'max [and under my original assumptions, 'min] in mine instead of sorting the whole list and getting the values from the first and last items.  It would eliminate the need for my 'areasort' variable.  Coming in adjusted routine....

 

Thanks for the credit on the rounding function.  However, I see two problems with its use in the (setq n... rounding line quoted above:

1)  That rounding function rounds up or down to the nearest multiple of its 'near' argument [here, the 'range' variable].  If it rounds up, it should be left at that value, without adding 'range' again.

2)  If the area of the largest Polyline is exactly a multiple of the rounding value, it will likewise increase the subdividing value [here, the 'n' variable] to the next multiple above what it should be.  That is, if the largest Polyline is 500 square units and the User asks for division into 5 categories, the 'n' result will be 105 rather than 100.

 

What's needed is a round-up-only approach that doesn't round up if the number is an exact multiple of the rounding value.  [See my other routine, though that needs to be altered in other ways to do what they're looking for.]

Kent Cooper
*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 15 of 26 (160 Views)

Re: Polyline areas

03-22-2013 07:50 AM in reply to: sean.keohane

sean.keohane wrote:

.... If say I decide to divide it into 5 ranges, It would find the largest area and divide by 5 and round up to a  whole number. In your example the range increment would be set to 105. (rounding up to nearest multiple of 5). Then 5 layers would be created (105,210,315,420,525) plines with areas >0 <105 into 105layer etc. and plines moved to those layers.

....


Okay, the attached updated version of PolylineClassify.lsp seems to do those things [though I used a Layer naming convention that calls your example PLClass105], in limited testing.  It could use some other stuff [error handling, undo begin/end, etc.], but give it a shot.

Kent Cooper
*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 16 of 26 (143 Views)

Re: Polyline areas

03-22-2013 08:29 PM in reply to: Kent1Cooper

Kent1Cooper wrote:

pbejse wrote:

 

Thanks for the credit on the rounding function.  However, I see two problems with its use in the (setq n... rounding line quoted above:

1)  That rounding function rounds up or down to the nearest multiple of its 'near' argument [here, the 'range' variable].  If it rounds up, it should be left at that value, without adding 'range' again.

2)  If the area of the largest Polyline is exactly a multiple of the rounding value, it will likewise increase the subdividing value [here, the 'n' variable] to the next multiple above what it should be.  That is, if the largest Polyline is 500 square units and the User asks for division into 5 categories, the 'n' result will be 105 rather than 100.

 

What's needed is a round-up-only approach that doesn't round up if the number is an exact multiple of the rounding value.  [See my other routine, though that needs to be altered in other ways to do what they're looking for.]


I noticed that too, Hence my question in post # 8 why he end up with 105 instead of 100. by removing the additional "range" value  it will not conform with the OPs request. 

 

It appears thats the OPs intention, not really sure.

 

I did had a look-see. interesting approach capturing polylines with area property. I may have to write an round-up-only routine or just use yours :smileyhappy:

 

Cheers

 

BTW: nice idea with the color assignment.

 

*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 17 of 26 (138 Views)

Re: Polyline areas

03-22-2013 09:04 PM in reply to: pbejse

 

(defun c:ATL (/ round data ClosePolylines i e maxarea l) ; Area To Layer
(vl-load-com)  
;;		pBe MAr2013			;;
;;	Kent Cooper for round fucntion	 	;;

  (defun round (num near) (* (fix (/ (+ num (/ near 2.0)) near)) near))

  (if (And (Setq data nil
                 l nil
                 ClosedPolylines
                  (ssget "_X"
                         '((0 . "LWPOLYLINE,POLYLINE")
                           (-4 . "<OR")
                           (70 . 1)
                           (70 . 5)
                           (70 . 129)
                           (70 . 133)
                           (-4 . "OR>")
                          )
                  )
           )
           (setq range (getint "\nEnter Range: "))
      )
    (progn (repeat (setq i (sslength ClosedPolylines))
             (setq e (ssname ClosedPolylines (setq i (1- i))))
             (setq Data (cons (list (vlax-curve-getArea e) e) Data))
           )
           (setq maxarea (apply 'max (mapcar 'car data)))
           (setq n (round (/ maxarea range) range)
      		 n (if (< (* n range) maxarea)
                     	(+ range n) n))
           (repeat range
             (setq l     (cons (* n range) l)
                   range (1- range)
             )
		(entmake (list (cons 0 "LAYER")
	                 (cons 100 "AcDbSymbolTableRecord")
	                 (cons 100 "AcDbLayerTableRecord")
	                 (cons 2 (itoa (car l)))
                         (cons 62 (1+ range))      
	                 (cons 70 0)))
           )
           (foreach itm data
             (setq lay (vl-some '(lambda (j k)
                                   (if (<= j (car itm) k)
                                     k
                                   )
                                 )
                                (cons 0 l)
                                l
                       )
             )
             (setq e (entget (cadr itm)))
             (entmod (subst (cons 8 (itoa lay)) (assoc 8 e) e))
           )
    )
  )
  (princ)
)

 

Following Kents advice, the additional "range" value will be added to n varaible only if the MAX area is LESS than the highest value of the calculated range. Also added color assignment.

 

HTH

*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 18 of 26 (131 Views)

Re: Polyline areas

03-23-2013 02:34 AM in reply to: braudpat

braudpat wrote:

 

BRAVO for pbejse and for Kent Cooper !

 

PS: Both routines tested on ACAD 2013 32 bits French

 


Thank you for that patrice. Nice of you to test the rouitnes.

 

I peek at your code, I undertstand the programming language but NOT French though :smileyvery-happy:

 

Cheers

 

*Expert Elite*
Kent1Cooper
Posts: 5,242
Registered: ‎09-13-2004
Message 19 of 26 (121 Views)

Re: Polyline areas

03-23-2013 07:10 AM in reply to: pbejse

pbejse wrote:

Kent1Cooper wrote:
....

1)  That rounding function rounds up or down to the nearest multiple of its 'near' argument [here, the 'range' variable].  If it rounds up, it should be left at that value, without adding 'range' again.

....


I noticed that too, Hence my question in post # 8 why he end up with 105 instead of 100. by removing the additional "range" value  it will not conform with the OPs request. 

....


Here's my interpretation:  Given your original for-example situation with the largest Polyline area being 502.36, and with the User asking for 5 categories/classifications, they want to divide 502.36 by 5, which gives 100.472.  If the size of each category were 100, then the top category would go from 400 to 500, and the largest Polyline would not fall into any of the categories.  That's why they want to round the size of each category up to the next multiple of whatever increment the User asks for -- in this case, if that's 5, up to 105.  Then the top category is from 420 to 525, and the largest Polyline does fall within that range.

 

With my rounding function that rounds up or down to the nearest multiple, a divided value of 100.472 rounds down to 100, and it's necessary to add the 5 to that to get the category size to 105, so that the largest area will fall into the top size category.

 

But suppose the largest Polyline's area is 515 square units.  Dividing that by 5 gives 103, which that rounding function will round up, to 105.  Then if 5 is added, it becomes 110, and the top category is from 440 to 550.  Yes, the largest Polyline will fall into that category, but the top category from 420 to 525, based on a category size of 105 without the extra 5 added, is enough to encompass that largest Polyline.

 

So if the rounding function rounds up, the extra 5 [or whatever the User's increment is] does not need to be added to ensure the largest Polyline is covered.  It only needs to be added if the rounding function rounds down.  But the same can be accomplished by having a rounding function that only rounds up.

 

But it should not round up if the starting value is an exact multiple.  If the largest Polyline is 500 square units, with a divided value of 100, that should not be increased to 105, because the un-increased size of 100 will make a top category from 400 to 500, which will include the size of that largest Polyline.

Kent Cooper
*Expert Elite*
braudpat
Posts: 1,837
Registered: ‎12-15-2006
Message 20 of 26 (116 Views)

Re: Polyline areas

03-23-2013 08:10 AM in reply to: Kent1Cooper

 

Hello Kent

 

I appreciate your comments, so I have a new name for you : Rounder Manager !

 

Bye, Pat

 

Bye, Pat

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community