### Author Topic: Draw a circle dynamically  (Read 8016 times)

0 Members and 1 Guest are viewing this topic.

#### Robert_s

• Guest
##### Draw a circle dynamically
« on: June 17, 2009, 08:46:36 AM »
Hello,

I am trying to find and learn from code that will allow me to draw a circle dynamically.

Before placing the circle I would like to use  the keyboard's  "+" key to increase the
size/diameter or the "-" to decrease the size/diameter dynamically.

I've seen one here but it was too complicated from me. Any help would be appreciated.

#### CAB

• Global Moderator
• Seagull
• Posts: 10401
##### Re: Draw a circle dynamically
« Reply #1 on: June 17, 2009, 08:58:20 AM »
How would you place and size the first circle?
What increments would you assign to the + - keys?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### Robert_s

• Guest
##### Re: Draw a circle dynamically
« Reply #2 on: June 17, 2009, 09:04:00 AM »
Hi Cab,

For initial size..24"
Increments..4"

Thank you.

#### CAB

• Global Moderator
• Seagull
• Posts: 10401
##### Re: Draw a circle dynamically
« Reply #3 on: June 17, 2009, 09:46:11 AM »
The way a routine / procedure is created is to establish rules & steps with sequence.

Rules:
Starting Size:  0.24  ? diameter or Radius ?
Increment Size:    ? diameter or Radius ?
Minimum Size? nn  ? diameter or Radius ?
Maximum Size? nn  ? diameter or Radius ?
Allowable keyboard entries + - Enter Esc
Action for each Allowable Key?
Action for disallowed keys?
Layer to use:  Current Layer

Steps: [ Pseudo Code ]
User picks center point
Draw the Starting circle
Get user input [ + or - or EnterKey ]
Action for + Key: Draw a larger circle
Action for - Key: Draw a smaller circle
Action for Enter Key: End Program

How would you change these & answer any that are incomplete.
« Last Edit: June 17, 2009, 09:52:57 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### Robert_s

• Guest
##### Re: Draw a circle dynamically
« Reply #4 on: June 17, 2009, 10:14:06 AM »

Rules:
Starting Size:  0.24  ? diameter or Radius ?     24" Diameter.
Increment Size:    ? diameter or Radius ?        2" Diameter.
Minimum Size? nn  ? diameter or Radius ?        none...Action for Enter Key: End Program.
Maximum Size? nn  ? diameter or Radius ?       none...Action for Enter Key: End Program.
Allowable keyboard entries + - Enter Esc        please add "D" for Diameter. So user can keyin a desired diameter instead.
Action for each Allowable Key?                     see "Steps".
Action for disallowed keys?                          prompt "Invalid selection".

Steps: [ Pseudo Code ]
User picks center point
Draw the Starting circle
Get user input [ + or - or EnterKey ]
Action for + Key: Draw a larger circle
Action for - Key: Draw a smaller circle
Action for Enter Key: End Program......(Draw the circle)

Action for Esc: Cancel the program
Action for letter "D": user is allow to key-in a desired diameter instead.
Action for "Space Bar": Same as Action for enter (End program).

#### Lee Mac

• Seagull
• Posts: 12892
• London, England
##### Re: Draw a circle dynamically
« Reply #5 on: June 17, 2009, 10:33:17 AM »
You could look into the GRREAD and GRVECS functions.

For example, to get you started, to draw a simple circle using a combination of GRREAD and GRVECS, look at the example below:

Code: [Select]
`(defun c:test (/ gr lst i)  (while (not (eq 3 (car (setq gr (grread t 7 0)))))    (redraw)    (setq lst nil i 0)    (repeat 300      (setq lst        (cons          (polar (cadr gr)                 (* i (/ pi 150))                 (/ (getvar "VIEWSIZE") 20))          lst))      (setq i (1+ i)))    (grvecs (append '(3) (reverse lst))))  (princ))`
In Pseudo code:

