Author Topic: draw ellipse  (Read 938 times)

0 Members and 1 Guest are viewing this topic.

DanB

  • Bull Frog
  • Posts: 367
draw ellipse
« on: June 13, 2022, 01:30:19 PM »
Having trouble with what I think should be pretty basic. I have 2 parallel lines, first point desired is pick nearest point on line; second point is perpendicular on second line; ellipse is drawn between lines; minor axis is 1/4 of major axis. When I utilize any of the osnap lines of code, the ellipse is drawn correctly but placed at wrong location on the line. Any suggestions?

Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun myerror (s)
  (if (/= s "Function cancelled")
    (princ (strcat "\nError: " s))
  )
  (setvar "osmode" oldos)
  (setvar "cmdecho" oldecho)
  (setq *error* olderr) ; Restore old *error* handler
  (princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun c:test (/ oldecho oldos pnt1 pnt2 axismaj axismin)

  (setq olderr *error*
*error* myerror
  )
  (setq oldecho (getvar "cmdecho"))
 ; (setvar "cmdecho" 0)
 ; (setq oldos (getvar "osmode"))
 
  (setvar "osmode" 512)
  (setq pnt1 (getpoint "\nFirst Point: "))
  (setvar "osmode" 128)
  (setq pnt2 (getpoint "\nSecond Point: " pnt1))
  (setq axismaj (distance pnt1 pnt2))
  (setq axismin (/ axismaj 4.0))
  ;(command "_ellipse" pnt1 pnt2 (/ (distance pnt1 pnt2) 4.0))
  (command "_ellipse" pnt1 pnt2 (/ axismin 4.0))

  (setvar "cmdecho" oldecho)
 ; (setvar "osmode" oldos)
  (princ)
)

DanB

  • Bull Frog
  • Posts: 367
Re: draw ellipse
« Reply #1 on: June 13, 2022, 02:15:47 PM »
Think I found a solution, although I am still unclear why it was not functioning correctly. The correction is to simply set OSMODE zero before running ellipse command line.

Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun myerror (s)
  (if (/= s "Function cancelled")
    (princ (strcat "\nError: " s))
  )
  (setvar "osmode" oldos)
  (setvar "cmdecho" oldecho)
  (setq *error* olderr) ; Restore old *error* handler
  (princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun c:test (/ oldecho oldos pnt1 pnt2 axismaj axismin)

  (setq olderr *error*
*error* myerror
  )
  (setq oldecho (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (setq oldos (getvar "osmode"))
 
  (setvar "osmode" 512)
  (setq pnt1 (getpoint "\nFirst Point: "))
  (setvar "osmode" 128)
  (setq pnt2 (getpoint "\nSecond Point: " pnt1))
  (setvar "osmode" 0)   ;;;;<<<<<<<<<<<<<<<ADDED THIS LINE
  (command "_ellipse" pnt1 pnt2 (/ (distance pnt1 pnt2) 4.0))

  (setvar "cmdecho" oldecho)
  (setvar "osmode" oldos)
  (princ)
)

Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: draw ellipse
« Reply #2 on: June 13, 2022, 03:18:50 PM »
You can replace the system variable osmode via adding either of the two strings "_non" or "_none" in prior of the variable that represents coordinates to let the command ignores the osmode settings so you will reduce the quantity of codes and eradicate the error function from the program.

hmspe

  • Bull Frog
  • Posts: 362
Re: draw ellipse
« Reply #3 on: June 13, 2022, 03:45:52 PM »
The ellipse command honors whatever osnaps are active when you feed a point to the command.  In this case you left the perpendicular osnap active.  Adding the line setting OSMODE to zero meant the ellipse command used the points "as is" rather than snapping to (in this case) a perpendicular osnap point.

(command "_ellipse" "_non" pnt1 "_non" pnt2 (/ (distance pnt1 pnt2) 4.0))  would be another option.  Each "_non" cancels any active osnap for the following point only.

I create ellipses using ENTMAKEX.
Code: [Select]
(defun c:test2 (/ oldecho oldos pnt1 pnt2 axismaj axismin)

  (defun *error* (msg)
    (if (/= s "Function cancelled")
      (princ (strcat "\nError: " s))
    )
    (setvar "osmode" oldos)
    (setvar "cmdecho" oldecho)
    (princ)
  )

  (setq oldecho (getvar "cmdecho"))
  (setq oldos (getvar "osmode")) 
  (setvar "osmode" 512)
  (setq pnt1 (getpoint "\nFirst Point: "))
  (setvar "osmode" 128)
  (setq pnt2 (getpoint "\nSecond Point: " pnt1))
  (setq ellipse_center (list (/ (+ (car pnt1) (car pnt2)) 2.0) (/ (+ (cadr pnt1) (cadr pnt2)) 2.0)))
  (setq major_axis_point (polar '(0 0 0) (+ (angle pnt2 pnt1) (/ pi 2.0)) (* (distance pnt2 pnt1) 2.0)))
  (setq axis_ratio 0.25)
  (entmakex (list (cons 0 "ELLIPSE")
                  (cons 100 "AcDbEntity")
                  (cons 100 "AcDbEllipse")
;                  (cons 6 linetype)
;                  (cons 8 layer)
                  (cons 10 ellipse_center)
                  (cons 11 major_axis_point)
                  (cons 40 axis_ratio)
                  (cons 41 0.0)
                  (cons 42 (* PI 2.0))
;                  (cons 62 color)
            )
  )
  (setvar "cmdecho" oldecho)
  (setvar "osmode" oldos)
  (princ)

ENTMAKEX is faster than using COMMAND and it avoids the osnap issue.  I commented out the lines where you could set linetype, layer, or color if you didn't want to use the active defaults.  I moved the *error* definition inside the function.  *error* is automatically set up (at least in Bricscad) so you don't have to manually set and restorethe error handler.

The tricky part of using ENTMAKEX for an ellipse is the major axis point.  The angle and distance are the same as for a vector from the ellipse center to a point where the major axis crosses the ellipse, but the point is calculated from the origin. 


"Science is the belief in the ignorance of experts." - Richard Feynman

DanB

  • Bull Frog
  • Posts: 367
Re: draw ellipse
« Reply #4 on: June 13, 2022, 04:40:00 PM »
Thank you both for your replies.

This:
Quote
"(command "_ellipse" "_non" pnt1 "_non" pnt2 (/ (distance pnt1 pnt2) 4.0))  would be another option.  Each "_non" cancels any active osnap for the following point only."
was very helpful. The entmakex function is a lot more for me to digest.

didier

  • Newt
  • Posts: 48
  • expatrié
Re: draw ellipse
« Reply #5 on: June 14, 2022, 05:17:35 AM »
Bonjour

You write : The entmakex function is a lot more for me to digest.
I will try an explanation for you :
  • Command makes an entity as you were drawing on screen
    Entmake creates a list, and AutoCAD interprets the list as an entity and draw it.

Amicalement
eternal beginner ...
my english is not fluent ...

tombu

  • Bull Frog
  • Posts: 289
  • ByLayer=>Not0
Re: draw ellipse
« Reply #6 on: June 14, 2022, 11:22:10 AM »
Code: [Select]
(defun c:test2 (/ *error* oldecho oldos pnt1 pnt2 axismaj axismin)

I moved the *error* definition inside the function.  *error* is automatically set up (at least in Bricscad) so you don't have to manually set and restorethe error handler.
*error* is automatically defined in AutoCAD as well but you need to add *error* as a local variable when using a definition inside a lisp routine so it doesn't affect how the *error* function works in other lisp.
Tom Beauford P.S.M.
Leon County FL Public Works - Windows 7 64 bit AutoCAD Civil 3D