TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Robert_s 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.
-
How would you place and size the first circle?
What increments would you assign to the + - keys?
-
Hi Cab,
For initial size..24"
Increments..4"
Thank you.
-
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.
-
How about this?
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)
Additions
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).
-
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:
(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.
-
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.
(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
-
Alan, you might want to allow for key 61 (=), as that can be counted as "+".
-
Thanks Cad & Lee
..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.
-
Robert,
You can combine the two routines in this thread to acheave your goal.
-
Not as elegant as Alan's, but I'm not as experienced as him :oops:
(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))
-
Thank you Lee!!!..Thank you Cab!!!
-
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
-
Thanks Ron.
Am I right in thinking that that "shift" using (cdr) and attaching the (car) covers up the "gaps" in the circle?
-
Thanks Ron.
Am I right in thinking that that "shift" using (cdr) and attaching the (car) covers up the "gaps" in the circle?
Exactly :-)