draw a circle with lisp.. (visually)

Discussion in 'AutoCAD' started by C Witt, Sep 27, 2004.

  1. C Witt

    C Witt Guest

    I'm trying to replicate a feature of the circle command..

    when you go to draw a circle it "draws" the circle as you go through the
    prompts..

    (just as line does that with a line..)

    Now I know how to replicate the line method.. but how can I replicate
    the circle behavior?
     
    C Witt, Sep 27, 2004
    #1
  2. C Witt

    C Witt Guest

    umm.. ok.. not what I asked....

     
    C Witt, Sep 27, 2004
    #2
  3. C Witt

    BillZ Guest

    Here an routine that I've played with.

    ;Bill Zondlo
    ;program to get input
    ;and show drag.
    ;
    ;----------------;
    (defun fig_pts ()
    (setq ct (cadr pt3)
    inc 0
    d1 (distance pt1 (cadr pt3))
    ang (* pi 2.0) ;;(angle pt1 (cadr pt3))
    nm (fix (/ ang deg))
    p2 (polar pt1 inc d1)
    )
    ;---------------;
    (repeat nm ;
    (setq p1 (polar pt1 inc d1)
    inc (+ inc deg)
    p2 (polar pt1 inc d1)
    lst (append lst (list p1 p2)) ;grvecs points.
    )
    ) ;end repeat.
    (setq sl (append sl (list pt1 ct)) ;center to point line.
    p3 (polar pt1 ang d1)
    lst (append lst (list p2 p3))
    lst (cons 256 lst) ;add color to list
    lss lst
    sl (cons 256 sl) ;add color
    sh sl
    )
    )
    ;---------------;
    (defun c:show_drag_circle (/ )
    (initget 1)
    (setq pt1 (getpoint "\nSelect Base Point:") ;select
    dif 0
    deg (/ (* pi 2.0) 36.0) ;10 degree increments
    )
    ;---;
    (prompt "\nNext point:")
    (while (/= (car (setq pt3 (grread 'T 1 0))) 3)
    (setq dif (1+ dif)
    )
    (cond ((= dif 1)
    (fig_pts)
    (grvecs lst) ;draw lines
    (grvecs sl)
    (setq lst nil
    sl nil)
    )
    ((= dif 2)
    (grvecs lss) ;cover lines
    (grvecs sh)
    (setq lss nil
    sh nil
    dif 0)
    )
    )
    ) ;end while
    ;---;
    (grvecs lss) ;cover lines
    (grvecs sh)
    (princ)
    ) ;end defun


    HTH

    Bill
     
    BillZ, Sep 27, 2004
    #3
  4. C Witt

    Jeff Mishler Guest

    But, short of C++ and ObjectArx, it's about the only answer.......
     
    Jeff Mishler, Sep 27, 2004
    #4
  5. C Witt

    Jim Dee Guest

    uhh... I went back and read your question again, and it still sounds like
    you're asking how to show the circle as you draw it and prompt for user
    input within a lisp. In other words show the circle changing size as you
    drag the mouse. If this is not what you're asking, then I suggest you
    rephrase your question a bit to make it more clear.

    Your Welcome,

    Jim Dee
    www.caddee.com
     
    Jim Dee, Sep 27, 2004
    #5
  6. C Witt

    Tom Smith Guest

    Some of the things that we take for granted with built-in commands --
    rubberbanding, dragging, ghosting, etc. -- are all but impossible to
    replicate, in lisp, for anything but a simple line. And even then, it's
    doubtful whether the programming overhead is worth it.

    As Bill shows, you could conceivably use grvecs to get an acceptable polygon
    approximation of a circle. But that's not gonna help on an ellipse.

    These are cases where you either accept the use of the built-in command, or
    else approach your Acad customizations in a much deeper and more complicated
    way -- the C++ solution.

    If you'd describe the scenario in more detail, maybe somebody could suggest
    a workaround. For instance, if you don't really want to draw a circle
    entity, but just want the interactive look for another purpose, why not use
    Jim's simple solution, then delete the circle?
     
    Tom Smith, Sep 27, 2004
    #6
  7. C Witt

    Jim Claypool Guest

    But as Jim Dee pointed out (command ".circle" pause pause) does show the
    circle as you move the cursor. At least it will if dragmode is on.
     
    Jim Claypool, Sep 27, 2004
    #7
  8. C Witt

    C Witt Guest

    the whole reason for this post is so i can use my own interface.. and
    then call up the built-in command with my variables..

    but I need a way of doing the ghost circle, so the end user won't see a
    difference.

    (that a better explanation?)
     
    C Witt, Sep 27, 2004
    #8
  9. C Witt

    Jim Claypool Guest

    Can you post what you have so far?
     
    Jim Claypool, Sep 27, 2004
    #9
  10. C Witt

    C Witt Guest

    at the moment it's all in my head.. I won't "write" it down till i know
    it can be done (why waste the time?).
     
    C Witt, Sep 27, 2004
    #10
  11. C Witt

    Tom Smith Guest

    We seem to be mostly saying the same thing -- we don't know a way to ghost the circle comparable to what the native command does, without calling the command.

    The same issue comes up in placing a block. You can't get the ghosted visualization without starting the insert command. Maybe you predetermine some variables otherwise, like block name and scale factor. But to get the ghost you gotta run the command, feed it those variables, and at some point do a pause, to let the user see the ghost.

    Again, if you could reveal more specifically what you're trying to do, someone might have a workaround.
     
    Tom Smith, Sep 28, 2004
    #11
  12. C Witt

    Doug Broad Guest

    C,
    That sounds like a really odd way to respond to those trying
    to help you. The implied message is that its OK to waste
    other peoples time.

    What is in your head? Is it? a) The idea of what you want to happen.
    b) Some idea of how to accomplish it.

    It's reasonable to assume that those who've tried to help you
    on this thread don't understand what you need. It might help
    if you were to explain how your interface would be different
    than that provided by AutoCAD. We all know how the
    circle command works. How would it work differently for you?

    The autocad express tools contain subfunctions that ghost
    certain actions. You might look inside those to learn how
    Autodesk implemented some of these tasks with lisp.

    Regards,
    Doug
     
    Doug Broad, Sep 28, 2004
    #12
  13. C Witt

    C Witt Guest

    that was not what I ment.. and by posting I had hoped to find someone
    else who had done it (thus not a waste of anyone's time)..

    but as I haven't put anyting to paper (so to speak).. I've attached my
    offset command.. (same concept of an "overlay".. using my own vars)..

    I hope this give you a better idea of what i'm after.. (and helps mend
    the fence I seem to have pushed over).

    (defun c:eek:ffset (/ tesffo osetpoint OBSEL oset decim decimloc divi decimal isfoot subinch subfoot desscale)
    (setvar "cmdecho" 0)
    (setq PERROR *error*)
    (setq *error* ETRAPO)
    (setq dimset (CDR (ASSOC 1 (dictsearch (namedobjdict) "XRECLIST"))))
    (if (= dimset nil)
    (if (= (getvar "lunits") 2)(setq tarunit 25.4)(setq tarunit 1))
    (if (= (substr dimset 4 1) "M")(setq tarunit 25.4)(setq tarunit 1))
    )
    (if (= osetdist nil)
    (setq osetdist 0)
    )
    (while (/= tesffo 1)
    (initget 128)
    (setq oset (getdist (strcat "\nSpecify offset distance or [Through] <" (rtos osetdist) ">: ")))
    (cond
    ((or (= (type oset) 'INT)(= (type oset) 'REAL))
    (setq tesffo 1)
    )
    ((= oset nil)
    (setq tesffo 1)
    )
    ((= (type oset) 'STR)
    (progn
    (SETQ desscale (distof oset 4))
    (if (/= desscale nil)
    (progn
    (setq tesffo 1)
    (setq desscale (* tarunit desscale))
    (setq osetdist desscale)
    (setq oset osetdist)
    )
    )
    )
    )
    )
    )
    (if (= oset nil)
    (setq osetdist osetdist)
    (setq osetdist oset)
    )
    (setvar "errno" 0)
    (while (= obsel nil)
    (setq obsel (entsel "\nSelect object to offset or <exit>: "))
    (if (= (getvar "errno") 52)
    (exit)
    )
    )
    (setvar "errno" 0)
    (while (= osetpoint nil)
    (setq osetpoint (getpoint "\nSpecify point on side to offset: "))
    (if (= (getvar "errno") 52)
    (exit)
    )
    )
    (command ".offset" osetdist obsel osetpoint)(PRINC)
    (setvar "cmdecho" 1)(princ)
    )

    (defun ETRAPO (msg)
    (setvar "cmdecho" 0)
    (if (or (= msg "Function cancelled") (= msg "quit / exit abort"))
    (princ)
    (princ (strcat "\nError: " msg))
    )
    (setq tesffo nil)
    (setq obsel nil)
    (setq oset nil)
    (setq isfoot nil)
    (prompt "\n")
    (setq *error* PERROR)
    (setvar "cmdecho" 1)
    (princ)
    )
     
    C Witt, Sep 28, 2004
    #13
  14. C Witt

    BillZ Guest

    BillZ, Sep 28, 2004
    #14
  15. C Witt

    BillZ Guest

    Reply From: Tom Smith<<<
    ;Bill Zondlo
    ;program to get input
    ;and show drag.
    ;
    ;----------------;
    (defun fig_ell (/ pst pstt ptt pttt spt stt)
    (setq pt3 (cadr pt3) ;point
    ds2 (distance pt1 pt3) ;short axis length
    deg (/ (* pi 2.0) nm1) ;10 degree increments
    )
    (repeat nm1 ;full circle div/10.
    (setq pst (+ (car pt1)(* ds1 (cos inc))) ;formula
    pstt (+ (cadr pt1)(* ds2 (sin inc))) ;of ellipse
    spt (list pst pstt) ;point from center.
    an1 (angle pt1 spt) ;angle from 0d.
    spt (polar pt1 (+ ang an1)(distance pt1 spt)) ;
    inc (+ inc deg) ;next angle
    ptt (+ (car pt1)(* ds1 (cos inc))) ;formula
    pttt (+ (cadr pt1)(* ds2 (sin inc))) ;of ellipse
    stt (list ptt pttt) ;point
    an2 (angle pt1 stt) ;angle from 0d.
    stt (polar pt1 (+ ang an2)(distance pt1 stt)) ;
    lst (append lst (list spt stt))
    )
    ) ;end repeat
    (setq lst (cons 256 lst) ;add xor color to front of list.
    lt1 lst ;draw over lst
    pt4 pt3) ;draw over point.
    )
    ;----------------;
    (defun c:show_drag_ellipse (/ an1 an2 an3 ang deg dif ds1 ds2 e inc lst lt1 nm1 pt1 pt2 pt3 pt4)
    (initget 1)
    (setq pt1 (getpoint "\n<Center of Ellipse >: ")
    )
    ;--;
    (initget 1)
    (setq pt2 (getpoint pt1"\n<Axis endpoint: > ") ;select
    )
    ;---;
    (setq ang (angle pt1 pt2)
    nm1 60
    ds1 (distance pt1 pt2)
    deg (/ (* pi 2.0) nm1) ;10 degree increments
    dif 0 ;counter
    )
    ;---;
    (prompt "\n<Other axis distance> ")
    ;---;
    (setq e 1)
    (while (and (/= (car (setq pt3 (grread 'T 1 0))) 3) e)
    (setq dif (1+ dif)
    )
    (cond ((and (= dif 1)
    (= (car pt3) 5)
    )
    (setq inc 0) ;start at end of ellipse.
    (fig_ell) ;ghost ellipse
    (grdraw pt1 pt3 -1) ;draw center line
    (grvecs lst) ;draw ellipse
    (setq lst nil)
    )
    ((and (= dif 2)
    (= (car pt3) 5))
    (grdraw pt1 pt4 -1) ;cover center line
    (grvecs lt1) ;cover ellipse
    (setq lt1 nil
    dif 0)
    ) ;end list
    (t (setq e nil
    dif 0)) ;other key strokes.
    ) ;end cond
    ) ;end while
    ;---;
    (if (= dif 1) ;
    (grdraw pt1 pt4 -1)
    )
    (grvecs lt1)
    (setq lt1 (cdr lt1))
    (princ)
    ) ;end main defun


    I'm not trying to be obnoxious......really. :)


    Bill
     
    BillZ, Sep 28, 2004
    #15
  16. C Witt

    Tom Smith Guest

    Bravo, Bill! Now do an arbitrary spline. :)

    Until the current generation of computers, of course, this would have been nightmarishly slow -- maybe that's why they didn't give us anything beyond vector drawing capabilities in designing the gr* functions. A grcircle function would have been just the thing for the OP.

    I'd put this in that gray area of not literally impossible, if you accept some limitations on approximating the curve, but not something I'd ever want to do either, because of inordinant code overhead as compared to something like (command "ellipse" pause etc). There would need to be overwhelming reasons (functional rather than preferential) for avoiding the command function before I'd go down this road. But that's just me.

    As I suggested, there have been times I've used a command function just to get the qhost visualization, then deleted the resultant entity and continued with whatever I really wanted to do.
     
    Tom Smith, Sep 28, 2004
    #16
  17. C Witt

    MP Guest

    very cool dude!
    :)

     
    MP, Sep 28, 2004
    #17
  18. C Witt

    BillZ Guest

    Tom,
    I agree whoeheartedly with your philosiphy,
    What I posted are basically "parlor tricks" that were fun to play while creating but actually have the inherent limitations of grread when you try to add osnaps and other options not to mention cleaning up after a cancel or other error.

    I was kinda proud of myself when I figured out the ellipse formula by myself which was the orginal program that I started using grread with.

    I did spend some time figuring out splines but that's a whole 'nother discussion.

    Thanks MP!

    Bill
     
    BillZ, Sep 28, 2004
    #18
  19. C Witt

    Tom Smith Guest

    I was kinda proud of myself when I figured out the ellipse formula

    Rightfully so. I went through something similar on a routine which needed to
    divide various entities into segments. It began with lines, but then more
    requests started coming in The math was trivial on a line, just a little
    trickier on an arc or circle, a rather huge pain on an ellispse. Not being
    quite as persistent as you :) I went "whoa" before I got the ellipse
    algorithm perfected, and backed off to a whole different approach. Figured
    out a hack using the divide command, which would work the same on any
    divisible entity.

    Then found a v-lispy trick on afralisp for getting the curve length of just
    about any entity, and that allowed a slightly quicker algorithm for
    returning a list of division points along an arbitrary curve. It's slightly
    less code than my previous recursive command algorithm, but arguably a lot
    less clear, so it's a wash IMHO as far as which is preferable. I'll crunch
    the math if I have to, but if I can make Acad do it for me, so much the
    better!
     
    Tom Smith, Sep 28, 2004
    #19
  20. C Witt

    Jim Claypool Guest

    I give up!
     
    Jim Claypool, Sep 28, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.