# Adding global width to a circle

## Recommended Posts

Here's a little trick I learned a while back. I needed to add thickness to a circle & found a slick way to do it. Here goes: Start by making a polygon with 4 sides. Check inscribed in circle when prompted. Next specify your radius. That will create a square. Then select polyline edit, then select fit, then width. Tah Dah! You have a circle with a global width!

##### Share on other sites

great tip - saved me today

##### Share on other sites

The DONUT command can probably also give you a similar result. Specify the inner and outer dimensions, and voila!

Thanks ... ..

##### Share on other sites

That helps a lot! Thanks

##### Share on other sites

Hi my names is Homer Simson some one said Donuts !!

##### Share on other sites

I use two arcs and use PE to convert to polylines and join. I think I once saw a LISP somewhere that would do the two polyline arcs from a circle, maybe from DotSoft.

##### Share on other sites

I have used this with success for a long time.

```;;  CirclePolylineSwap.lsp [command names: C2P & P2C]
;;  Two commands, to convert in both directions between a Circle and a circular
;;  (two-equal-arc-segment closed) Polyline, such as the Donut command makes.
;;  Both commands:
;;  1. ask User to select again if they miss, pick an incorrect object type, or pick an
;;      object on a locked Layer;
;;  2. remove selected/converted object, but can easily be edited to retain it;
;;  3. account for different Coordinate Systems;
;;  4. retain non-default/non-Bylayer color, linetype, linetype scale, lineweight,
;;      and/or thickness.
;;  See additional notes above each command's definition.
;;  Kent Cooper, May 2011

;;  C2P
;;  To convert a selected Circle to a two-equal-arc-segment closed zero-
;;  width Polyline circle [Donut w/ equal inside & outside diameters],
;;  which can then be modified as desired [given width, etc.], since Pedit
;;  will not accept selection of a Circle.
;
(defun C:C2P (/ *error* cmde csel cir cdata cctr crad cextdir pdata)
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg))
); end if
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
); end defun - *error*
(setq cmde (getvar 'cmdecho))
(setvar 'cmdecho 0)
(command "_.undo" "_begin")
(prompt "\nTo convert a Circle to its Polyline equivalent,")
(while
(not
(and
(setq csel (ssget ":S" '((0 . "CIRCLE"))))
(= (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 (entget (ssname csel 0))))))) 0)
; 0 for Unlocked, 4 for Locked
); end and
); end not
(prompt "\nNothing selected, or not a Circle, or on a Locked Layer.")
); end while
(setq
cir (ssname csel 0); Circle entity name
cdata (entget cir); entity data
cctr (cdr (assoc 10 cdata)); center point, OCS for Circle & LWPolyline w/ WCS 0,0,0 as origin
cextdir (assoc 210 cdata); extrusion direction
); end setq
(setq
pdata (vl-remove-if-not '(lambda (x) (member (car x) '(67 410 8 62 6 48 370 39))) cdata)
; start Polyline entity data list -- remove Circle-specific entries from
; Circle's entity data, and extrusion direction; 62 Color, 6 Linetype, 48
; LTScale, 370 LWeight, 39 Thickness present only if not default/bylayer
pdata
'((0 . "LWPOLYLINE") (100 . "AcDbEntity"))
pdata ; remaining non-entity-type-specific entries
'((100 . "AcDbPolyline") (90 . 2) (70 . 129) (43 . 0.0))
; 90 = # of vertices, 70 1 bit = closed 128 bit = ltype gen. on, 43 = global width
(list
(cons 38 (caddr cctr)); elevation in OCS above WCS origin [Z of Circle center]
'(40 . 0.0) '(41 . 0.0) '(42 . 1); 0 width, semi-circle bulge factors
'(40 . 0.0) '(41 . 0.0) '(42 . 1)
cextdir ; extr. dir. at end [if in middle, reverts to (210 0.0 0.0 1.0) in (entmake)]
); end list
); end append & pdata
); end setq
(entmake pdata)
(entdel cir); [remove or comment out this line to retain selected Circle]
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
(princ)
); end defun

;;  P2C
;;  To convert a selected closed two-equal-arc-segment global-width circular
;;  Polyline [Donut] to a true Circle.  If selected Polyline has non-zero global
;;  width, offers User option to draw Circle along center-line or along inside or
;;  outside edge of width, and retains choice as default for next use.
;;  Works on both old-style "heavy" and newer "lightweight" Polylines.
;;  [Will not work on one with more than two segments, or with two unequal-
;;  included-angle segments, even if truly circular.]
;
(defun C:P2C (/ *error* cmde psel pl pdata pwidadj cposdef cpostemp pv1 pv2 cdata)
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg))
); end if
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
); end defun - *error*
(setq cmde (getvar 'cmdecho))
(setvar 'cmdecho 0)
(command "_.undo" "_begin")
(prompt "\nTo convert a Polyline circle to a true Circle,")
(while
(not
(and
(setq psel (ssget ":S" '((0 . "*POLYLINE"))))
(if psel (setq pl (ssname psel 0) pdata (entget pl)))
(= (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 pdata))))) 0)
; 0 for Unlocked, 4 for Locked
(if (= (cdr (assoc 0 pdata)) "POLYLINE"); "heavy" Polyline
(progn; then
(command "_.convertpoly" "_light" pl ""); retains same entity name
(setq pdata (entget pl)); replace "heavy" Polyline entity data
); end progn
T; else - to not return nil for LWPolyline
); end if
(member '(90 . 2) pdata); two vertices
(member '(42 . 1.0) (cdr (member '(42 . 1.0) pdata))); two half-circle bulge factors
; needs to be really precise -- will be for one made with Donut,
; but may not be for one made with, for example, Pline [pt] Arc
; Direction [direction] [halfway around] Close, even with Snap on
); end and
); end not
(prompt "\nNothing selected, or not a circular Polyline [Donut], or on a Locked Layer.")
); end while
(if (and (assoc 43 pdata) (/= (cdr (assoc 43 pdata)) 0)); global non-zero width
(progn; then
(initget "Center Inside Outside")
(setq
pwidadj (/ (cdr (assoc 43 pdata)) 2)
cposdef (cond (_P2Ccpos_) (T "Center")); Center default on first use
cpostemp
(getkword
(strcat
"\nCircle position on Donut [Center/Inside/Outside] <"
(substr cposdef 1 1)
">: "
); end strcat
); end getkword & cpostemp
_P2Ccpos_ (cond (cpostemp) (cposdef))
); end setq
); end progn
); end if
(setq
pv1 (cdr (assoc 10 pdata)); = Polyline Vertex 1 [XY]
pv2 (cdr (assoc 10 (cdr (member (assoc 10 pdata) pdata)))); = Polyline Vertex 2 [XY]
; can't use parameter XYZ WCS locations, because cdata needs XY OCS locations
cdata (vl-remove-if-not '(lambda (x) (member (car x) '(67 410 8 62 6 48 370 39))) pdata)
; build circle entity data list -- remove Polyline-specific entries from
; Polyline's entity data, and extrusion direction; 62 Color, 6 Linetype, 48
; LTScale, 370 LWeight, 39 Thickness present only if not default/bylayer
cdata
'((0 . "CIRCLE") (100 . "AcDbEntity"))
cdata ; remaining non-entity-type-specific entries
(list
'(100 . "AcDbCircle")
(list
10 ; center
(/ (+ (car pv1) (car pv2)) 2); X = halfway between X's of vertices
(/ (+ (cadr pv1) (cadr pv2)) 2); Y = halfway between Y's of vertices
(cdr (assoc 38 pdata))); Z of Circle = elevation of Pline
(cons
(+
(/
(distance; diameter -- needs 3D points for 3D distance
(vlax-curve-getStartPoint pl)
(vlax-curve-getPointAtParam pl 1)
); end distance
2
); end /
(cond
(T 0); Pline with width & Center option, or no width/no position prompt
); end cond
); end +
); end cons
(assoc 210 pdata); extr. dir. at end [if in middle, reverts to (210 0.0 0.0 1.0) in (entmake)]
); end list
); end append & cdata
); end setq
(entmake cdata)
(entdel pl)
; [remove or comment out above line to retain selected
; Polyline -- will be left lightweight if originally heavy]
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
(princ)
); end defun
(prompt "\nType C2P to convert a Circle to its Polyline equivalent.")
(prompt "\nType P2C to convert a circular Polyline to its Circle equivalent.")```

