Ellipse to Gcode

Ellipse to Gcode

rpajounia
Advocate Advocate
2,083 Views
18 Replies
Message 1 of 19

Ellipse to Gcode

rpajounia
Advocate
Advocate

so i have an ellipse and im trying to convert it to a GCode for a cnc machine, im trying to update a auto method script but can figure out how the manufacturers outdated lisp code gets this information. So what it pretty much is, its getting the coordinates from the right side  going left and its suppose to draw it using my cnc machine. It outputs the code below. I know g90 and g03 meaning but i dont know where its getting all the x and y coorinates with the I and J. ( I and J are suppose to be middle coordinates of the circle/ellipse ) can anyone help me with getting the x and y this outputs?

 

G90 G92 X6073.000 Y2108.000
G03 X6063.018 Y2167.512 I-182.392 J-0.000
G03 X6035.803 Y2215.763 I-145.303 J-50.155
G03 X5993.393 Y2249.271 I-100.831 J-84.026
G03 X5946.000 Y2260.400 I-47.393 J-95.347
G03 X5898.607 Y2249.271 I0.000 J-106.475
G03 X5856.197 Y2215.763 I58.421 J-117.534
G03 X5828.982 Y2167.512 I118.088 J-98.406
G03 X5819.000 Y2108.000 I172.410 J-59.512

 

0 Likes
Accepted solutions (1)
2,084 Views
18 Replies
Replies (18)
Message 2 of 19

annoisscary
Advocate
Advocate

It looks to me that its interpolating the ellipse into a smaller set of arcs. I don't know if this is the CNC software that has written this or a lisp, most CNC's (hell, all of the ones I'm familiar with) will always do some form of interpolation on ellipses/splines. Don't have the time to take a crack at it but I would assume you could get similar results by changing the ellipse into a series or arcs and pulling the info from each segment. As the ellipse is in cad now, I think the only thing you would get would be the vertices and center for the ellipse which wouldn't run an ellipse with G03, but an arc.

0 Likes
Message 3 of 19

rpajounia
Advocate
Advocate

how can i get the arc points? when i do entget and output that it only gives me starting and ending point

0 Likes
Message 4 of 19

Sea-Haven
Mentor
Mentor

Have you looked at the formula for a ellipse ? You can work out any XY point on the ellipse so depending on step size is how small a straight will exist between points.  How critical is the curvature ? Google "ellipse formula autocad lisp". Pretty sure there is some code out there.

 

 

0 Likes
Message 5 of 19

komondormrex
Mentor
Mentor

half ellipse is divided into 8 parts and each part is approximated by arc. you may draw each arc by 3 three points: start, end and middle point between start point and end point then get the center offset from start point.

 

komondormrex_0-1683645773360.png

 

 

0 Likes
Message 6 of 19

rpajounia
Advocate
Advocate

My problem is getting those arc end, start, and mid point. Would you be able to tell me where you got that from?

0 Likes
Message 7 of 19

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

My problem is getting those arc end, start, and mid point. ....


[Maybe this isn't relevant to you if you don't have Arc objects to select, but....]

Entity data is not stored that way for an Arc, but what are stored are the center, radius, and the angles from center to the two ends.  You could calculate the endpoints from those, using (polar), and the midpoint by splitting the angle difference in half [being careful about the possibility of the range crossing the 0° direction].  Or for the ends, you could use (vlax-curve-getStartPoint) and (vlax-curve-getEndPoint) functions, and a more complex calculation using (vlax-curve-...) functions could get you the midpoint.

Kent Cooper, AIA
0 Likes
Message 8 of 19

komondormrex
Mentor
Mentor

you may get 'em using this

 

 

 

(setq approximation_steps 8.0
      ellipse_object (vlax-ename->vla-object (car (entsel)))
      ellipse_included_angle (- (vlax-curve-getendparam ellipse_object) (setq ellipse_start_param (vlax-curve-getstartparam ellipse_object)))
      ellipse_approximation_angle (/ ellipse_included_angle approximation_steps) 
)
(repeat (fix approximation_steps)
	(setq arc_start_point (vlax-curve-getpointatparam ellipse_object ellipse_start_param)
	      arc_middle_point (vlax-curve-getpointatparam ellipse_object (+ ellipse_start_param (* 0.5 ellipse_approximation_angle)))
	      arc_end_point (vlax-curve-getpointatparam ellipse_object (setq ellipse_start_param (+ ellipse_start_param ellipse_approximation_angle)))
	      arc_center_point (inters (setq aux_point_1 (polar arc_start_point (angle arc_start_point arc_middle_point) (+ (* 0.5 (distance arc_start_point arc_middle_point)))))   
				       (polar aux_point_1 (+ (* 0.5 pi) (angle arc_start_point arc_middle_point)) 5.0)
				       (setq aux_point_2 (polar arc_middle_point (angle arc_middle_point arc_end_point) (+ (* 0.5 (distance arc_middle_point arc_end_point)))))   
				       (polar aux_point_2 (+ (* 0.5 pi) (angle arc_middle_point arc_end_point)) 5.0)
				       nil
			       )
        )
  	(command "_point" "_non" arc_start_point)
  	(command "_point" "_non" arc_center_point)
)

 

 

0 Likes
Message 9 of 19

rpajounia
Advocate
Advocate

TY your amazing ill try this out in the next hour or so

0 Likes
Message 10 of 19

Sea-Haven
Mentor
Mentor

Still thinking better to just work out XY points depending on step size will be closer to an ellipse than doing say 3 arcs. 

 

This is a ellipse then used divide into 360 parts ie 1 degree, about 2 seconds.

SeaHaven_0-1683681434544.png

(defun c:ellipsepts ( / ss elst)
(command "divide" pause (getint "\nEnter number of increments "))
(setq ss (ssget '((0 . "POINT"))))
(setq elst '())
(repeat (setq x (sslength ss))
(setq elst (cons (cdr (assoc 10 (entget (ssname ss (setq x (1- x)))))) elst))
)
(setq elst (cons (cdr (assoc 10 (entget (ssname ss (- (sslength ss) 1))))) elst)) ; need last point again to close
(princ)
)
(c:ellipsepts)

 

Did 1440, 2880 etc at last value on a 300 ellipse that is 0.23mm steps.

0 Likes
Message 11 of 19

_gile
Consultant
Consultant
Accepted solution

Hi,

First, you can convert the ellipse to a polyline which is the same approximation as an ellipse drawn with the PELLIPSE system variable set to 1 with the following code:

 

 

;; EllipseToPolyline
;; Returns a polyline (vla-object) which is an approximation of the ellipse (or elliptical arc)
;;
;; Argument : an ellipse (vla-object)
 
(defun EllipseToPolyline (el    /     cl    norm  cen   elv   pt0   pt1   pt2   pt3   pt4   ac0
                          ac4   a04   a02   a24   bsc0  bsc2  bsc3  bsc4  plst  blst  spt   spa
                          fspa  srat  ept   epa   fepa  erat  n
                         )
  (vl-load-com)
  (setq cl   (= (ang<2pi (vla-get-StartAngle el))
                (ang<2pi (vla-get-EndAngle el)))
        norm (vlax-get el 'Normal)
        cen  (trans (vlax-get el 'Center) 0 norm)
        elv  (caddr cen)
        cen  (3dTo2dPt cen)
        pt0  (mapcar '+ (trans (vlax-get el 'MajorAxis) 0 norm) cen)
        ac0  (angle cen pt0)
        pt4  (mapcar '+ cen (trans (vlax-get el 'MinorAxis) 0 norm))
        pt2  (3dTo2dPt (trans (vlax-curve-getPointAtparam el (/ pi 4.)) 0 norm))
        ac4  (angle cen pt4)
        a04  (angle pt0 pt4)
        a02  (angle pt0 pt2)
        a24  (angle pt2 pt4)
        bsc0 (/ (ang<2pi (- a02 ac4)) 2.)
        bsc2 (/ (ang<2pi (- a04 a02)) 2.)
        bsc3 (/ (ang<2pi (- a24 a04)) 2.)
        bsc4 (/ (ang<2pi (- (+ ac0 pi) a24)) 2.)
        pt1  (inters pt0
                     (polar pt0 (+ ac0 (/ pi 2.) bsc0) 1.)
                     pt2
                     (polar pt2 (+ a02 bsc2) 1.)
                     nil
             )
        pt3  (inters pt2
                     (polar pt2 (+ a04 bsc3) 1.)
                     pt4
                     (polar pt4 (+ a24 bsc4) 1.)
                     nil
             )
        plst (list pt4 pt3 pt2 pt1 pt0)
        blst (mapcar '(lambda (b) (tan (/ b 2.)))
                     (list bsc4 bsc3 bsc2 bsc0)
             )
  )
  (foreach b blst
    (setq blst (cons b blst))
  )
  (foreach b blst
    (setq blst (cons b blst))
  )
  (foreach p (cdr plst)
    (setq ang  (angle cen p)
          plst (cons
                 (polar cen (+ ang (* 2 (- ac4 ang))) (distance cen p))
                 plst
               )
    )
  )
  (foreach p (cdr plst)
    (setq ang  (angle cen p)
          plst (cons
                 (polar cen (+ ang (* 2 (- ac0 ang))) (distance cen p))
                 plst
               )
    )
  )
  (setq pl
         (vlax-invoke
           (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
           'AddLightWeightPolyline
           (apply 'append
                  (setq plst
                         (reverse (if cl
                                    (cdr plst)
                                    plst
                                  )
                         )
                  )
           )
         )
  )
  (vlax-put pl 'Normal norm)
  (vla-put-Elevation pl elv)
  (mapcar '(lambda (i v) (vla-SetBulge pl i v))
          '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
          blst
  )
  (if cl
    (vla-put-Closed pl :vlax-true)
    (progn
      (setq spt  (vlax-curve-getClosestPointTo pl (vlax-get el 'Startpoint))
            spa  (vlax-curve-getParamAtPoint pl spt)
            fspa (fix spa)
            ept  (vlax-curve-getClosestPointTo pl (vlax-get el 'Endpoint))
            epa  (vlax-curve-getParamAtPoint pl ept)
            fepa (fix epa)
            n    0
      )
      (cond
        ((equal spt (trans pt0 norm 0) 1e-9)
         (if (= epa fepa)
           (setq plst (sublist plst 0 (1+ fepa))
                 blst (sublist blst 0 (1+ fepa))
           )
           (setq erat (/ (- (vlax-curve-getDistAtParam pl epa)
                            (vlax-curve-getDistAtParam pl fepa)
                         )
                         (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
                            (vlax-curve-getDistAtParam pl fepa)
                         )
                      )
                 plst (append (sublist plst 0 (1+ fepa))
                              (list (3dTo2dPt (trans ept 0 norm)))
                      )
                 blst (append (sublist blst 0 (1+ fepa))
                              (list (k*bulge (nth fepa blst) erat))
                      )
           )
         )
        )
        ((equal ept (trans pt0 norm 0) 1e-9)
         (if (= spa fspa)
           (setq plst (sublist plst fspa nil)
                 blst (sublist blst fspa nil)
           )
           (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
                            (vlax-curve-getDistAtParam pl spa)
                         )
                         (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
                            (vlax-curve-getDistAtParam pl fspa)
                         )
                      )
                 plst (cons (3dTo2dPt (trans spt 0 norm))
                            (sublist plst (1+ fspa) nil)
                      )
                 blst (cons (k*bulge (nth fspa blst) srat)
                            (sublist blst (1+ fspa) nil)
                      )
           )
         )
        )
        (T
         (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
                          (vlax-curve-getDistAtParam pl spa)
                       )
                       (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
                          (vlax-curve-getDistAtParam pl fspa)
                       )
                    )
               erat (/ (- (vlax-curve-getDistAtParam pl epa)
                          (vlax-curve-getDistAtParam pl fepa)
                       )
                       (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
                          (vlax-curve-getDistAtParam pl fepa)
                       )
                    )
         )
         (if (< epa spa)
           (setq plst (append
                        (if (= spa fspa)
                          (sublist plst fspa nil)
                          (cons (3dTo2dPt (trans spt 0 norm))
                                (sublist plst (1+ fspa) nil)
                          )
                        )
                        (cdr (sublist plst 0 (1+ fepa)))
                        (if (/= epa fepa)
                          (list (3dTo2dPt (trans ept 0 norm)))
                        )
                      )
                 blst (append
                        (if (= spa fspa)
                          (sublist blst fspa nil)
                          (cons
                            (k*bulge (nth fspa blst) srat)
                            (sublist blst (1+ fspa) nil)
                          )
                        )
                        (sublist blst 0 fepa)
                        (if (= epa fepa)
                          (list (nth fepa blst))
                          (list (k*bulge (nth fepa blst) erat))
                        )
                      )
           )
           (setq plst (append
                        (if (= spa fspa)
                          (sublist plst fspa (1+ (- fepa fspa)))
                          (cons (3dTo2dPt (trans spt 0 norm))
                                (sublist plst (1+ fspa) (- fepa fspa))
                          )
                        )
                        (list (3dTo2dPt (trans ept 0 norm)))
                      )
                 blst (append
                        (if (= spa fspa)
                          (sublist blst fspa (- fepa fspa))
                          (cons
                            (k*bulge (nth fspa blst) srat)
                            (sublist blst (1+ fspa) (- fepa fspa))
                          )
                        )
                        (if (= epa fepa)
                          (list (nth fepa blst))
                          (list (k*bulge (nth fepa blst) erat))
                        )
                      )
           )
         )
        )
      )
      (vlax-put pl 'Coordinates (apply 'append plst))
      (foreach b blst
        (vla-SetBulge pl n b)
        (setq n (1+ n))
      )
    )
  )
  pl
)
 
;; Ang<2pi
;; Returns the angle expression betweem 0 and 2*pi
(defun ang<2pi (ang)
  (if (and (<= 0 ang) (< ang (* 2 pi)))
    ang
    (ang<2pi (rem (+ ang (* 2 pi)) (* 2 pi)))
  )
)
 
;; 3dTo2dPt
;; Returns the 2d point (x y) of a 3d point (x y z)
(defun 3dTo2dPt (pt) (list (car pt) (cadr pt)))
 
;; Tan
;; Returns the angle tangent
(defun tan (a) (/ (sin a) (cos a)))
 
;; SUBLIST 
;; Returns a sub list
;;
;; Arguments
;; lst : a list
;; start : start index (first item = 0)
;; leng : the sub list length (number of items) or nil
(defun sublist (lst start leng / n r)
  (if (or (not leng) (< (- (length lst) start) leng))
    (setq leng (- (length lst) start))
  )
  (setq n (+ start leng))
  (while (< start n)
    (setq r (cons (nth (setq n (1- n)) lst) r))
  )
)
 
;; K*BULGE
;; Returns the proportinal bulge to the reference bulge
;; Arguments :
;; b : the bulge
;; k : the proportion ratio (between angles or arcs length)
(defun k*bulge (b k / a)
  (setq a (atan b))
  (/ (sin (* k a)) (cos (* k a)))
)

 

 

 

Second, as far as I know, the I and J GCode parameters are the coordinates of the center of the arc relative to its start point. That said, the following code generates a list of strings corresponding to the lines of a GCode file.

 

 

(defun gc:massoc (key alst)
  (if (setq alst (member (assoc key alst) alst))
    (cons (cdar alst) (gc:massoc key (cdr alst)))
  )
)

(defun pline2gcode (pline / elst points bulges lines)

  (defun getCenter (p1 p2 b / a r)
    (setq a (* 2 (atan b))
	  r (/ (distance p1 p2) (* 2. (sin a)))
    )
    (polar p1 (+ (angle p1 p2) (/ pi 2.) (- a)) r)
  )

  (if (= (type pline) 'vla-object)
    (setq pline (vlax-vla-object->ename pline))
  )
  (setq	elst   (entget pline)
	points (gc:massoc 10 elst)
	bulges (gc:massoc 42 elst)
  )
  (if (= (logand 1 (cdr (assoc 70 elst))) 1)
    (setq points (append points (list (car points))))
  )
  (cons
    (strcat "G90 G92 X"
	    (rtos (caar points))
	    " Y"
	    (rtos (cadar points))
    )
    (mapcar '(lambda (p1 p2 b / c)
	       (if (zerop b)
		 (strcat "G1 X" (rtos (car p2)) " Y" (rtos (cadr p2)))
		 (progn
		   (setq c (mapcar '- (getCenter p1 p2 b) p1))
		   (strcat
		     (if (minusp b)
		       "G02 X"
		       "G03 X"
		     )
		     (rtos (car p2))
		     " Y"
		     (rtos (cadr p2))
		     (strcat
		       " I"
		       (rtos (car c))
		       " J"
		       (rtos (cadr c))
		     )
		   )
		 )
	       )
	     )
	    points
	    (cdr points)
	    bulges
    )
  )
)

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 12 of 19

_gile
Consultant
Consultant

With the upper code and the ellipse in the drawing you provided,

(pline2gcode (ellipseToPolyline(car (entsel))))

returns the following list:

("G90 G92 X6073.0000 Y2108.0000"
  "G03 X6063.0178 Y2167.5121 I-182.3921 J0.0000"
  "G03 X6035.8026 Y2215.7631 I-145.3028 J-50.1553"
  "G03 X5993.3926 Y2249.2711 I-100.8308 J-84.0257"
  "G03 X5946.0000 Y2260.4000 I-47.3926 J-95.3466"
  "G03 X5898.6074 Y2249.2711 I0.0000 J-106.4755"
  "G03 X5856.1974 Y2215.7631 I58.4209 J-117.5337"
  "G03 X5828.9822 Y2167.5121 I118.0876 J-98.4063"
  "G03 X5819.0000 Y2108.0000 I172.4099 J-59.5121"
 )


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 19

komondormrex
Mentor
Mentor

getting out cnc-s

;************************************************************************************************************************************

(defun get_direction (point_1 point_2 point_3 / segment_1_2_angle segment_2_3_angle normalized_segment_2_3_angle direction)
	(setq segment_1_2_angle (angle point_1 point_2)
		  segment_2_3_angle (angle point_2 point_3)
  		  normalized_segment_2_3_angle (if (< (- segment_2_3_angle segment_1_2_angle) 0)
  								(+ (- segment_2_3_angle segment_1_2_angle) (* 2 pi))
								(- segment_2_3_angle segment_1_2_angle)
						)
)
  	(cond
  		(
  			(and (> normalized_segment_2_3_angle 0)
  				 (<  normalized_segment_2_3_angle pi)
  			)
				(setq direction +1)
  		)
  		(
  			(and (> normalized_segment_2_3_angle pi)
  				 (< normalized_segment_2_3_angle (* 2 pi))
  			)
				(setq direction -1)
  		)
		(
			t
		)
  	)
	direction
)

;************************************************************************************************************************************

(setq approximation_steps 8
      ellipse_object (vlax-ename->vla-object (car (entsel)))
      ellipse_included_angle (- (vlax-curve-getendparam ellipse_object) (setq ellipse_start_param (vlax-curve-getstartparam ellipse_object)))
      ellipse_start_point (vlax-curve-getstartpoint ellipse_object)
      ellipse_approximation_angle (/ ellipse_included_angle (float approximation_steps))
      ellipse_direction nil
      cnc_arc '((1 . "G03") (-1 . "G02"))
)
(princ (strcat "G90 G92 X" (rtos (car ellipse_start_point) 2 3) " Y" (rtos (cadr ellipse_start_point) 2 3) "\n"))
(repeat approximation_steps
	(setq arc_start_point (vlax-curve-getpointatparam ellipse_object ellipse_start_param)
	      arc_middle_point (vlax-curve-getpointatparam ellipse_object (+ ellipse_start_param (* 0.5 ellipse_approximation_angle)))
	      arc_end_point (vlax-curve-getpointatparam ellipse_object (setq ellipse_start_param (+ ellipse_start_param ellipse_approximation_angle)))
	)
	(if (null ellipse_direction)
		(setq ellipse_direction (get_direction arc_start_point arc_middle_point arc_end_point))
	)
	(setq ellipse_direction (if (null ellipse_direction) (get_direction arc_start_point arc_middle_point arc_end_point) ellipse_direction)
	      arc_center_point (inters (setq aux_point_1 (polar arc_start_point (angle arc_start_point arc_middle_point) (+ (* 0.5 (distance arc_start_point arc_middle_point)))))
				       			   (polar aux_point_1 (+ (* 0.5 pi) (angle arc_start_point arc_middle_point)) 5.0)
				         		   (setq aux_point_2 (polar arc_middle_point (angle arc_middle_point arc_end_point) (+ (* 0.5 (distance arc_middle_point arc_end_point)))))
				       			   (polar aux_point_2 (+ (* 0.5 pi) (angle arc_middle_point arc_end_point)) 5.0)
				       			   nil
			       		   )
    )
	(princ (strcat (cdr (assoc ellipse_direction cnc_arc)) " X" (rtos (car arc_end_point) 2 3)
							       " Y" (rtos (cadr arc_end_point) 2 3)
							       " I" (rtos (- (car arc_center_point) (car arc_start_point)) 2 3)
							       " J" (rtos (- (cadr arc_center_point) (cadr arc_start_point)) 2 3)
							       "\n"
		   )
	)
	(if (minusp ellipse_direction) 
  		(vla-addarc (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
		    	    (vlax-3d-point arc_center_point)
	  	    	    (distance arc_center_point arc_start_point)
		  	    (angle arc_center_point arc_end_point)
			    (angle arc_center_point arc_start_point)
	  	)
	  	(vla-addarc (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
		    	    (vlax-3d-point arc_center_point)
	  	    	    (distance arc_center_point arc_start_point)
	    		    (angle arc_center_point arc_start_point)
		  	    (angle arc_center_point arc_end_point)
	  	)
  	)
;;;  	(command "_point" "_non" arc_start_point)
;;;	(command "_point" "_non" arc_end_point)
;;;  	(command "_point" "_non" arc_center_point)
)

 

G90 G92 X6073.000 Y2108.000
G03 X6063.333 Y2166.321 I-179.194 J0.258
G03 X6035.803 Y2215.763 I-149.008 J-50.584
G03 X5994.601 Y2248.799 I-99.087 J-81.367
G03 X5946.000 Y2260.400 I-48.911 J-97.304
G03 X5897.399 Y2248.799 I0.310 J-108.905
G03 X5856.197 Y2215.763 I57.885 J-114.403
G03 X5828.667 Y2166.321 I121.478 J-100.026
G03 X5819.000 Y2108.000 I169.526 J-58.062
0 Likes
Message 14 of 19

_gile
Consultant
Consultant

Here's the used method in images to approximate an ellipse with successive tangent arcs.

_gile_0-1683799412728.png

 

EDIT: corrected a mistake in the construction process.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 15 of 19

Sea-Haven
Mentor
Mentor

Version 2, I dont do any GCODE but method should still be practical.

 

 

 

(defun c:ellipsepts ( / ss elst)
(command "divide" pause (getint "\nEnter number of increments "))
(setvar 'pdmode 34)
(setvar 'pdsize 3)
(prompt "\nSelect all the points ")
(setq ss (ssget '((0 . "POINT"))))
(setq elst '())
(repeat (setq x (sslength ss))
(setq elst (cons (cdr (assoc 10 (entget (ssname ss (setq x (1- x)))))) elst))
)
(setq elst (cons (cdr (assoc 10 (entget (ssname ss (- (sslength ss) 1))))) elst))
(setq fo (open "D:\\acadtemp\\mygcodeattempt.txt" "W"))
(write-line (strcat "G00 X" (rtos (CAR (LAST ELST)) 2 4) " Y" (rtos (CADR (LAST ELST)) 2 4)) FO)
(foreach pt elst
(write-line (strcat "G01 X" (rtos (CAR pt) 2 4) " Y" (rtos (CADR pt) 2 4)) fo)
)
(close fo)
(command "erase" ss "")
(princ)
)
(c:ellipsepts)

 

 

G00 X-42456541.494 Y75347964.3315
G01 X-42456541.494 Y75347964.3315
G01 X-42456537.9035 Y75347975.4743
G01 X-42456535.2374 Y75347980.6952
G01 X-42456532.0544 Y75347985.6184
G01 X-42456528.4184 Y75347990.2176

 

 

0 Likes
Message 16 of 19

rpajounia
Advocate
Advocate

this is amazing just what i needed thanks alot guys for your help on this

0 Likes
Message 17 of 19

rpajounia
Advocate
Advocate

im getting this error

 

Select object: ; error: bad argument type: VLA-OBJECT <Entity name: 19fad8486b0>

0 Likes
Message 18 of 19

_gile
Consultant
Consultant

Oops!... My mistake. You can try like this:

(pline2gcode (ellipseToPolyline (vlax-ename->vla-object (car (entsel)))))

 

Anyway the code I posted upper was an old one which converts an ellipse into a polyline. In your case, there's no need to convert into a polyline to get the arcs  apprimating an ellipse. The following code directly computes the arcs.

;; EllipseToArcs
;; Returns a list of the data (startPoint endPoint center)
;; defining the arcs which approximate the ellipse.
;;
;; Argument
;; el : ellipse ename
(defun EllipseToArcs (el     /	    norm   cen	  pt0	 pt1	pt2
		      pt3    pt4    ac0	   ac4	  a02	 a24	bsc1
		      bsc2   bsc3   bsc4   plst	  clst	 arcs	dist
		      startPt	    endPt  trimStart	 trimEnd
		     )
  (setq	norm	(getpropertyvalue el "Normal")
	cen	(trans (getpropertyvalue el "Center") 0 norm)
	majAxis	(trans (getpropertyvalue el "MajorAxis") 0 norm)
	minAxis	(trans (getpropertyvalue el "MinorAxis") 0 norm)
	pt0	(mapcar '+ cen majAxis)
	pt4	(mapcar '+ cen minAxis)
	pt2	(trans (vlax-curve-getPointAtparam el (/ pi 4.)) 0 norm)
	ac0	(angle cen pt0)
	ac4	(angle cen pt4)
	a04	(angle pt0 pt4)
	a02	(angle pt0 pt2)
	a24	(angle pt2 pt4)
	bsc1	(/ (- a02 ac4) 2.)
	bsc2	(/ (- a04 a02) 2.)
	bsc3	(/ (- a24 a04) 2.)
	bsc4	(/ (- (+ ac0 pi) a24) 2.)
	plst	(list
		  pt0
		  (setq	pt1 (inters pt0
				    (polar pt0 (+ ac4 bsc1) 1.)
				    pt2
				    (polar pt2 (+ a02 bsc2) 1.)
				    nil
			    )
		  )
		  pt2
		  (setq	pt3 (inters pt2
				    (polar pt2 (+ a04 bsc3) 1.)
				    pt4
				    (polar pt4 (+ a24 bsc4) 1.)
				    nil
			    )
		  )
		  pt4
		)
	clst	(list
		  (inters pt0
			  (polar pt0 ac0 1.)
			  pt1
			  (polar pt1 (+ (/ pi 2.) a02) 1.)
			  nil
		  )
		  (inters pt1
			  (polar pt1 (+ (/ pi 2.) a02) 1.)
			  pt2
			  (polar pt2 (+ (/ pi 2.) a04) 1.)
			  nil
		  )
		  (inters pt2
			  (polar pt2 (+ (/ pi 2.) a04) 1.)
			  pt3
			  (polar pt3 (+ (/ pi 2.) a24) 1.)
			  nil
		  )
		  (inters pt3
			  (polar pt3 (+ (/ pi 2.) a24) 1.)
			  pt4
			  (polar pt4 ac4 1.)
			  nil
		  )
		)
	arcs	(mapcar 'list plst (cdr plst) clst)
	arcs	(append
		  arcs
		  (mapcar
		    '(lambda (a)
		       (mapcar
			 '(lambda (p)
			    (gc:MirrorPoint p cen majAxis)
			  )
			 (list (cadr a) (car a) (caddr a))
		       )
		     )
		    (reverse arcs)
		  )
		)
	arcs	(append
		  arcs
		  (mapcar
		    '(lambda (a)
		       (mapcar
			 '(lambda (p)
			    (gc:MirrorPoint p cen minAxis)
			  )
			 (list (cadr a) (car a) (caddr a))
		       )
		     )
		    (reverse arcs)
		  )
		)
  )
  (if (vlax-curve-IsClosed el)
    arcs
    (progn
      (setq dist    (distance '(0. 0. 0.) majAxis)
	    startPt (trans (vlax-curve-getStartPoint el) 0 norm)
	    endPt   (trans (vlax-curve-getEndPoint el) 0 norm)
	    pt1	    (polar cen (+ ac0 (getpropertyvalue el "StartAngle")) dist)
	    pt2	    (polar cen (+ ac0 (getpropertyvalue el "EndAngle")) dist)
	    arcs    (append arcs arcs)
      )
      (defun trimStart (lst / int)
	(cond
	  ((null lst) nil)
	  ((null (setq int (inters cen pt1 (caar lst) (cadar lst))))
	   (trimStart (cdr lst))
	  )
	  ((equal int (caar lst) 1e-10)
	   (trimEnd lst)
	  )
	  ((equal int (cadar lst) 1e-10)
	   (trimEnd (cdr lst))
	  )
	  (T
	   (cons (list
		   (polar (caddar lst)
			  (angle (caddar lst) startPt)
			  (distance (caddar lst) (caar lst))
		   )
		   (cadar lst)
		   (caddar lst)
		 )
		 (trimEnd (cdr lst))
	   )
	  )
	)
      )
      (defun trimEnd (lst / int)
	(cond
	  ((null lst) nil)
	  ((null (setq int (inters cen pt2 (caar lst) (cadar lst))))
	   (cons (car lst) (trimEnd (cdr lst)))
	  )
	  ((equal int (caar lst) 1e-10)
	   nil
	  )
	  ((equal int (cadar lst) 1e-10)
	   (list (car lst))
	  )
	  (T
	   (list (list
		   (caar lst)
		   (polar (caddar lst)
			  (angle (caddar lst) endPt)
			  (distance (caddar lst) (caar lst))
		   )
		   (caddar lst)
		 )
	   )
	  )
	)
      )
      (trimStart arcs)
    )
  )
)

;; gc:MirrorVector
;; Returns the vector after a mirror about a plane which norm is the normal.
;;
;; Arguments
;; vector : Vector to mirror
;; normal : Normal of the plane
(defun gc:MirrorVector (vector normal)
  (setq vector (trans vector 0 normal))
  (trans (list (car vector) (cadr vector) (- (caddr vector))) normal 0)
)

;; gc:MirrorPoint
;; Returns the point after a mirror about the plane defined by origin and normal.
;;
;; Arguments
;; point : Point to mirror
;; origin : Point on plane
;; normal : Normal of the plane
(defun gc:MirrorPoint (point origin normal)
  (mapcar '+
	  origin
	  (gc:MirrorVector (mapcar '- point origin) normal)
  )
)

;; EllipseToGCode
;; Returns a list of strings (GCode lines) for an ellipse (or elliptical arc)
;;
;; Argument
;; ellipse: ellipse ename
(defun EllipseToGCode (ellipse / arcs)
  (setq arcs (EllipseToArcs ellipse))
  (cons
    (strcat "G90 G92 X"
	    (rtos (caaar arcs))
	    " Y"
	    (rtos (cadaar arcs))
    )
    (mapcar '(lambda (arc / p1 p2 c)
	       (setq p1	(car arc)
		     p2	(cadr arc)
		     c	(mapcar '- (caddr arc) p1)
	       )
	       (strcat
		 "G03 X"
		 (rtos (car p2))
		 " Y"
		 (rtos (cadr p2))
		 " I"
		 (rtos (car c))
		 " J"
		 (rtos (cadr c))
	       )
	     )
	    arcs
    )
  )
)

This one works with enames, so you can call it with:

(EllipseToGcode (car (entsel)))


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 19 of 19

rpajounia
Advocate
Advocate

ok so this is almost perfect. the only issue is the G02 and G03, when its going clock wise it should be G02 and counter clockwise is G03, how would i be able to calculate which way its going? Can you let me add a variable stating which point im starting from?

0 Likes