明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: highflybir

【越飞越高讲堂14】椭圆论

    [复制链接]
发表于 2014-1-8 01:36:10 | 显示全部楼层
真的是大师级的,受教了,万分感谢
发表于 2014-2-17 14:59:52 | 显示全部楼层
我就喜欢挺这种贴,抱着学无止境的态度追逐
发表于 2014-2-25 14:39:24 | 显示全部楼层
向大师反应一个问题:
椭圆长短轴长为260X90这个尺寸,在双数等分周长时,CAD2010以下版本(如04,08)多数情况都会出错,但略改尺寸,如改为260X106等等或在单数等分时,则不出错。以上问题,在CAD2010版本中,260X90的椭圆在双数等分时又正常。
请教大师,看看是不是CAD版本的原因?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2014-3-12 22:02:16 | 显示全部楼层
本帖最后由 chlh_jd 于 2014-3-12 22:03 编辑

感谢高飞大师的总结!
Lee Mac 大师写了个5点拟合椭圆的程序:http://www.lee-mac.com/5pointellipse.html
我写了个最小二乘法拟合椭圆源码,欢迎大家批评指正:
;;最小二乘法拟合椭圆

  1. ;;;-------------------------------------------------------------
  2. (defun LS-Pts->Ellipse (lst  /    n arg_mat   res_vec   a  b
  3.     c    d    e f    res  xc   yc   aa  bb
  4.     ang  co   si co2  si2)
  5.   ;; by GSLS(SS)
  6.   ;; Pointset return Ellipse by Least Square method
  7.   ;; 2014-01-02
  8.   (if (> (setq n (length lst)) 4)
  9.     (progn
  10.       (mapcar (function (lambda (p / x y)
  11.      (setq x (car p)
  12.     y (cadr p))
  13.      (setq arg_mat (cons (list (* x y) (* y y) x y 1.)
  14.            arg_mat)
  15.     res_vec (cons (* -1. x x) res_vec))))
  16.        lst)
  17.       (setq res (solve-odeq arg_mat res_vec))
  18.       (mapcar (function set) (quote (a b c d e f)) (cons 1. res))
  19.       (if (= a c)
  20. (setq ang _pi2)
  21. (setq ang (* 0.5 (atan (/ b (- a c))))))
  22.       (if (and (/= f 0) (/= (setq delt (- (* 4. c) (* b b))) 0))
  23. (progn
  24.    (setq xc  (/ (- (* b e) (* 2. c d)) delt)
  25.   yc  (/ (- (* b d) (* 2. e)) delt)
  26.   co  (cos ang)
  27.   si  (sin ang)
  28.   co2 (* co co)
  29.   si2 (* si si)
  30.   bb  (sqrt
  31.         (abs (/ (- (* (- (* f co2)
  32.            (* (+ (* xc xc)
  33.           (* b xc yc)
  34.           (* c yc yc))
  35.        co2))
  36.         (- (* 2 xc si2)
  37.            (* 2 yc co si)
  38.            (* (+ xc xc (* b yc)) si2)))
  39.      (* (- (* f si2)
  40.            (* (+ (* xc xc)
  41.           (* b xc yc)
  42.           (* c yc yc))
  43.        si2))
  44.         (- (* 2 xc co2)
  45.            (* -2 yc co si)
  46.            (* (+ xc xc (* b yc)) co2))))
  47.          (+ (* 2 xc co2)
  48.      (* 2 yc co si)
  49.      (- (* (+ xc xc (* b yc)) co2))))))
  50.   aa  (*
  51.         (sqrt
  52.    (abs (- (/ (+ (* 2 xc co2)
  53.           (* 2 yc co si)
  54.           (* -1 (+ xc xc (* b yc)) co2))
  55.        (- (* 2 xc si2)
  56.           (* 2 yc co si)
  57.           (* (+ xc xc (* b yc)) si2))))))
  58.         bb)
  59.   )
  60.    (list (list xc yc) (polar (list 0 0) ang aa) (/ bb aa)))))
  61.     ))