##### Share on other sites
I have used this with success for a long time.

Nice one.

The only thing that would make it better is if it allowed you to set the width within the routine, rather than having to do after with the Pedit command. Still a time saver though.

Fixed quote tags

##### Share on other sites

A circle is 2*pi.

What is an arc angle 2*pi-pi/1000000 ?

A tiny gap ! one arc !

6.283182166 v's 6.2.83185307

As suggetsed by Cad64 in lisp Enter offset +ve would mean 1/2 each side -ve match existing radius etc or a combo width,off 12,0

```command: arc
Specify start point of arc or [Center]: c
Specify center point of arc: 200,200
Specify start point of arc: 300,200
Specify end point of arc (hold Ctrl to switch direction) or [Angle/chord Length]: a
Specify included angle (hold Ctrl to switch direction): 359.9999
pedit L
w 5
```

Now to find 5 minutes

Edited by BIGAL

##### Share on other sites

Try this, yes there is a very small error but can you tell ? Not sure how far I can push the 0.00000001

```; circle to donut by Homer simson who loves donuts
; actually Alan H March 2018

(defun c-donut (/ obj cenpt rad width off oldaunits oldsnap)

(setq obj (vlax-ename->vla-object (car (entsel "\nPick circle"))))

(setq	cenpt (vlax-safearray->list
(vlax-variant-value (vla-get-center obj))
)
)

)

(ah:getval2
"Enter width" 5	4     "5"
"Enter offset +ve -ve "	5	4     "0"
)

(setq width (atof val1))
(setq off (atof val2))

(setq oldaunits (getvar "aunits"))
(setvar 'aunits 3)
(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)

(entmakex (list (cons 0 "ARC")
(cons 10 cenpt)
(cons 50 0.0)
(cons 51 (- (* pi 2.0) 0.0000001))
)
)

(command "pedit" (entlast) "Y" "w" width "")

(setvar 'aunits oldaunits)
(setvar 'osmode oldsnap)
(princ)
)

(c-donut)
```

