Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Polyline areas

25 REPLIES 25
SOLVED
Reply
Message 1 of 26
sean.keohane
1288 Views, 25 Replies

Polyline areas

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

25 REPLIES 25
Message 2 of 26
braudpat
in reply to: sean.keohane

 

Hello from France

 

I have this kind of VLisp routine to sort PLines by Length or by Area since many years ...

I am not at all a developper so I can't update or improve it !

 

I have translated the minimum (from French to US) ...

 

IMPORTANT : You must update the source with YOURS Min-Max Values HERE >>>

(cons 1 3)
(cons 3 10)
(cons 10 20)
(cons 20 50)
(cons 50 200)

 

In this routine today, all Plines (if concerned by the famous Min-Max Values)

will changed from original Layer to a NEW layer named :

"ZZZ_SURF_LONG-1_3"

"ZZZ_SURF_LONG-3_10"

etc ...

 

Please enjoy, Bye, Pat

 

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 3 of 26
pbejse
in reply to: sean.keohane


@sean.keohane wrote:

Hi,

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.

 

Sean


 

Input number of ranges: <type in the value here as an example>

 

and what will the result if there are 5 items found Lets say 502.36 is the largest and 45.87 is the smallest, what will be the range then?

 

Result:

<type in result here for desired result>

<type in result here for desired result>

<type in result here for desired result>

 

Need more info Sean

 

 

Message 4 of 26
sean.keohane
in reply to: braudpat

Hi Pat,

Thank you for your lisp, I'll study it to see if I can alter it for my task.

Regards

Sean

Message 5 of 26
braudpat
in reply to: sean.keohane

 

Hello Sean

 

Yes it will be very easy to patch the routine "TRI_POLY" to follow the Min-Max Values you need ...

(cons minvalue1  maxvalue1)

(cons minvalue2  maxvalue2)

etc

 

I have retested this old VLisp routine on my ACAD 2013 32 bits, it's OK !

 

Bye, Pat

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 6 of 26
sean.keohane
in reply to: pbejse

Hi,

thank you for replying, sorry for being vague. I guess its not that important about the smallest area. 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.

Pat (from other reply) kindly shared a lisp he had, do you think the code/part of is useful for me?

Regards

Sean

Message 7 of 26
sean.keohane
in reply to: braudpat

Hi Pat,

thank you, I'll try to alter/use your code. I'll let you know how I get on.

Regards

Sean

Message 8 of 26
pbejse
in reply to: sean.keohane

Go ahead and tryt Braudpat's code and tell me how it goes before i do any coding on my end 🙂

 

Cheers

 

BTW: why 105 and not 100 ?

 

Message 9 of 26
braudpat
in reply to: pbejse

 

Hello Sean

 

Please patch the TRI_POLY routine like that :

 

(cons 0 105)
(cons 105 210)
(cons 210 315)
(cons 315 420)
(cons 420 525)

 

And it will do the job !

 

Don't forget to answer S (for Surface) at the question Length or Surface (L/S) :?

 

Bye, Pat

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 10 of 26
sean.keohane
in reply to: sean.keohane

Thanks Pat,

That does work but I need the ranges to be calculated by the routine by finding the largest area and dividing by number of ranges (user input) then round up the result to nearest multiple of x. (hopefully to a user input as well).

Question -  how do I select pline with largest area?

Question - how do I round up to a multiple?

thanks for your time and input.

regards

Sean

Message 11 of 26
pbejse
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

 

Message 12 of 26
Kent1Cooper
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, AIA
Message 13 of 26
braudpat
in reply to: Kent1Cooper

 

Hello

 

BRAVO for pbejse and for Kent Cooper !

 

Bye, Pat

 

PS: Both routines tested on ACAD 2013 32 bits French

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 14 of 26
Kent1Cooper
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, AIA
Message 15 of 26
Kent1Cooper
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, AIA
Message 16 of 26
pbejse
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 🙂

 

Cheers

 

BTW: nice idea with the color assignment.

 

Message 17 of 26
pbejse
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

Message 18 of 26
pbejse
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 Smiley Very Happy

 

Cheers

 

Message 19 of 26
Kent1Cooper
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, AIA
Message 20 of 26
braudpat
in reply to: Kent1Cooper

 

Hello Kent

 

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

 

Bye, Pat

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

”Boost