WHILE the user doesn't click a point
Set the variables to nil
Construct a list of points forming a "circle" (constructed from 300 segments)
Append the list with the colour (3 in this case), and display it with GRVECS.

#### CAB

• Global Moderator
• Seagull
• Posts: 10401
##### Re: Draw a circle dynamically
« Reply #6 on: June 17, 2009, 11:10:37 AM »
Robert,
There must be a minimum circle size & the layer must be addressed.

Here is a routine but I left out the D for user input. I expect you to complete that section.

Code: [Select]
`(defun c:MyCircle (/ CIRCLEDIAM CIRCLEENT CPT GRR KEY MAXDIAM MINDIAM                   MSG STEPSIZE CircleLay)  ;;  sub to make a circle & return the ename  (defun MakeCircle (cen rad lay)    (entmakex      (list        (cons 0 "CIRCLE")        (cons 6 "BYLAYER")        (cons 8 lay)          ; layer        (cons 10 cen)        (cons 39 0.0)        (cons 40 rad)         ; radius        (cons 62 256)        (cons 210 (list 0.0 0.0 1.0))      )    )  )  (setq CircleDiam 24.0       ; this is the starting size for the circle        StepSize   4.0        MinDiam    4.0        MaxDiam    0        CircleLay  (getvar "clayer")          CircleEnt  nil         ; this is the ename for the circle  )  (setq cpt (getpoint "\nPick the center point for circle."))  (setq msg "\nUse + - keys to change size. D to enter. Enter to quit. :")  (if cpt                     ; draw the first circle    (progn      ;;  Loop reading keyboard using grread      (while                  ; get the string from user, exit only for ENTER        (progn          (if (or (null CircleEnt) (null (entget CircleEnt)))            (progn              (setq CircleEnt (makeCircle cpt (/ CircleDiam 2.0) CircleLay))              (princ (strcat "\nCircle diameter is " (rtos CircleDiam 2 2)))              (princ msg)            )          )          (cond            ((eq 2 (car (setq grr (grread t 7 0)))) ; keyboard input             (setq key (cadr grr))             (cond               ((= key 43)    ; + key                (if (or (zerop MaxDiam) (<= (+ CircleDiam StepSize) MaxDiam))                  (progn      ;  increase circle size                    (setq CircleDiam (+ CircleDiam StepSize))                    (entdel CircleEnt) ; remove old circle                  )                  (princ "\nCircle has reached Maximum size.")                )                t             ;stay in loop               )               ((= key 45)    ; - key                (if (>= (- CircleDiam StepSize) MinDiam)                  (progn      ;  decrease circle size                    (setq CircleDiam (- CircleDiam StepSize))                    (entdel CircleEnt) ; remove old circle                  )                  (princ "\nCircle has reached Minimum size.")                )                t             ;stay in loop               )               ((member key '(68 100)) ; D or d for user entry of Diameter                (princ "\nThis function is under construction. :)\n")               )               ((or (= key 13) (= key 32)) ; ENTER or Spacebar - where done here                (princ "\nUser Quit.")                nil           ; exit loop               )               ((princ "\nInvalid Keypress.") (princ msg))             )                ; end cond            )            (t t) ; no valid input, stay in loop          )        )      )                       ; while    )  )  (princ)                     ; exit quietly)(prompt "\nMy Circle Lisp loaded. Enter MyCircle to run.")(princ)                       ; kill echo to command line from last function`
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### Lee Mac

• Seagull
• Posts: 12892
• London, England
##### Re: Draw a circle dynamically
« Reply #7 on: June 17, 2009, 11:12:11 AM »
Alan, you might want to allow for key 61 (=), as that can be counted as "+".

#### Robert_s

• Guest
##### Re: Draw a circle dynamically
« Reply #8 on: June 17, 2009, 11:23:23 AM »

..Actually I was kinda thinking of a combination of both of your routines.
Wherein I change the circle's diameter dynamically on the screen "before"
I place it. I'm sorry if I did'nt explain it well.

#### CAB

