Author Topic: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?  (Read 2192 times)

0 Members and 1 Guest are viewing this topic.

chlh_jd

  • Guest
How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« on: February 23, 2013, 12:45:05 PM »
Hi all !
what all as the title .
I use points forec into arc ,  and found it dose not get the best result , is there better way to do it (Particularly it lost the symmetry) .
Code - Auto/Visual Lisp: [Select]
  1. ;; Convert an ellipse or ellipse arc into lwpolyline
  2. ;;
  3. ;; test routine
  4. (defun c:test () (ss-ellipse2pl (car (entsel "\nSelect an Ellipse or Ellipse-Arc to convert :")) 200 0.075))
  5. ;;
  6. ;; main function
  7. (defun ss-ellipse2pl
  8.                       (ell n tor / pas pae dpa pai p pts ptl ps arc an1
  9.                        an2 cr p0 p1 p2 en ss)
  10.   ;; ell -- ellipse or ellipse arc
  11.   ;; n -- devided numbers to get pointset of the ell entity
  12.   ;;       Fit number : >= 100
  13.   ;; tor -- Tolerance , the ratio of the average distance of all centers with the Fit center and the Radius
  14.   ;;        Fit value : 0.01~0.2
  15.         pae (vlax-curve-getendparam ell)
  16.         dpa (- pae pas)
  17.         pai (/ dpa n))
  18.   (repeat (1+ n)
  19.     (if (setq p (vlax-curve-getpointatparam ell pas))
  20.       (setq pts (cons p pts))
  21.       (if (and (equal pas pae 1e-6)
  22.                (setq p (vlax-curve-getpointatparam ell pae)))
  23.         (setq pts (cons p pts))))
  24.     (setq pas (+ pas pai)))
  25.   (setq pts (reverse pts))
  26.   (setq ptl pts)
  27.   (setq en (entlast))
  28.   (while (> (length ptl) 2)
  29.     (repeat (- 3 (length ps))
  30.       (setq ps  (cons (car ptl) ps)
  31.             ptl (cdr ptl)))
  32.     (while
  33.       (and (< (caddr (setq arc (ss-pts2arc (reverse ps)))) tor)
  34.            ptl)
  35.        (setq ps  (cons (car ptl) ps)
  36.              ptl (cdr ptl)))
  37.     (if (> (length ps) 3)
  38.       (setq ptl (cons (car ps) ptl)
  39.             ps  (cdr ps)
  40.             arc (ss-pts2arc (reverse ps))))
  41.     (if (and arc (< (caddr arc) tor))
  42.       (progn
  43.         (setq p2  (car ps)
  44.               p0  (last ps)
  45.               p1  (vlax-curve-getclosestpointto ell (midpt p0 p2))
  46.               cr  (ss-3pcircle p0 p1 p2)
  47.               an1 (angle (car cr) (last ps))
  48.               an2 (angle (car cr) (car ps)))
  49.         (setq ps (list (car ps)))
  50.         (if (and (equal an1 an2 1e-6) (equal an1 0 1e-6))
  51.           (setq an2 (* 2 pi)))
  52.         (entmake (list (cons 0 "ARC")
  53.                        (cons 100 "AcDbEntity")
  54.                        (cons 100 "AcDbCircle")
  55.                        (cons 10 (car cr))
  56.                        (cons 40 (cadr cr))
  57.                        (cons 100 "AcDbArc")
  58.                        (cons 50 an1)
  59.                        (cons 51 an2))
  60.                  ))
  61.       (setq ps (butlast ps))))
  62.   (if (and (cadr ptl)
  63.            ps
  64.            (setq ps (append (reverse ptl) ps))
  65.            (setq arc (ss-pts2arc (reverse ps)))
  66.            )
  67.     (progn
  68.       (setq p2  (car ps)
  69.             p0  (last ps)
  70.             p1  (vlax-curve-getclosestpointto ell (midpt p0 p2))
  71.             cr  (ss-3pcircle p0 p1 p2)
  72.             an1 (angle (car cr) (last ps))
  73.             an2 (angle (car cr) (car ps)))
  74.       (if (and (equal an1 an2 1e-6) (equal an1 0 1e-6))
  75.         (setq an2 (* 2 pi)))
  76.       (entmake (list (cons 0 "ARC")
  77.                      (cons 100 "AcDbEntity")
  78.                      (cons 100 "AcDbCircle")
  79.                      (cons 10 (car cr))
  80.                      (cons 40 (cadr cr))
  81.                      (cons 100 "AcDbArc")
  82.                      (cons 50 an1)
  83.                      (cons 51 an2))
  84.                )
  85.       )
  86.     (entmod(ch-en (cons 51 (angle (car cr) (car ptl))) (entget (entlast))))
  87.     )
  88.   (setq ss (ssadd))
  89.   (while (setq en (entnext en))
  90.     (setq ss (ssadd en ss)))
  91.   (vl-cmdf "pedit" "M" ss "" "y" "j" "" "")
  92.   (entlast)
  93.   )
  94. ;;;force points into a circle
  95. (defun ss-pts2arc  (pts / cs c dc r n)
  96.   (if (setq cs (mapcar (function (lambda (p1 p2 p3 / p4 p5 p6 p7)
  97.                                    (setq p4 (midpt p1 p2)
  98.                                          p5 (midpt p2 p3))
  99.                                    (setq p6 (polar p4 (+ (angle p1 p2) (/ pi 2.)) 1.)
  100.                                          p7 (polar p5 (+ (angle p2 p3) (/ pi 2.)) 1.))
  101.                                    (inters p4 p6 p5 p7 nil)))
  102.                        pts
  103.                        (cdr pts)
  104.                        (cddr pts))
  105.             cs (vl-remove nil cs))
  106.     (setq
  107.       c  (midpts cs)
  108.       n  (length pts)
  109.       dc (/ (apply (function +)
  110.                    (mapcar (function (lambda (p)
  111.                                        (distance p c)))
  112.                            cs))
  113.             n)
  114.       r  (/ (apply (function +)
  115.                    (mapcar (function (lambda (p)
  116.                                        (distance p c)))
  117.                            pts))
  118.             n)))
  119.   (if c
  120.     (list c r (/ dc r)))
  121.   )
  122. ;;--------------------------
  123. ;; Used functions
  124. (defun ss-3PCirCle (p0 p1 p2 / v1 v2 m1 m2 v3 mat d0 d1 d2 v c )
  125.   (setq p0 (trans p0 0 0)
  126.         p1 (trans p1 0 0)
  127.         p2 (trans p2 0 0)
  128.         v1 (pt* (pt- p0 p1) 2.)
  129.         v2 (pt* (pt- p1 p2) 2.)
  130.         m1 (- (* (caddr v1) (cadr v2)) (* (cadr v1) (caddr v2)) )
  131.         m2 (- (* (car v1) (caddr v2)) (* (caddr v1) (car v2)) )
  132.         v3 (list (/ (* (caddr v1) m1) 8.)
  133.                  (/ (* (caddr v1) m2) 8.)
  134.                  (/ (+ (* (car v1) m1) (* (cadr v1) m2)) -8.))
  135.         mat (list v1 v2 v3)
  136.         d0 (apply (function +) (mapcar (function *) p0 p0))
  137.         d1 (apply (function +) (mapcar (function *) p1 p1))
  138.         d2 (apply (function +) (mapcar (function *) p2 p2))
  139.         v (list (- d0 d1)
  140.                  (- d1 d2)
  141.                  (apply (function +) (mapcar (function *) p0 v3))
  142.                  )     
  143.         )
  144.   (if (equal (last mat) (list 0.0 0.0 0.0) 1e-14)
  145.     (setq mat (list (butlast (car mat)) (butlast (cadr mat)))))
  146.   (setq c (flatset([*] ([inv] mat) (mapcar (function list) v))))
  147.   (if c
  148.     (list c (distance c p0)))
  149. )
  150. ;;--------
  151. (defun butlast(a) (reverse (cdr(reverse a))))
  152. ;;--------
  153. (defun flatset (s / foo)
  154.   ;;by Gile
  155.   (defun foo (s p)
  156.     (if s(foo(cdr s)(if (atom (car s))(cons (car s) p)(foo (car s) p)))p))
  157.   (reverse (foo s nil)))
  158. ;;--------
  159. (defun [inv] (mat / col piv row res)
  160.   ;; gauss-jordan elimination method to calculate the inverse
  161.   ;; by gile
  162.   ;;([inv] '((1 2 3) (2 4 5) (3 5 6)))
  163.   (setq mat (mapcar (function (lambda (x1 x2)
  164.                  (append  x1  x2))) mat([I] (length mat))))
  165.   (while mat
  166.     (setq col (mapcar(function(lambda (x)(abs (car x))))mat))
  167.       (setq mat (append (cdr mat) (list (car mat)))))  
  168.     (if (equal (setq piv (caar mat))0.0 1e-14)
  169.       (setq mat nil  res nil)      
  170.       (setq piv (/ 1.0 (caar mat))
  171.             row (mapcar(function(lambda (x)(* x piv)))(car mat))
  172.             mat (mapcar (function(lambda (r / e)
  173.                      (setq e (car r))(cdr (mapcar(function(lambda (x n)
  174.                                (- x (* n e))))r row))))          
  175.                   (cdr mat))
  176.             res (cons (cdr row)
  177.                       (mapcar(function(lambda (r / e)
  178.                            (setq e (car r))(cdr(mapcar(function(lambda (x n)
  179.                                      (- x (* n e))))r row))))res))
  180.       )))
  181.   (reverse res)
  182. )
  183. ;;-------mat x mat
  184. (defun [*](m q)(mapcar(function (lambda (r)(mxv ([trp] q) r)))m))
  185. ;;-------
  186. (defun mxv(m v)(mapcar(function(lambda (r)(vxv r v)))m))
  187. ;;-------Transpose matrix
  188. (defun [trp] (a)  
  189. ;;; vxv returns the dot product of 2 vectors
  190. ;; (vxv '(1 2 0) '(2 5 0))
  191. (defun vxv(v1 v2)(apply(function +)(mapcar(function *)v1 v2)))
  192. ;;-------get I matrix
  193. (defun [I] (d / i r n m)
  194.   (setq i d)
  195.   (while (<= 0 (setq i (1- i)))
  196.     (setq n d
  197.           r nil)
  198.     (while (<= 0 (setq n (1- n)))
  199.       (setq r (cons (if (= i n)
  200.                       1.0
  201.                       0.0)
  202.                     r)))
  203.     (setq m (cons r m))))
  204. ;;-------
  205. (defun midpt (p1 p2)
  206.   (mapcar (function /2) (mapcar (function +)  p1 p2))
  207. )
  208. (defun /2 (a) (cond ((numberp a) (/ a 2.))
  209.                     ((vl-consp a) (mapcar (function /2) a))))
  210. ;;-------
  211. (defun pt-(p2 p1)(mapcar(function -)p2 p1))
  212. ;;-------
  213. (defun pt*(v c)(mapcar(function(lambda(x)(* x c)))v))
  214. ;;-------
  215. (defun midpts (l / n)
  216.   (setq n (float(length l)))
  217.   (mapcar (function (lambda (x) (/ x n)))
  218.           (apply (function mapcar) (cons (function +) l))))
  219. ;;-------
  220. (defun ch-en  (co en / b)
  221.   (if (eq (type en) (quote ename))
  222.     (setq en (entget en (list "*"))))
  223.   (cond ((not co) en)
  224.         ((vl-every (function vl-consp) co)
  225.          (ch-en (cdr co) (ch-en (car co) en))
  226.          )
  227.         (t
  228.          (if (setq b (assoc (car co) en))
  229.            (subst co b en)
  230.            (reverse (cons co (reverse en))))))
  231.   )
  232.  
« Last Edit: February 23, 2013, 12:57:15 PM by chlh_jd »

Peter Guappa

  • Guest
Re: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« Reply #1 on: February 23, 2013, 03:03:08 PM »
You could use Lee Mac 's :

http://lee-mac.com/entitytopointlist.html

and create a LWpoly from these points.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« Reply #2 on: February 23, 2013, 03:57:39 PM »
Hi,

Here's my (quite old) attempt.
The polyline ellipse approximation is the same as AutoCAD's one (i.e. PELLIPSE = 1).

The EL2PL command converts the selected ellipses or elliptical arcs in lwpolylines.
The PELL command let the user draw a polyline ellipse approximation as with te native ELLIPSE command.

Code - Auto/Visual Lisp: [Select]
  1. ;; EllipseToPolyline
  2. ;; Returns a polyline (vla-object) which is an approximation of the ellipse (or elliptical arc)
  3. ;;
  4. ;; Argument : an ellipse (vla-object)
  5.  
  6. (defun EllipseToPolyline (el    /     cl    norm  cen   elv   pt0   pt1   pt2   pt3   pt4   ac0
  7.                           ac4   a04   a02   a24   bsc0  bsc2  bsc3  bsc4  plst  blst  spt   spa
  8.                           fspa  srat  ept   epa   fepa  erat  n
  9.                          )
  10.   (setq cl   (= (ang<2pi (vla-get-StartAngle el))
  11.                 (ang<2pi (vla-get-EndAngle el)))
  12.         norm (vlax-get el 'Normal)
  13.         cen  (trans (vlax-get el 'Center) 0 norm)
  14.         elv  (caddr cen)
  15.         cen  (3dTo2dPt cen)
  16.         pt0  (mapcar '+ (trans (vlax-get el 'MajorAxis) 0 norm) cen)
  17.         ac0  (angle cen pt0)
  18.         pt4  (mapcar '+ cen (trans (vlax-get el 'MinorAxis) 0 norm))
  19.         pt2  (3dTo2dPt (trans (vlax-curve-getPointAtparam el (/ pi 4.)) 0 norm))
  20.         ac4  (angle cen pt4)
  21.         a04  (angle pt0 pt4)
  22.         a02  (angle pt0 pt2)
  23.         a24  (angle pt2 pt4)
  24.         bsc0 (/ (ang<2pi (- a02 ac4)) 2.)
  25.         bsc2 (/ (ang<2pi (- a04 a02)) 2.)
  26.         bsc3 (/ (ang<2pi (- a24 a04)) 2.)
  27.         bsc4 (/ (ang<2pi (- (+ ac0 pi) a24)) 2.)
  28.         pt1  (inters pt0
  29.                      (polar pt0 (+ ac0 (/ pi 2.) bsc0) 1.)
  30.                      pt2
  31.                      (polar pt2 (+ a02 bsc2) 1.)
  32.                      nil
  33.              )
  34.         pt3  (inters pt2
  35.                      (polar pt2 (+ a04 bsc3) 1.)
  36.                      pt4
  37.                      (polar pt4 (+ a24 bsc4) 1.)
  38.                      nil
  39.              )
  40.         plst (list pt4 pt3 pt2 pt1 pt0)
  41.         blst (mapcar '(lambda (b) (tan (/ b 2.)))
  42.                      (list bsc4 bsc3 bsc2 bsc0)
  43.              )
  44.   )
  45.   (foreach b blst
  46.     (setq blst (cons b blst))
  47.   )
  48.   (foreach b blst
  49.     (setq blst (cons b blst))
  50.   )
  51.   (foreach p (cdr plst)
  52.     (setq ang  (angle cen p)
  53.           plst (cons
  54.                  (polar cen (+ ang (* 2 (- ac4 ang))) (distance cen p))
  55.                  plst
  56.                )
  57.     )
  58.   )
  59.   (foreach p (cdr plst)
  60.     (setq ang  (angle cen p)
  61.           plst (cons
  62.                  (polar cen (+ ang (* 2 (- ac0 ang))) (distance cen p))
  63.                  plst
  64.                )
  65.     )
  66.   )
  67.   (setq pl
  68.          (vlax-invoke
  69.            'AddLightWeightPolyline
  70.            (apply 'append
  71.                   (setq plst
  72.                          (reverse (if cl
  73.                                     (cdr plst)
  74.                                     plst
  75.                                   )
  76.                          )
  77.                   )
  78.            )
  79.          )
  80.   )
  81.   (vlax-put pl 'Normal norm)
  82.   (vla-put-Elevation pl elv)
  83.   (mapcar '(lambda (i v) (vla-SetBulge pl i v))
  84.           '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
  85.           blst
  86.   )
  87.   (if cl
  88.     (vla-put-Closed pl :vlax-true)
  89.     (progn
  90.       (setq spt  (vlax-curve-getClosestPointTo pl (vlax-get el 'Startpoint))
  91.             spa  (vlax-curve-getParamAtPoint pl spt)
  92.             fspa (fix spa)
  93.             ept  (vlax-curve-getClosestPointTo pl (vlax-get el 'Endpoint))
  94.             epa  (vlax-curve-getParamAtPoint pl ept)
  95.             fepa (fix epa)
  96.             n    0
  97.       )
  98.       (cond
  99.         ((equal spt (trans pt0 norm 0) 1e-9)
  100.          (if (= epa fepa)
  101.            (setq plst (sublist plst 0 (1+ fepa))
  102.                  blst (sublist blst 0 (1+ fepa))
  103.            )
  104.            (setq erat (/ (- (vlax-curve-getDistAtParam pl epa)
  105.                             (vlax-curve-getDistAtParam pl fepa)
  106.                          )
  107.                          (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
  108.                             (vlax-curve-getDistAtParam pl fepa)
  109.                          )
  110.                       )
  111.                  plst (append (sublist plst 0 (1+ fepa))
  112.                               (list (3dTo2dPt (trans ept 0 norm)))
  113.                       )
  114.                  blst (append (sublist blst 0 (1+ fepa))
  115.                               (list (k*bulge (nth fepa blst) erat))
  116.                       )
  117.            )
  118.          )
  119.         )
  120.         ((equal ept (trans pt0 norm 0) 1e-9)
  121.          (if (= spa fspa)
  122.            (setq plst (sublist plst fspa nil)
  123.                  blst (sublist blst fspa nil)
  124.            )
  125.            (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  126.                             (vlax-curve-getDistAtParam pl spa)
  127.                          )
  128.                          (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  129.                             (vlax-curve-getDistAtParam pl fspa)
  130.                          )
  131.                       )
  132.                  plst (cons (3dTo2dPt (trans spt 0 norm))
  133.                             (sublist plst (1+ fspa) nil)
  134.                       )
  135.                  blst (cons (k*bulge (nth fspa blst) srat)
  136.                             (sublist blst (1+ fspa) nil)
  137.                       )
  138.            )
  139.          )
  140.         )
  141.         (T
  142.          (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  143.                           (vlax-curve-getDistAtParam pl spa)
  144.                        )
  145.                        (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  146.                           (vlax-curve-getDistAtParam pl fspa)
  147.                        )
  148.                     )
  149.                erat (/ (- (vlax-curve-getDistAtParam pl epa)
  150.                           (vlax-curve-getDistAtParam pl fepa)
  151.                        )
  152.                        (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
  153.                           (vlax-curve-getDistAtParam pl fepa)
  154.                        )
  155.                     )
  156.          )
  157.          (if (< epa spa)
  158.            (setq plst (append
  159.                         (if (= spa fspa)
  160.                           (sublist plst fspa nil)
  161.                           (cons (3dTo2dPt (trans spt 0 norm))
  162.                                 (sublist plst (1+ fspa) nil)
  163.                           )
  164.                         )
  165.                         (cdr (sublist plst 0 (1+ fepa)))
  166.                         (if (/= epa fepa)
  167.                           (list (3dTo2dPt (trans ept 0 norm)))
  168.                         )
  169.                       )
  170.                  blst (append
  171.                         (if (= spa fspa)
  172.                           (sublist blst fspa nil)
  173.                           (cons
  174.                             (k*bulge (nth fspa blst) srat)
  175.                             (sublist blst (1+ fspa) nil)
  176.                           )
  177.                         )
  178.                         (sublist blst 0 fepa)
  179.                         (if (= epa fepa)
  180.                           (list (nth fepa blst))
  181.                           (list (k*bulge (nth fepa blst) erat))
  182.                         )
  183.                       )
  184.            )
  185.            (setq plst (append
  186.                         (if (= spa fspa)
  187.                           (sublist plst fspa (1+ (- fepa fspa)))
  188.                           (cons (3dTo2dPt (trans spt 0 norm))
  189.                                 (sublist plst (1+ fspa) (- fepa fspa))
  190.                           )
  191.                         )
  192.                         (list (3dTo2dPt (trans ept 0 norm)))
  193.                       )
  194.                  blst (append
  195.                         (if (= spa fspa)
  196.                           (sublist blst fspa (- fepa fspa))
  197.                           (cons
  198.                             (k*bulge (nth fspa blst) srat)
  199.                             (sublist blst (1+ fspa) (- fepa fspa))
  200.                           )
  201.                         )
  202.                         (if (= epa fepa)
  203.                           (list (nth fepa blst))
  204.                           (list (k*bulge (nth fepa blst) erat))
  205.                         )
  206.                       )
  207.            )
  208.          )
  209.         )
  210.       )
  211.       (vlax-put pl 'Coordinates (apply 'append plst))
  212.       (foreach b blst
  213.         (vla-SetBulge pl n b)
  214.         (setq n (1+ n))
  215.       )
  216.     )
  217.   )
  218.   pl
  219. )
  220.  
  221. ;; Ang<2pi
  222. ;; Returns the angle expression betweem 0 and 2*pi
  223. (defun ang<2pi (ang)
  224.   (if (and (<= 0 ang) (< ang (* 2 pi)))
  225.     ang
  226.     (ang<2pi (rem (+ ang (* 2 pi)) (* 2 pi)))
  227.   )
  228. )
  229.  
  230. ;; 3dTo2dPt
  231. ;; Returns the 2d point (x y) of a 3d point (x y z)
  232. (defun 3dTo2dPt (pt) (list (car pt) (cadr pt)))
  233.  
  234. ;; Tan
  235. ;; Returns the angle tangent
  236. (defun tan (a) (/ (sin a) (cos a)))
  237.  
  238. ;; SUBLIST
  239. ;; Returns a sub list
  240. ;;
  241. ;; Arguments
  242. ;; lst : a list
  243. ;; start : start index (first item = 0)
  244. ;; leng : the sub list length (number of items) or nil
  245. (defun sublist (lst start leng / n r)
  246.   (if (or (not leng) (< (- (length lst) start) leng))
  247.     (setq leng (- (length lst) start))
  248.   )
  249.   (setq n (+ start leng))
  250.   (while (< start n)
  251.     (setq r (cons (nth (setq n (1- n)) lst) r))
  252.   )
  253. )
  254.  
  255. ;; K*BULGE
  256. ;; Returns the proportinal bulge to the référence bulge
  257. ;; Arguments :
  258. ;; b : the bulge
  259. ;; k : the proportion ratio (between angles or arcs length)
  260. (defun k*bulge (b k / a)
  261.   (setq a (atan b))
  262.   (/ (sin (* k a)) (cos (* k a)))
  263. )
  264.  
  265. ;; EL2PL
  266. ;; Converts ellipses and elliptcal arcs into polylines
  267.  
  268. (defun c:el2pl (/ *error* fra acdoc ss)
  269.   (defun *error* (msg)
  270.     (if (and (/= msg "Fonction annulée")
  271.              (/= msg "Function cancelled")
  272.         )
  273.       (princ (strcat (if (= "FRA" (getvar 'locale))
  274.                        "\nErreur: "
  275.                        "\Error: "
  276.                      )
  277.                      msg
  278.              )
  279.       )
  280.     )
  281.     (vla-endUndoMark acdoc)
  282.     (princ)
  283.   )
  284.   (if (ssget '((0 . "ELLIPSE")))
  285.     (progn
  286.       (vla-StartUndoMark acdoc)
  287.       (vlax-for e (setq ss (vla-get-ActiveSelectionSet acdoc))
  288.         (EllipseToPolyline e)
  289.         (vla-delete e)
  290.       )
  291.       (vla-delete ss)
  292.       (vla-EndUndoMark acdoc)
  293.     )
  294.   )
  295.   (princ)
  296. )
  297.  
  298. ;; PELL
  299. ;; Draws an ellipse or an elliptical arc approximation (polyline) on the fly
  300. (defun c:pell (/ *error* ec pe old ent)
  301.   (defun *error* (msg)
  302.     (if (and msg
  303.              (/= msg "Fonction annulée")
  304.              (/= msg "Function cancelled")
  305.         )
  306.       (princ (strcat (if (= "FRA" (getvar 'locale))
  307.                        "\nErreur: "
  308.                        "\Error: "
  309.                      )
  310.                      msg
  311.              )
  312.       )
  313.     )
  314.     (setvar 'cmdecho ec)
  315.     (setvar 'pellipse pe)
  316.     (princ)
  317.   )
  318.   (setq ec  (getvar 'cmdecho)
  319.         pe  (getvar 'pellipse)
  320.         old (entlast)
  321.   )
  322.   (setvar 'cmdecho 1)
  323.   (setvar 'pellipse 0)
  324.   (command "_.ellipse")
  325.   (while (/= 0 (getvar 'cmdactive))
  326.     (command pause)
  327.   )
  328.   (if (not (eq old (setq ent (entlast))))
  329.     (progn
  330.       (EllipseToPolyline (vlax-ename->vla-object ent))
  331.       (entdel ent)
  332.     )
  333.   )
  334.   (*error* nil)
  335. )
Speaking English as a French Frog

chlh_jd

  • Guest
Re: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« Reply #3 on: February 24, 2013, 02:24:14 AM »
You could use Lee Mac 's :

http://lee-mac.com/entitytopointlist.html

and create a LWpoly from these points.

Thanks Peter !

chlh_jd

  • Guest
Re: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« Reply #4 on: February 24, 2013, 02:37:30 AM »
Hi,

Here's my (quite old) attempt.
The polyline ellipse approximation is the same as AutoCAD's one (i.e. PELLIPSE = 1).

The EL2PL command converts the selected ellipses or elliptical arcs in lwpolylines.
The PELL command let the user draw a polyline ellipse approximation as with te native ELLIPSE command.

Code: [Select]
;; 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
)
    ...
  pl
)

Nice solution ,  Gile !
I always can see the master's demeanor from you !  :-)
Thank you a lot ![/code]

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: How to convert Ellipse or Ellipse-Arc to Lwpolyine ?
« Reply #5 on: February 24, 2013, 04:29:12 AM »
Hi,

Here's my (quite old) attempt.
The polyline ellipse approximation is the same as AutoCAD's one (i.e. PELLIPSE = 1).

The EL2PL command converts the selected ellipses or elliptical arcs in lwpolylines.
The PELL command let the user draw a polyline ellipse approximation as with te native ELLIPSE command.

Code - Auto/Visual Lisp: [Select]
  1. ;; EllipseToPolyline
  2. ;; Returns a polyline (vla-object) which is an approximation of the ellipse (or elliptical arc)
  3. ;;
  4. ;; Argument : an ellipse (vla-object)
  5.  
  6. (defun EllipseToPolyline (el    /     cl    norm  cen   elv   pt0   pt1   pt2   pt3   pt4   ac0
  7.                           ac4   a04   a02   a24   bsc0  bsc2  bsc3  bsc4  plst  blst  spt   spa
  8.                           fspa  srat  ept   epa   fepa  erat  n
  9.                          )
  10.   (setq cl   (= (ang<2pi (vla-get-StartAngle el))
  11.                 (ang<2pi (vla-get-EndAngle el)))
  12.         norm (vlax-get el 'Normal)
  13.         cen  (trans (vlax-get el 'Center) 0 norm)
  14.         elv  (caddr cen)
  15.         cen  (3dTo2dPt cen)
  16.         pt0  (mapcar '+ (trans (vlax-get el 'MajorAxis) 0 norm) cen)
  17.         ac0  (angle cen pt0)
  18.         pt4  (mapcar '+ cen (trans (vlax-get el 'MinorAxis) 0 norm))
  19.         pt2  (3dTo2dPt (trans (vlax-curve-getPointAtparam el (/ pi 4.)) 0 norm))
  20.         ac4  (angle cen pt4)
  21.         a04  (angle pt0 pt4)
  22.         a02  (angle pt0 pt2)
  23.         a24  (angle pt2 pt4)
  24.         bsc0 (/ (ang<2pi (- a02 ac4)) 2.)
  25.         bsc2 (/ (ang<2pi (- a04 a02)) 2.)
  26.         bsc3 (/ (ang<2pi (- a24 a04)) 2.)
  27.         bsc4 (/ (ang<2pi (- (+ ac0 pi) a24)) 2.)
  28.         pt1  (inters pt0
  29.                      (polar pt0 (+ ac0 (/ pi 2.) bsc0) 1.)
  30.                      pt2
  31.                      (polar pt2 (+ a02 bsc2) 1.)
  32.                      nil
  33.              )
  34.         pt3  (inters pt2
  35.                      (polar pt2 (+ a04 bsc3) 1.)
  36.                      pt4
  37.                      (polar pt4 (+ a24 bsc4) 1.)
  38.                      nil
  39.              )
  40.         plst (list pt4 pt3 pt2 pt1 pt0)
  41.         blst (mapcar '(lambda (b) (tan (/ b 2.)))
  42.                      (list bsc4 bsc3 bsc2 bsc0)
  43.              )
  44.   )
  45.   (foreach b blst
  46.     (setq blst (cons b blst))
  47.   )
  48.   (foreach b blst
  49.     (setq blst (cons b blst))
  50.   )
  51.   (foreach p (cdr plst)
  52.     (setq ang  (angle cen p)
  53.           plst (cons
  54.                  (polar cen (+ ang (* 2 (- ac4 ang))) (distance cen p))
  55.                  plst
  56.                )
  57.     )
  58.   )
  59.   (foreach p (cdr plst)
  60.     (setq ang  (angle cen p)
  61.           plst (cons
  62.                  (polar cen (+ ang (* 2 (- ac0 ang))) (distance cen p))
  63.                  plst
  64.                )
  65.     )
  66.   )
  67.   (setq pl
  68.          (vlax-invoke
  69.            'AddLightWeightPolyline
  70.            (apply 'append
  71.                   (setq plst
  72.                          (reverse (if cl
  73.                                     (cdr plst)
  74.                                     plst
  75.                                   )
  76.                          )
  77.                   )
  78.            )
  79.          )
  80.   )
  81.   (vlax-put pl 'Normal norm)
  82.   (vla-put-Elevation pl elv)
  83.   (mapcar '(lambda (i v) (vla-SetBulge pl i v))
  84.           '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
  85.           blst
  86.   )
  87.   (if cl
  88.     (vla-put-Closed pl :vlax-true)
  89.     (progn
  90.       (setq spt  (vlax-curve-getClosestPointTo pl (vlax-get el 'Startpoint))
  91.             spa  (vlax-curve-getParamAtPoint pl spt)
  92.             fspa (fix spa)
  93.             ept  (vlax-curve-getClosestPointTo pl (vlax-get el 'Endpoint))
  94.             epa  (vlax-curve-getParamAtPoint pl ept)
  95.             fepa (fix epa)
  96.             n    0
  97.       )
  98.       (cond
  99.         ((equal spt (trans pt0 norm 0) 1e-9)
  100.          (if (= epa fepa)
  101.            (setq plst (sublist plst 0 (1+ fepa))
  102.                  blst (sublist blst 0 (1+ fepa))
  103.            )
  104.            (setq erat (/ (- (vlax-curve-getDistAtParam pl epa)
  105.                             (vlax-curve-getDistAtParam pl fepa)
  106.                          )
  107.                          (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
  108.                             (vlax-curve-getDistAtParam pl fepa)
  109.                          )
  110.                       )
  111.                  plst (append (sublist plst 0 (1+ fepa))
  112.                               (list (3dTo2dPt (trans ept 0 norm)))
  113.                       )
  114.                  blst (append (sublist blst 0 (1+ fepa))
  115.                               (list (k*bulge (nth fepa blst) erat))
  116.                       )
  117.            )
  118.          )
  119.         )
  120.         ((equal ept (trans pt0 norm 0) 1e-9)
  121.          (if (= spa fspa)
  122.            (setq plst (sublist plst fspa nil)
  123.                  blst (sublist blst fspa nil)
  124.            )
  125.            (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  126.                             (vlax-curve-getDistAtParam pl spa)
  127.                          )
  128.                          (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  129.                             (vlax-curve-getDistAtParam pl fspa)
  130.                          )
  131.                       )
  132.                  plst (cons (3dTo2dPt (trans spt 0 norm))
  133.                             (sublist plst (1+ fspa) nil)
  134.                       )
  135.                  blst (cons (k*bulge (nth fspa blst) srat)
  136.                             (sublist blst (1+ fspa) nil)
  137.                       )
  138.            )
  139.          )
  140.         )
  141.         (T
  142.          (setq srat (/ (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  143.                           (vlax-curve-getDistAtParam pl spa)
  144.                        )
  145.                        (- (vlax-curve-getDistAtParam pl (rem (1+ fspa) 17))
  146.                           (vlax-curve-getDistAtParam pl fspa)
  147.                        )
  148.                     )
  149.                erat (/ (- (vlax-curve-getDistAtParam pl epa)
  150.                           (vlax-curve-getDistAtParam pl fepa)
  151.                        )
  152.                        (- (vlax-curve-getDistAtParam pl (rem (1+ fepa) 17))
  153.                           (vlax-curve-getDistAtParam pl fepa)
  154.                        )
  155.                     )
  156.          )
  157.          (if (< epa spa)
  158.            (setq plst (append
  159.                         (if (= spa fspa)
  160.                           (sublist plst fspa nil)
  161.                           (cons (3dTo2dPt (trans spt 0 norm))
  162.                                 (sublist plst (1+ fspa) nil)
  163.                           )
  164.                         )
  165.                         (cdr (sublist plst 0 (1+ fepa)))
  166.                         (if (/= epa fepa)
  167.                           (list (3dTo2dPt (trans ept 0 norm)))
  168.                         )
  169.                       )
  170.                  blst (append
  171.                         (if (= spa fspa)
  172.                           (sublist blst fspa nil)
  173.                           (cons
  174.                             (k*bulge (nth fspa blst) srat)
  175.                             (sublist blst (1+ fspa) nil)
  176.                           )
  177.                         )
  178.                         (sublist blst 0 fepa)
  179.                         (if (= epa fepa)
  180.                           (list (nth fepa blst))
  181.                           (list (k*bulge (nth fepa blst) erat))
  182.                         )
  183.                       )
  184.            )
  185.            (setq plst (append
  186.                         (if (= spa fspa)
  187.                           (sublist plst fspa (1+ (- fepa fspa)))
  188.                           (cons (3dTo2dPt (trans spt 0 norm))
  189.                                 (sublist plst (1+ fspa) (- fepa fspa))
  190.                           )
  191.                         )
  192.                         (list (3dTo2dPt (trans ept 0 norm)))
  193.                       )
  194.                  blst (append
  195.                         (if (= spa fspa)
  196.                           (sublist blst fspa (- fepa fspa))
  197.                           (cons
  198.                             (k*bulge (nth fspa blst) srat)
  199.                             (sublist blst (1+ fspa) (- fepa fspa))
  200.                           )
  201.                         )
  202.                         (if (= epa fepa)
  203.                           (list (nth fepa blst))
  204.                           (list (k*bulge (nth fepa blst) erat))
  205.                         )
  206.                       )
  207.            )
  208.          )
  209.         )
  210.       )
  211.       (vlax-put pl 'Coordinates (apply 'append plst))
  212.       (foreach b blst
  213.         (vla-SetBulge pl n b)
  214.         (setq n (1+ n))
  215.       )
  216.     )
  217.   )
  218.   pl
  219. )
  220.  
  221. ;; Ang<2pi
  222. ;; Returns the angle expression betweem 0 and 2*pi
  223. (defun ang<2pi (ang)
  224.   (if (and (<= 0 ang) (< ang (* 2 pi)))
  225.     ang
  226.     (ang<2pi (rem (+ ang (* 2 pi)) (* 2 pi)))
  227.   )
  228. )
  229.  
  230. ;; 3dTo2dPt
  231. ;; Returns the 2d point (x y) of a 3d point (x y z)
  232. (defun 3dTo2dPt (pt) (list (car pt) (cadr pt)))
  233.  
  234. ;; Tan
  235. ;; Returns the angle tangent
  236. (defun tan (a) (/ (sin a) (cos a)))
  237.  
  238. ;; SUBLIST
  239. ;; Returns a sub list
  240. ;;
  241. ;; Arguments
  242. ;; lst : a list
  243. ;; start : start index (first item = 0)
  244. ;; leng : the sub list length (number of items) or nil
  245. (defun sublist (lst start leng / n r)
  246.   (if (or (not leng) (< (- (length lst) start) leng))
  247.     (setq leng (- (length lst) start))
  248.   )
  249.   (setq n (+ start leng))
  250.   (while (< start n)
  251.     (setq r (cons (nth (setq n (1- n)) lst) r))
  252.   )
  253. )
  254.  
  255. ;; K*BULGE
  256. ;; Returns the proportinal bulge to the référence bulge
  257. ;; Arguments :
  258. ;; b : the bulge
  259. ;; k : the proportion ratio (between angles or arcs length)
  260. (defun k*bulge (b k / a)
  261.   (setq a (atan b))
  262.   (/ (sin (* k a)) (cos (* k a)))
  263. )
  264.  
  265. ;; EL2PL
  266. ;; Converts ellipses and elliptcal arcs into polylines
  267.  
  268. (defun c:el2pl (/ *error* fra acdoc ss)
  269.   (defun *error* (msg)
  270.     (if (and (/= msg "Fonction annulée")
  271.              (/= msg "Function cancelled")
  272.         )
  273.       (princ (strcat (if (= "FRA" (getvar 'locale))
  274.                        "\nErreur: "
  275.                        "\Error: "
  276.                      )
  277.                      msg
  278.              )
  279.       )
  280.     )
  281.     (vla-endUndoMark acdoc)
  282.     (princ)
  283.   )
  284.   (if (ssget '((0 . "ELLIPSE")))
  285.     (progn
  286.       (vla-StartUndoMark acdoc)
  287.       (vlax-for e (setq ss (vla-get-ActiveSelectionSet acdoc))
  288.         (EllipseToPolyline e)
  289.         (vla-delete e)
  290.       )
  291.       (vla-delete ss)
  292.       (vla-EndUndoMark acdoc)
  293.     )
  294.   )
  295.   (princ)
  296. )
  297.  
  298. ;; PELL
  299. ;; Draws an ellipse or an elliptical arc approximation (polyline) on the fly
  300. (defun c:pell (/ *error* ec pe old ent)
  301.   (defun *error* (msg)
  302.     (if (and msg
  303.              (/= msg "Fonction annulée")
  304.              (/= msg "Function cancelled")
  305.         )
  306.       (princ (strcat (if (= "FRA" (getvar 'locale))
  307.                        "\nErreur: "
  308.                        "\Error: "
  309.                      )
  310.                      msg
  311.              )
  312.       )
  313.     )
  314.     (setvar 'cmdecho ec)
  315.     (setvar 'pellipse pe)
  316.     (princ)
  317.   )
  318.   (setq ec  (getvar 'cmdecho)
  319.         pe  (getvar 'pellipse)
  320.         old (entlast)
  321.   )
  322.   (setvar 'cmdecho 1)
  323.   (setvar 'pellipse 0)
  324.   (command "_.ellipse")
  325.   (while (/= 0 (getvar 'cmdactive))
  326.     (command pause)
  327.   )
  328.   (if (not (eq old (setq ent (entlast))))
  329.     (progn
  330.       (EllipseToPolyline (vlax-ename->vla-object ent))
  331.       (entdel ent)
  332.     )
  333.   )
  334.   (*error* nil)
  335. )


This 400 pages of code (lol...jk) is why lisp is so valuable