通用最小二乘法函数

  1. (defun solve-odeq  (arg_mat res_vector / mat)
  2.   ;; Universal least squares method
  3.   ;; arg_mat    -- Parameters Matrix of Overdetermined Equations
  4.   ;; res_vector -- Right term of Overdetermined Equations
  5.   ;; by GSLS(SS) 2013.11.22
  6.   (setq mat ([*] ([trp] arg_mat) arg_mat)
  7. mat ([inv] mat))
  8.   (mxv ([*] mat ([trp] arg_mat)) res_vector))
  9. ;; Use function ---------------------------------------------
  10. ;; DotProduct
  11. (defun vxv (v1 v2) (apply (function +) (mapcar (function *) v1 v2)))
  12. ;; Matrix Vector Multiply
  13. (defun mxv (m v) (mapcar (function (lambda (r) (vxv r v))) m))
  14. ;; Transpose matrix
  15. (defun [trp] (a) (apply (function mapcar) (cons (function list) a)))
  16. ;; Matrix is multiplied by a matrix
  17. (defun [*] (m q) (mapcar (function (lambda (r) (mxv ([trp] q) r))) m))
  18. ;; To get Unit diagonal matrix
  19. (defun [I]  (d / i r n m)
  20.   (setq i d)
  21.   (while (<= 0 (setq i (1- i)))
  22.     (setq n d
  23.    r nil)
  24.     (while (<= 0 (setq n (1- n)))
  25.       (setq r (cons (if (= i n)
  26.         1.0
  27.         0.0)
  28.       r)))
  29.     (setq m (cons r m))))
  30. ;;; gile-inverse-matrix (gile) 2009/03/17
  31. ;; uses the gauss-jordan elimination method to calculate the inverse matrix of any dimension square matrix
  32. ;; argument : a square matrix
  33. ;; return : the inverse matrix (or nil if singular)
  34. ;; ([inv] '((1 2 3) (2 4 5) (3 5 6)));_([inv] '((2 1) (5 3)))
  35. (defun [inv]  (mat / col piv row res)
  36.   (setq mat (mapcar (function (lambda (x1 x2)
  37.     (append x1 x2)))
  38.       mat
  39.       ([I] (length mat))))
  40.   (while mat
  41.     (setq col (mapcar (function (lambda (x) (abs (car x)))) mat))
  42.     (repeat (vl-position (apply (function max) col) col)
  43.       (setq mat (append (cdr mat) (list (car mat)))))
  44.     (if (equal (setq piv (caar mat)) 0.0 1e-14)
  45.       (setq mat nil
  46.      res nil)
  47.       (setq piv (/ 1.0 (caar mat))
  48.      row (mapcar (function (lambda (x) (* x piv))) (car mat))
  49.      mat (mapcar (function
  50.      (lambda (r / e)
  51.        (setq e (car r))
  52.        (cdr (mapcar (function (lambda (x n)
  53.            (- x (* n e))))
  54.       r
  55.       row))))
  56.    (cdr mat))
  57.      res (cons (cdr row)
  58.         (mapcar
  59.    (function
  60.      (lambda (r / e)
  61.        (setq e (car r))
  62.        (cdr (mapcar (function (lambda (x n)
  63.            (- x (* n e))))
  64.       r
  65.       row))))
  66.    res)))))
  67.   (reverse res))
测试函数

  1. ;; E.G.
  2. ;; For Ellipse
  3. (defun c:test  (/ l r p10 a b p11 d40)
  4.   (prompt
  5.     "\nFit Ellipse though Least-square method , the points you selected must be at least 5 !!!")
  6.   (setq l (mapcar (function (lambda (x) (cdr (assoc 10 (entget x)))))
  7.     (vl-remove-if-not
  8.       (function (lambda (x) (eq (type x) 'ENAME)))
  9.       (mapcar 'cadr (ssnamex (ssget '((0 . "POINT")))))))
  10. l (mapcar (function (lambda (p)
  11.          (trans p 0 1 t)))
  12.     l))
  13.   (if (and (> (length l) 4) (setq r (LS-Pts->Ellipse l)))
  14.     (progn
  15.       (setq p10 (car r)
  16.      p11 (cadr r)
  17.      d40 (caddr r))
  18.       (entmake
  19. (append
  20.    '(
  21.      (000 . "ELLIPSE")
  22.      (100 . "AcDbEntity")
  23.      (100 . "AcDbEllipse"))
  24.    (list (cons 10 (trans p10 1 0 t))
  25.   (cons 11 (trans p11 1 0))
  26.   (cons 40 d40))
  27.    (list (cons 210 (trans '(0.0 0.0 1.0) 1 0 t)))))))
  28.   (princ)
  29.   )

评分

参与人数 1明经币 +3 金钱 +24 收起 理由
Gu_xl + 3 + 24 赞一个!

查看全部评分

发表于 2015-3-15 22:31:31 | 显示全部楼层
楼主的胸怀让人敬佩
发表于 2016-3-22 11:10:09 | 显示全部楼层
大师啊,真正的大师
发表于 2020-2-21 23:57:18 | 显示全部楼层

highflybir  是中国公开研究和发表很多椭圆相关高精尖知识的大师
发表于 2021-1-19 08:53:59 | 显示全部楼层
highflybir  的胸怀,所公开的内容没有留一手,并很热心帮助明经上的朋友,热心免费提供源代码
向 highflybir  致敬
发表于 2021-1-28 22:36:55 | 显示全部楼层

真的是大师级的,受教了,万分感谢
发表于 2023-10-6 09:10:53 | 显示全部楼层
tanjurun 发表于 2021-1-19 08:53
highflybir  的胸怀,所公开的内容没有留一手,并很热心帮助明经上的朋友,热心免费提供源代码
向 highfly ...

的确,值得钦佩。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-14 14:34 , Processed in 0.196431 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表