Edited by BIGAL

##### Share on other sites
Try this, yes there is a very small error but can you tell ? Not sure how far I can push the 0.00000001

There's seems to be a problem. I load and run the routine, it asks me to pick a circle, I click on a circle and then it quits and says the operation has been cancelled.

##### Share on other sites

Do apologise left out the dcl asking for width and offset.

GETVALS3.lsp

##### Share on other sites

Thanks but it's still not working for me. I'm not sure why a dcl is needed? After the circle is converted, it should just be a simple call for Pedit to set width. Incorporating a dcl to open a dialog seems overly complicated. Maybe I'll take a look at it this weekend and see if I can tweak it to do what I want.

##### Share on other sites

Actually, it was pretty simple to add the function. I just added a single line of code at the end of dtkell's routine, before the (princ).

(command "_.pedit" (entlast) "w" pause "")

Now it does what I want.

##### Share on other sites

Hi Cad64 if you dont want the dcl just change the lines as in next code snippet. I took into account the next request can we have the pline at a different offset than the circle see diagram previous post, the dcl asks two questions width and offset, the offset can be predefined so it is a click on ok as the offset of zero means it is central over the existing circle. This also allows the circle to be an edge of the new pline. width = 5 offset= 2.5

It is just me I have moved more to not looking down and entering line after line, by using the library dcl, you can use it in any program maybe you thought it was hard coded, it creates the dcl in the Autocad defined temporary directory. (setq fname (vl-filename-mktemp "" "" ".dcl")) In terms of response time I have not had any lag in popping up on the screen.

```(if (not aH:getval2)    (load "getvals3")   )
(ah:getval2  "Enter width" 5 4     "5"     "Enter offset +ve -ve " 5 4     "0"    )
(setq width (atof val1))
(setq off (atof val2))

remove these
[color=red](if (not aH:getval2)    (load "getvals3")   )[/color]
[color=red](ah:getval2  "Enter width" 5 4     "5"     "Enter offset +ve -ve " 5 4     "0"    )[/color]
[color=black]change these[/color]
[color=teal](setq width (getreal "Enter width "))[/color]
[color=teal](setq off (getreal "Enter offset"))[/color]
```

Sample code getvals3.lsp for 1,2 or 3 inputs