• Global Moderator
• Seagull
• Posts: 10401
##### Re: Draw a circle dynamically
« Reply #9 on: June 17, 2009, 11:49:10 AM »
Robert,
You can combine the two routines in this thread to acheave your goal.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### Lee Mac

• Seagull
• Posts: 12892
• London, England
##### Re: Draw a circle dynamically
« Reply #10 on: June 17, 2009, 12:09:43 PM »
Not as elegant as Alan's, but I'm not as experienced as him

Code: [Select]
`(defun c:mycircle (/ *error* inc msg gr lst i flag tmp)  (vl-load-com)  (defun *error* (msg)    (redraw)    (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))      (princ (strcat "\n<< Error: " msg " >>"))      (princ "\n*Cancel*"))    (princ))    (or *Cir\$Dia* (setq *Cir\$Dia* 24.)) ; Initial Diameter  (setq Inc 2.)  ; Increment    (princ (setq msg "\n<< Position Circle [+] or [-] to Change [D]iameter >>"))  (while    (or      (and (setq gr (grread t 15 0))           (eq 5 (car gr)) (not flag))      (and (eq 2 (car gr))           (vl-position (cadr gr)             '(68 100 43 45 61 13 32)) (not flag)))    (redraw)    (cond ((and (eq 5 (car gr)) (listp (cadr gr)))           (setq lst nil i 0)           (repeat 300             (setq lst               (cons                 (polar (cadr gr)                        (* i (/ pi 150.))                        (/ *Cir\$Dia* 2.)) lst) i (1+ i)))           (grvecs (append '(6) lst (cdr lst) (list (car lst)))))          ((eq 2 (car gr)) ; Keyboard input           (cond ((vl-position (cadr gr) '(61 43)) ; +                  (setq *Cir\$Dia* (+ Inc *Cir\$Dia*)))                 ((eq 45 (cadr gr)) ; -                  (if (> *Cir\$Dia* Inc)                    (setq *Cir\$Dia* (- *Cir\$Dia* Inc))                    (progn                      (princ "\n<< Minimum Circle Diameter Reached >>")                      (princ msg))))                 ((vl-position (cadr gr) '(13 32))                  (setq flag T)                  (princ "\n<< User Quit >>"))                 ((vl-position (cadr gr) '(68 100)) ; D/d                  (initget 6)                  (if (setq tmp (getreal "\nSpecify Diameter: "))                    (setq *Cir\$Dia* tmp)))))))  (if (and (not flag) (listp (cadr gr)))    (entmakex      (list        (cons 0 "CIRCLE")        (cons 8 (getvar "CLAYER"))        (cons 10 (cadr gr))        (cons 40 (/ *Cir\$Dia* 2.))        (cons 62 6))))  (redraw)  (princ))`
« Last Edit: June 18, 2009, 06:02:34 AM by Lee Mac »

#### Robert_s

• Guest
##### Re: Draw a circle dynamically
« Reply #11 on: June 17, 2009, 12:19:25 PM »
Thank you Lee!!!..Thank you Cab!!!

#### ronjonp

• Needs a day job
• Posts: 7524
##### Re: Draw a circle dynamically
« Reply #12 on: June 17, 2009, 07:18:39 PM »
Lee,

FWIW...

If you use this for your vector list it will make it solid rather than dashed

(grvecs (append '(3) lst (cdr lst) (list (car lst))))

Ron

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

#### Lee Mac

• Seagull
• Posts: 12892
• London, England
##### Re: Draw a circle dynamically
« Reply #13 on: June 17, 2009, 09:28:25 PM »
Thanks Ron.

Am I right in thinking that that "shift" using (cdr) and attaching the (car) covers up the "gaps" in the circle?

#### ronjonp

• Needs a day job
• Posts: 7524
##### Re: Draw a circle dynamically
« Reply #14 on: June 17, 2009, 10:38:04 PM »
Thanks Ron.

Am I right in thinking that that "shift" using (cdr) and attaching the (car) covers up the "gaps" in the circle?

Exactly

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC