明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2414|回复: 12

[讨论] 求点集共线精简程序

  [复制链接]
发表于 2007-4-11 11:43 | 显示全部楼层 |阅读模式
以下是判断点集共线程序,总感觉太复杂,请高手出招!!
  1. ;;  判断点集共线
  2.   (defun on_line (plst / a b c)
  3.     (setq a (car plst) b (cadr plst) c (cdr (cdr plst)))
  4.     (not (vl-catch-all-error-p
  5.            (vl-catch-all-apply
  6.              'mapcar (list '(lambda (x / an)
  7.                              (setq an (angle a x))
  8.                              (if (not (or (equal an (angle b x) 1e-6)
  9.                                           (equal an (angle x b) 1e-6)
  10.                                       )
  11.                                  )
  12.                                (exit)
  13.                              )
  14.                             )
  15.                            c
  16.                      )
  17.            )
  18.          )
  19.     )
  20.   )
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2007-4-11 20:03 | 显示全部楼层
本帖最后由 作者 于 2007-4-11 20:08:10 编辑

  1. ;;;功能:判断点集共线
  2. ;;;日期:zml84 于 2007-04-11
  3. ;;;==============================
  4. (defun on_line (plst / a b c temp)
  5.     (if (< (length plst) 3)
  6.         nil
  7.         (if (setq a    (car plst)
  8.                     b    (cadr plst)
  9.                     c    (caddr plst)
  10.                     temp (or (equal (angle a b) (angle a c) 1e-6)
  11.                                 (equal (angle a b) (angle c a) 1e-6)
  12.                             )
  13.             )
  14.             (if (= (length plst) 3)
  15.                 t
  16.                 (on_line (cdr plst))
  17.             )
  18.             nil
  19.         )
  20.     )
  21. )
  1. ;;;==============================
  2. ;;;测试
  3. (defun c:tt (/ lst)
  4.     (setq lst (list
  5.                     '(0 0)
  6.                     '(3 3)
  7.                     '(-1 -1)
  8.                     '(10 10)
  9.                 )
  10.     )
  11.     (princ lst)
  12.     (princ (on_line lst))
  13.     (princ)
  14. )
发表于 2007-4-12 09:08 | 显示全部楼层

这个程序简单吧,而且运行时间要减少,只要找到一个点不在线上,即退出循环

;;;功能:判断点集共线
;;;日期:byghbcaixin 于 2007-04-12

(defun on_line (ptlst / n k)
  (setq n 2 k nil)
  (while (and (not k) (< n (length ptlst)))
    (if (inters (car ptlst) (cadr ptlst) (car ptlst) (nth n ptlst) nil) (setq k t))
    (setq n (1+ n))
  )
  k
)

点评

T,nil  发表于 2020-3-7 21:22
说下返回是啥?好判断啊  发表于 2020-3-7 21:22
 楼主| 发表于 2007-4-12 09:42 | 显示全部楼层
本帖最后由 作者 于 2007-4-12 10:01:24 编辑

多谢两位!

我用 exit 仍然可以退出循环

byghbcx 的 inters 思路比较好!!

把最后的返回改成 (not k) 看起来比较直观

顺便问以下,怎样能测试程序的运行时间(具体数据),谢谢!

发表于 2007-4-12 10:48 | 显示全部楼层

这个时间很短,基本不用测试,如需测试可加入

(defun on_line (ptlst / n k t0)
  (setq n 2 k nil)
  (setq t0 (getvar "TDUSRTIMER"))
  (while (and (not k) (< n (length ptlst)))
    (if (inters (car ptlst) (cadr ptlst) (car ptlst) (nth n ptlst) nil) (setq k t))
    (setq n (1+ n))
  )
  (princ "\n共用时")
  (princ (* (- (getvar "TDUSRTIMER") t0) 86400000))
  (princ "毫秒")
  k
)

发表于 2007-4-12 18:34 | 显示全部楼层
本帖最后由 作者 于 2007-4-12 18:46:38 编辑

将第1、2、3楼的代码整合起来,修改测试代码后,测试结果如下:
  1. 命令:
  2. 命令:  TT
  3. 测试on_line_01 : T  共用时16.0毫秒
  4. 测试on_line_02 : T  共用时891.0毫秒
  5. 测试on_line_022 : T  共用时485.0毫秒
  6. 测试on_line_03 : nil  共用时1313.0毫秒命令:
  7. 命令:  TT
  8. 测试on_line_01 : T  共用时15.0毫秒
  9. 测试on_line_02 : T  共用时1000.0毫秒
  10. 测试on_line_022 : T  共用时547.0毫秒
  11. 测试on_line_03 : nil  共用时1922.0毫秒
  12. 命令:
  13. 命令:  TT
  14. 测试on_line_01 : T  共用时16.0毫秒
  15. 测试on_line_02 : T  共用时813.0毫秒
  16. 测试on_line_022 : T  共用时485.0毫秒
  17. 测试on_line_03 : nil  共用时1375.0毫秒
复制代码
不知为何,3楼的代码返回NIL?·!
全部代码如下:
  1. ;;  判断点集共线
  2. (defun on_line_01 (plst / a b c)
  3.     (setq a (car plst)
  4.    b (cadr plst)
  5.    c (cdr (cdr plst))
  6.     )
  7.     (not
  8. (vl-catch-all-error-p
  9.      (vl-catch-all-apply
  10.   'mapcar
  11.   (list '(lambda (x / an)
  12.       (setq an (angle a x))
  13.       (if (not (or (equal an (angle b x) 1e-6)
  14.      (equal an (angle x b) 1e-6)
  15.         )
  16.           )
  17.           (exit)
  18.       )
  19.          )
  20.         c
  21.   )
  22.      )
  23. )
  24.     )
  25. )
  26. ;;;==============================
  27. ;;;功能:判断点集共线
  28. ;;;日期:zml84 于 2007-04-11
  29. ;;;==============================
  30. (defun on_line_02 (plst / a b c)
  31.     (if (< (length plst) 3)
  32. nil
  33. (if (setq a    (car plst)
  34.     b    (cadr plst)
  35.     c    (caddr plst)
  36.     temp (or (equal (angle a b) (angle a c) 1e-6)
  37.       (equal (angle a b) (angle c a) 1e-6)
  38.          )
  39.      )
  40.      (if (= (length plst) 3)
  41.   t
  42.   (on_line_02 (cdr plst))
  43.      )
  44.      nil
  45. )
  46.     )
  47. )
  48. ;;;==============================
  49. (defun on_line_022 (plst / a b c)
  50. ;;;    (if (< (length plst) 3)
  51. ;;; nil
  52.     (if (setq a    (car plst)
  53.        b    (cadr plst)
  54.        c    (caddr plst)
  55.        temp (or (equal (angle a b) (angle a c) 1e-6)
  56.          (equal (angle a b) (angle c a) 1e-6)
  57.      )
  58. )
  59. (if (= (length plst) 3)
  60.      t
  61.      (on_line_022 (cdr plst))
  62. )
  63. nil
  64.     )
  65. ;;;    )
  66. )
  67. ;;;==============================
  68. ;;;功能:判断点集共线
  69. ;;;日期:byghbcaixin 于 2007-04-12
  70. (defun on_line_03 (ptlst / n k)
  71.     (setq n 2
  72.    k nil
  73.     )
  74.     (while (and (not k) (< n (length ptlst)))
  75. (if (inters (car ptlst)
  76.       (cadr ptlst)
  77.       (car ptlst)
  78.       (nth n ptlst)
  79.       nil
  80.      )
  81.      (setq k t)
  82. )
  83. (setq n (1+ n))
  84.     )
  85.     k
  86. )
  87. ;;;==============================
  88. ;;;测试
  89. (defun c:tt (/ lst i t0)
  90.     (setq lst '()
  91.    i   1
  92.     )
  93.     (repeat 5000
  94. (setq lst (cons (list i i) lst)
  95.        i   (1+ i)
  96. )
  97.     )
  98.     ;;====
  99.     (princ "\n测试on_line_01 : ")
  100.     (setq t0 (getvar "TDUSRTIMER"))
  101.     (princ (on_line_01 lst))
  102.     (princ "  共用时")
  103.     (princ (* (- (getvar "TDUSRTIMER") t0) 86400000))
  104.     (princ "毫秒")
  105.     ;;====
  106.     (princ "\n测试on_line_02 : ")
  107.     (setq t0 (getvar "TDUSRTIMER"))
  108.     (princ (on_line_02 lst))
  109.     (princ "  共用时")
  110.     (princ (* (- (getvar "TDUSRTIMER") t0) 86400000))
  111.     (princ "毫秒")
  112.     ;;====
  113.     (princ "\n测试on_line_022 : ")
  114.     (setq t0 (getvar "TDUSRTIMER"))
  115.     (princ (on_line_022 lst))
  116.     (princ "  共用时")
  117.     (princ (* (- (getvar "TDUSRTIMER") t0) 86400000))
  118.     (princ "毫秒")
  119.     ;;====
  120.     (princ "\n测试on_line_03 : ")
  121.     (setq t0 (getvar "TDUSRTIMER"))
  122.     (princ (on_line_03 lst))
  123.     (princ "  共用时")
  124.     (princ (* (- (getvar "TDUSRTIMER") t0) 86400000))
  125.     (princ "毫秒")
  126.     (princ)
  127. )