```[color=black](if (not aH:getval2)    (load "getvals3")   ) ; returns val1 as string[/color]
[color=black](ah:getval1 "Line 1" 5 4 "default")[/color]
[color=black](ah:getval2  "Enter width" 5 4     "5"     "Enter o ffset +ve -ve " 5 4     "0"    ) ; returns val1 val2 as strings[/color]
[color=black](ah:getval3 "Line 1" 5 4 "default1" "Line2" 8 7 "default2" "Line 3" 6 4 "123") ; val1 val2 val3 as strings[/color]
```

Edited by BIGAL

##### Share on other sites
I have used this with success for a long time.

```;;  CirclePolylineSwap.lsp [command names: C2P & P2C]
;;  Two commands, to convert in both directions between a Circle and a circular
;;  (two-equal-arc-segment closed) Polyline, such as the Donut command makes.
;;  Both commands:
;;  1. ask User to select again if they miss, pick an incorrect object type, or pick an
;;      object on a locked Layer;
;;  2. remove selected/converted object, but can easily be edited to retain it;
;;  3. account for different Coordinate Systems;
;;  4. retain non-default/non-Bylayer color, linetype, linetype scale, lineweight,
;;      and/or thickness.
;;  See additional notes above each command's definition.
;;  Kent Cooper, May 2011

;;  C2P
;;  To convert a selected Circle to a two-equal-arc-segment closed zero-
;;  width Polyline circle [Donut w/ equal inside & outside diameters],
;;  which can then be modified as desired [given width, etc.], since Pedit
;;  will not accept selection of a Circle.
;
(defun C:C2P (/ *error* cmde csel cir cdata cctr crad cextdir pdata)
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg))
); end if
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
); end defun - *error*
(setq cmde (getvar 'cmdecho))
(setvar 'cmdecho 0)
(command "_.undo" "_begin")
(prompt "\nTo convert a Circle to its Polyline equivalent,")
(while
(not
(and
(setq csel (ssget ":S" '((0 . "CIRCLE"))))
(= (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 (entget (ssname csel 0))))))) 0)
; 0 for Unlocked, 4 for Locked
); end and
); end not
(prompt "\nNothing selected, or not a Circle, or on a Locked Layer.")
); end while
(setq
cir (ssname csel 0); Circle entity name
cdata (entget cir); entity data
cctr (cdr (assoc 10 cdata)); center point, OCS for Circle & LWPolyline w/ WCS 0,0,0 as origin
cextdir (assoc 210 cdata); extrusion direction
); end setq
(setq
pdata (vl-remove-if-not '(lambda (x) (member (car x) '(67 410 8 62 6 48 370 39))) cdata)
; start Polyline entity data list -- remove Circle-specific entries from
; Circle's entity data, and extrusion direction; 62 Color, 6 Linetype, 48
; LTScale, 370 LWeight, 39 Thickness present only if not default/bylayer
pdata
'((0 . "LWPOLYLINE") (100 . "AcDbEntity"))
pdata ; remaining non-entity-type-specific entries
'((100 . "AcDbPolyline") (90 . 2) (70 . 129) (43 . 0.0))
; 90 = # of vertices, 70 1 bit = closed 128 bit = ltype gen. on, 43 = global width
(list
(cons 38 (caddr cctr)); elevation in OCS above WCS origin [Z of Circle center]
'(40 . 0.0) '(41 . 0.0) '(42 . 1); 0 width, semi-circle bulge factors
'(40 . 0.0) '(41 . 0.0) '(42 . 1)
cextdir ; extr. dir. at end [if in middle, reverts to (210 0.0 0.0 1.0) in (entmake)]
); end list
); end append & pdata
); end setq
(entmake pdata)
(entdel cir); [remove or comment out this line to retain selected Circle]
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
(princ)
); end defun

;;  P2C
;;  To convert a selected closed two-equal-arc-segment global-width circular
;;  Polyline [Donut] to a true Circle.  If selected Polyline has non-zero global
;;  width, offers User option to draw Circle along center-line or along inside or
;;  outside edge of width, and retains choice as default for next use.
;;  Works on both old-style "heavy" and newer "lightweight" Polylines.
;;  [Will not work on one with more than two segments, or with two unequal-
;;  included-angle segments, even if truly circular.]
;
(defun C:P2C (/ *error* cmde psel pl pdata pwidadj cposdef cpostemp pv1 pv2 cdata)
(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg))
); end if
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
); end defun - *error*
(setq cmde (getvar 'cmdecho))
(setvar 'cmdecho 0)
(command "_.undo" "_begin")
(prompt "\nTo convert a Polyline circle to a true Circle,")
(while
(not
(and
(setq psel (ssget ":S" '((0 . "*POLYLINE"))))
(if psel (setq pl (ssname psel 0) pdata (entget pl)))
(= (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 pdata))))) 0)
; 0 for Unlocked, 4 for Locked
(if (= (cdr (assoc 0 pdata)) "POLYLINE"); "heavy" Polyline
(progn; then
(command "_.convertpoly" "_light" pl ""); retains same entity name
(setq pdata (entget pl)); replace "heavy" Polyline entity data
); end progn
T; else - to not return nil for LWPolyline
); end if
(member '(90 . 2) pdata); two vertices
(member '(42 . 1.0) (cdr (member '(42 . 1.0) pdata))); two half-circle bulge factors
; needs to be really precise -- will be for one made with Donut,
; but may not be for one made with, for example, Pline [pt] Arc
; Direction [direction] [halfway around] Close, even with Snap on
); end and
); end not
(prompt "\nNothing selected, or not a circular Polyline [Donut], or on a Locked Layer.")
); end while
(if (and (assoc 43 pdata) (/= (cdr (assoc 43 pdata)) 0)); global non-zero width
(progn; then
(initget "Center Inside Outside")
(setq
pwidadj (/ (cdr (assoc 43 pdata)) 2)
cposdef (cond (_P2Ccpos_) (T "Center")); Center default on first use
cpostemp
(getkword
(strcat
"\nCircle position on Donut [Center/Inside/Outside] <"
(substr cposdef 1 1)
">: "
); end strcat
); end getkword & cpostemp
_P2Ccpos_ (cond (cpostemp) (cposdef))
); end setq
); end progn
); end if
(setq
pv1 (cdr (assoc 10 pdata)); = Polyline Vertex 1 [XY]
pv2 (cdr (assoc 10 (cdr (member (assoc 10 pdata) pdata)))); = Polyline Vertex 2 [XY]
; can't use parameter XYZ WCS locations, because cdata needs XY OCS locations
cdata (vl-remove-if-not '(lambda (x) (member (car x) '(67 410 8 62 6 48 370 39))) pdata)
; build circle entity data list -- remove Polyline-specific entries from
; Polyline's entity data, and extrusion direction; 62 Color, 6 Linetype, 48
; LTScale, 370 LWeight, 39 Thickness present only if not default/bylayer
cdata
'((0 . "CIRCLE") (100 . "AcDbEntity"))
cdata ; remaining non-entity-type-specific entries
(list
'(100 . "AcDbCircle")
(list
10 ; center
(/ (+ (car pv1) (car pv2)) 2); X = halfway between X's of vertices
(/ (+ (cadr pv1) (cadr pv2)) 2); Y = halfway between Y's of vertices
(cdr (assoc 38 pdata))); Z of Circle = elevation of Pline
(cons
(+
(/
(distance; diameter -- needs 3D points for 3D distance
(vlax-curve-getStartPoint pl)
(vlax-curve-getPointAtParam pl 1)
); end distance
2
); end /
(cond
(T 0); Pline with width & Center option, or no width/no position prompt
); end cond
); end +
); end cons
(assoc 210 pdata); extr. dir. at end [if in middle, reverts to (210 0.0 0.0 1.0) in (entmake)]
); end list
); end append & cdata
); end setq
(entmake cdata)
(entdel pl)
; [remove or comment out above line to retain selected
; Polyline -- will be left lightweight if originally heavy]
(command "_.undo" "_end")
(setvar 'cmdecho cmde)
(princ)
); end defun
(prompt "\nType C2P to convert a Circle to its Polyline equivalent.")
(prompt "\nType P2C to convert a circular Polyline to its Circle equivalent.")```

That's the LISP I have, it came from CADALYST.

##### Share on other sites
Actually, it was pretty simple to add the function. I just added a single line of code at the end of dtkell's routine, before the (princ).

(command "_.pedit" (entlast) "w" pause "")

Now it does what I want.

I'll have to check that out, thanks!

##### Share on other sites
I'll have to check that out, thanks!

Just to be clear, there are two functions inside this routine. One is the C2P function which converts the circle to polyline. The other is the P2C function which does something else. I'm only concerned with the C2P function, so I added the line of code at the end of that section. See below.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.