Convert polyline-circle to normal circle

Convert polyline-circle to normal circle

Henrik_Lo
Collaborator Collaborator
21,560 Views
39 Replies
Message 1 of 40

Convert polyline-circle to normal circle

Henrik_Lo
Collaborator
Collaborator

HI

 

I dose anyone have a LISP program there can convert polyline-circle to normal circle.

I do have 10 different polyline-circles in my drawing, and a lot of them.

I looked up at code, there can do the job for one polyline-circle, but I need it be able

selecting all, and then convert them to normal circles.

 

 

This is the code I looked up.

(defun c:Test (/ ss)

;; Author : Tharwat 20. jan. 2014 ;;

(if (setq ss (ssget "_:L" '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))))

((lambda (i / sn l x y)

(while (setq sn (ssname ss (setq i (1+ i))))

(setq l (mapcar 'cdr (vl-remove-if-not (function (lambda (u) (eq (car u) 10))) (entget sn)))

x (/ (apply '+ (mapcar 'car l)) (length l))

y (/ (apply '+ (mapcar 'cadr l)) (length l))

)

(if (entmakex (list '(0 . "CIRCLE") (cons 10 (list x y)) (cons 40 (distance (list x y) (car l)))))

(entdel sn)

)

(setq l nil

x nil

y nil

)

)

)

-1

)

)

(princ)

)

(vl-load-com)

 

 

 

 

 

 

Regards

Henrik

 

0 Likes
Accepted solutions (1)
21,561 Views
39 Replies
Replies (39)
Message 2 of 40

Ajilal.Vijayan
Advisor
Advisor

Hi Henrik,

Have you tried EXPLODE command ?

Or if you want to use the above code, remove "_:L"  from this line

(if (setq ss (ssget "_:L" '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))))

0 Likes
Message 3 of 40

Henrik_Lo
Collaborator
Collaborator

Hi

That worked just find by removing the L, and that’s was what I needed.

Thangs a lot for that advice.

 

The last problem left, is to convert all the spline to polyline automatic. I am

use the command “SPLinEdit” to convert to polyline, but I can only select

one at the time, and I have about 1000 holes at the time.

 

Is there a command for this converting job?

 

Regards

Henrik

0 Likes
Message 4 of 40

Ajilal.Vijayan
Advisor
Advisor
0 Likes
Message 5 of 40

ВeekeeCZ
Consultant
Consultant

@Henrik_Lo wrote:

 

 

The last problem left, is to convert all the spline to polyline automatic. I am

use the command “SPLinEdit” to convert to polyline, but I can only select

one at the time, and I have about 1000 holes at the time.

 

Is there a command for this converting job?

 

Regards

Henrik


Use PEDIT command.

Message 6 of 40

Henrik_Lo
Collaborator
Collaborator
Accepted solution

HI, this program seem to work just find

Thangs for helping me out

 

Regards

Henrik

 

0 Likes
Message 7 of 40

Kent1Cooper
Consultant
Consultant

@Henrik_Lo wrote:

.... 

I dose anyone have a LISP program there can convert polyline-circle to normal circle.

.... 

This is the code I looked up.

....

x (/ (apply '+ (mapcar 'car l)) (length l))

y (/ (apply '+ (mapcar 'cadr l)) (length l))

)

(if (entmakex (list '(0 . "CIRCLE") (cons 10 (list x y)) (cons 40 (distance (list x y) (car l)))))

.... 


That converts any closed Polyline, no matter what its shape or combination of line and/or arc segments, to a Circle, using the average of the vertex locations as the center, and the first vertex of the Polyline as the point that lies on the circumferance, which can mean the resulting Circle is pretty far from representative of the Polyline in size as well as shape, if it wasn't very circular to begin with.

 

If you want a routine that will determine whether a Polyline is actually circular in shape before turning it into a Circle, try the P2C command in CirclePolylineSwap.lsp, available here.  [Make sure you download the most advanced one, in Post 27].  This allows you to select a whole area of a drawing all at once, and it will turn any circular Polylines into Circles, but will leave alone any Polylines that are not circular.

 

P2C also works on "heavy" 2D Polylines, which the "Test" command won't.  And it has another cool feature:  if a Polyline circle has global width, it offers the option of whether to draw the resulting Circle along the Polyline's center or its inside or outside edge.  [If any Polyline(s) in a multiple selection have global width, it asks the question once, and applies the same choice to all in the selection.]

Kent Cooper, AIA
Message 8 of 40

Henrik_Lo
Collaborator
Collaborator

HI

How to get the “CirclePolylineSwap”  work with this “circle”

 

 

I am working a lot with 3D items, created from differed software, and I receive then in STEP formats.

If I convert the faces to DXF and open the in AutoCAD, all items are Spline, ant therefore i need to convert then before I can use then further.

 

Regards

Henrik

 

 

 

0 Likes
Message 9 of 40

Kent1Cooper
Consultant
Consultant

@Henrik_Lo wrote:

....

How to get the “CirclePolylineSwap”  work with this “circle”

....


P2C won't do those -- it requires a Polyline made of arc segments [for example, what is made by the Donut command], that is, truly in circular shape, not just an approximation with a lot of short line segments.  Nor does it work with Splines.  For your Polyline made of many line segments, you'll get a Circle from the code in Post 1, but I think it will be slightly off, because there are coincident vertices at the beginning/end [a zero-length closing segment].  That means the center, as an average of the vertices, will be slightly skewed from the true center [downward just a little], and the size won't be quite accurate.  You would need to decide how precise it needs to be.

 

[I tried another routine I have that converts regular polygons to Circles, but even correcting for the coincident vertices, it didn't work, so I think that Polyline must be not quite regular enough as a polygon.]

Kent Cooper, AIA
0 Likes
Message 10 of 40

Kent1Cooper
Consultant
Consultant

@Henrik_Lo wrote:

....

If I convert the faces to DXF and open the in AutoCAD, all items are Spline, ant therefore i need to convert then before I can use then further.

.... 


If I may assume that all Splines that are conversions from Circles via DXF like that are converted in the same way, that is, have the same number and configuration of control points, etc., then as a start, this basic routine will draw the equivalent Circle [minimally tested]:

 

(defun C:S2C (/ spl cplist); = Spline [To] Circle
  (setq
    spl (car (entsel "\nSelect circular Spline to draw equivalent Circle: "))
    cplist (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget spl)))
; list of control points ); setq (command "_.circle" "_2P" "_none" (car cplist) "_none" (nth 6 cplist)) ); defun

 

If there are other ways to make a Spline circular, using different control-point and/or fit-point configurations, this won't draw Circles on them correctly.  I haven't tried it in any non-World Coordinate System.  It does not check anything about the selected Spline [not even whether it is a Spline, much less whether it's circular], so it's up to you to select only an appropriate object.  And it does not remove the selected Spline, but only draws a Circle over it, on the current Layer.

 

Removing the Spline can be added easily enough, and drawing the Circle on the same Layer as the Spline, and limiting the selection to a Spline, and selection of multiple Splines if you want, and accounting for different Coordinate Systems.  Having it check whether a Spline is actually circular should be achievable, but is probably not trivial, and it may only be able to check within some tolerance, but I won't look into that unless you think it's necessary.

Kent Cooper, AIA
0 Likes
Message 11 of 40

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
....

....  For your Polyline made of many line segments, you'll get a Circle from the code in Post 1, but I think it will be slightly off, because there are coincident vertices at the beginning/end [a zero-length closing segment].  That means the center, as an average of the vertices, will be slightly skewed from the true center [downward just a little], and the size won't be quite accurate.  You would need to decide how precise it needs to be.

 

...

Here's a way to do a Polyline approximation of a Circle of many short line segments, which will not be thrown off by coincident vertices/zero-length segments [within reason].  It finds three vertices, at the start and about 1/3 and 2/3 of the way around, for a 3-point Circle.  It has similar limitations to the one about circular Splines in my previous Reply, and can be similarly enhanced, but see what you think.

 

(defun C:PLS2C (/ pl verts); = Polyline of Line Segments [To] Circle
  (setq
    pl (car (entsel "\nSelect mult-line-segment Polyline approximating circle to draw equivalent Circle: "))
    verts (cdr (assoc 90 (entget pl))); number of VERTiceS
  ); setq
  (command "_.circle" "_3P"
    "_none" (vlax-curve-getStartPoint pl)
    "_none" (vlax-curve-getPointAtParam pl (/ verts 3))
    "_none" (vlax-curve-getPointAtParam pl (fix (* verts 0.67)))
  ); command
); defun
Kent Cooper, AIA
0 Likes
Message 12 of 40

ВeekeeCZ
Consultant
Consultant

@Kent1Cooper wrote:

@Kent1Cooper wrote:
....

....  For your Polyline made of many line segments, you'll get a Circle from the code in Post 1, but I think it will be slightly off, because there are coincident vertices at the beginning/end [a zero-length closing segment].  That means the center, as an average of the vertices, will be slightly skewed from the true center [downward just a little], and the size won't be quite accurate.  You would need to decide how precise it needs to be.

 

...

Here's a way to do a Polyline approximation of a Circle of many short line segments, which will not be thrown off by coincident vertices/zero-length segments [within reason].  It finds three vertices, at the start and about 1/3 and 2/3 of the way around, for a 3-point Circle.  It has similar limitations to the one about circular Splines in my previous Reply, and can be similarly enhanced, but see what you think.

 

(defun C:PLS2C (/ pl verts); = Polyline of Line Segments [To] Circle
  (setq
    pl (car (entsel "\nSelect mult-line-segment Polyline approximating circle to draw equivalent Circle: "))
    verts (cdr (assoc 90 (entget pl))); number of VERTiceS
  ); setq
  (command "_.circle" "_3P"
    "_none" (vlax-curve-getStartPoint pl)
    "_none" (vlax-curve-getPointAtParam pl (fix (/ verts 3)))
    "_none" (vlax-curve-getPointAtParam pl (fix (* verts 0.67)))
  ); command
); defun

Nice idea, I would suggest fix both the thirds 🙂

0 Likes
Message 13 of 40

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:

.... 

....
    "_none" (vlax-curve-getPointAtParam pl (fix (/ verts 3)))
....

Nice idea, I would suggest fix both the thirds 🙂


Not necessary -- the 'verts' variable will be an integer already, so dividing it by an integer will result in an integer returned value, and (fix) would have no effect.

Kent Cooper, AIA
Message 14 of 40

Henrik_Lo
Collaborator
Collaborator

HI All

Thangs for all the help and information’s regarding this issue; I’ll tray work out the best method

Rergards

Henrik

0 Likes
Message 15 of 40

Anonymous
Not applicable

I have exactly 277 entities to change into circles, I would like to be able to select them at once and create circles around every one of them. Is there an option to add to this routine so You could select multiple entities to create circles around them and not having to select them seperately one by one?

 

KR

 

0 Likes
Message 16 of 40

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

I have exactly 277 entities to change into circles, I would like to be able to select them at once and create circles around every one of them. Is there an option to add to this routine so You could select multiple entities to create circles around them and not having to select them seperately one by one?

 

....

 

That can certainly be done, but it's different enough from the subject of this thread that it probably deserves a new thread of its own [for instance so that if someone else is looking to do the same thing, they'll be more likely to be able to find whatever solution you get].

 

But when you do start a new thread:  "change into circles" and "create circles around" are two different things, so some more detail would be helpful, such as an image or sample drawing, showing before and after situations, and what a Circle around [or replacing?] various object types should be like.  For instance, the simple approach that comes to mind is to find the bounding box of each object, and draw a Circle with its center in the middle of the bounding box and a corner of that box defining the radius.  That would do well with Line entities, but for some entity types would result in Circles larger than you probably want, such as this:

 

CircleAround.png

 

whereas for an Arc, maybe you would want the Circle to be the one of which that Arc is a portion.  [I have a routine to close Arcs into Circles, if you're interested.]  The result on an initial Circle would be similarly larger than the Circle it's drawing one around, whereas you would probably want it to coincide with that.  A square Polyline rotated 45 degrees would likewise get a Circle that is fully beyond it, whereas you might want a corner of the square itself, rather than of its bounding box, to define the Circle's radius.  Etc., etc.

Kent Cooper, AIA
0 Likes
Message 17 of 40

Anonymous
Not applicable
New thread? Its basically the same lisp with multiselection added. I would do it myself but Im a beginner and I don't know how to change that
0 Likes
Message 18 of 40

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:
New thread? Its basically the same lisp with multiselection added. ....

I would agree if not for your use of the seemingly contradictory phrases "create circles around" vs. "change into circles" [which latter the routine in Post 11 does not do, but the one linked to in Post 7 does, though that already allows multiple selection], and mostly your use of the word "objects" which is so much broader in scope than the Polylines that most of this thread is about.  [You might also be talking about the routine in Post 10, which is about Splines instead.]

 

But if it's really just a matter of adding multiple selection to the routine in Post 11, try this [minimally tested]:

 

(defun C:PLS2C (/ ss n pl verts); = Polyline of Line Segments [To] Circle
  (prompt "\nTo draw true Circles over mult-line-segment Polylines approximating circles,")
  (setq ss (ssget "_:L" '((0 . "*POLYLINE"))))
  (repeat (setq n (sslength ss))
    (setq
      pl (ssname ss (setq n (1- n)))
      verts (cdr (assoc 90 (entget pl))); number of VERTiceS
    ); setq
    (command "_.circle" "_3P"
      "_none" (vlax-curve-getStartPoint pl)
      "_none" (vlax-curve-getPointAtParam pl (/ verts 3))
      "_none" (vlax-curve-getPointAtParam pl (fix (* verts 0.67)))
    ); command
  ); repeat
); defun

Still very basic -- doesn't confirm that you actually picked any Polylines, or whether each one has enough vertices for it to make a 3-point Circle, has no error handler, etc., but all that can be added.

Kent Cooper, AIA
0 Likes
Message 19 of 40

Anonymous
Not applicable

The thing is I have a drawing with tree canopies that appear not to by truly circular therefore the routine from post 7 doesnt work.

Thats why I figured the other lisp might work. Your routine above works perfectly, doesnt have error handler as You said but good enough 🙂 thx

You can see my drawing belowe as I attached it - those canopies look like they are circular... but paparently they are not.

 

KR

0 Likes
Message 20 of 40

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

... I have a drawing with tree canopies that appear not to by truly circular therefore the routine from post 7 doesnt work.

.... those canopies look like they are circular... but paparently they are not.

 


That's right -- they're made of line segments [see Post 9 for more explanation].

Kent Cooper, AIA
0 Likes