本帖子中包含更多资源

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

x
发表于 2007-4-13 09:13 | 显示全部楼层
看来,只有ANGLE算法最省时,INTERS算法较费时,运行时间不能看语句的长短.再发一个简单代码吧:
  1. (defun on_line_04 (ptlst / k)
  2.   (command "_.ucs" "n" "3" (car ptlst) (cadr ptlst) "")
  3.   (setq k t)
  4.   (mapcar '(lambda(x) (if (/= (cadr (trans x 0 1)) 0.0) (setq k nil))) ptlst)
  5.   (command "_.ucs" "w")
  6.   k
  7.   )
 楼主| 发表于 2007-4-13 09:55 | 显示全部楼层

回 byghbcx

避免每次循环都对 le a b求值

(defun on_line (ptlst / le n k a b)
  (setq n 2 k T le (length ptlst) a (car ptlst) b (cadr ptlst))
  (while (and k (< n le))
    (if (inters a b a (nth n ptlst) nil)
      (setq k nil)
    )
    (setq n (1+ n))
  )
  k
)

修改后返回 125 毫秒

 楼主| 发表于 2007-4-13 11:23 | 显示全部楼层
本帖最后由 作者 于 2007-4-13 12:01:27 编辑

;;来一个更简洁的
  1. ;;求点集共线---by caoyin
  2. (defun on_line (plst / p)
  3.   (setq p (apply 'mapcar (cons '+ plst)))
  4.   (not (inters (car plst) p (cadr plst) p nil))
  5. )
发表于 2007-4-13 15:31 | 显示全部楼层

这个测试不正确,从理论上讲也是不对的.如果所有点共线,那么这所有点的代数和所构成的点(X1+X2+X3+...Xn,Y1+Y2+Y3+...Yn)一定在这条线上.反之则不然,如果两个点或更多的点不共线,而它们的代数和的点在线上,所以不能以此来判断.

你可以测试一下,你把不在线上的点加到点集的末尾,返回的也是T,这可能与INTERS的精度有关.如果不是精度问题,按道理,加入一个'(0 100)点,应该返回NIL,但同时加入两个点'(0 100)、点'(100 0)应该返回T。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-19 13:51 , Processed in 0.262957 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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