找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1919|回复: 20

[求助] [求助]:求点表中所有点是否共线

[复制链接]
发表于 2005-5-9 18:34:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
求点表中所有点是否共线大家有什么高招~
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 593个

财富等级: 财运亨通

发表于 2005-5-9 18:57:02 | 显示全部楼层
取两点然后判断其他点,用几何方法判断是否共线。算法我转贴过一个链接。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-9 20:16:48 | 显示全部楼层
以角度判断:
[php]
(defun test (ptlst)
  (if (setq pt1 (car ptlst))
    (setq ptlst (vl-remove pt1 ptlst))
  )
  (if (setq pt2 (car ptlst))
    (setq ptlst        (vl-remove pt2 ptlst)
          ang        (abs (angle pt1 pt2))
    )
  )
  
  (princ "\n共线测试,进度")
  (while (setq pt3 (car ptlst))
    (setq ptlst        (vl-remove pt3 ptlst)
          ang1        (abs (angle pt1 pt3))
          da        (abs (- ang1 ang))
    )   
    (if        (or(< da 0.00000001)(>= da 3.14159))
      (princ ".")
      (progn
        (princ "\n找到不共线点,退出!")
        (setq ptlst nil)
      )
    )
   
  )
  (princ)
)[/php]

(setq ptlst '((88.9966 -90.0683) (170.899 -79.6394) (243.811
-70.3552) (348.686 -57.0012) (455.558 -43.3928) (800.145 0.484633) (777.172
-2.44053) (734.224 -7.90932) (658.975 -17.491) (634.005 -20.6705) (576.075
-28.047) (481.188 -40.1292) (336.362 -58.5704) (405.279 -49.7949) (558.096
-30.3363) (540.118 -32.6255) (501.164 -37.5856) (447.229 -44.4533) (409.274
-49.2862) (361.332 -55.3909) (329.37 -59.4607) (285.423 -65.0567) (212.51
-74.3409) (173.557 -79.301) (133.605 -84.3882) (90.656 -89.857) (44.711
-95.7073) (29.729 -97.615) (-55.1693 -108.425) (-73.1478 -110.715)))
命令: (test ptlst)
共线测试,进度....................
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-9 23:23:28 | 显示全部楼层
da    (abs (- ang1 ang))
    )
    (if    (< da 0.00000001)

如果 ang1=0,ang=PI,那又如何?
比如 pt2 = (-1 0) pt1 =(0 0 ) pt3 =(1 0)
显然共线,但是 da=(abs (- 0 PI))=PI > 0.00000001
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2005-5-9 23:52:30 | 显示全部楼层

  1. (defun ptonln (ptl / p)
  2.   (setq p (car ptl))
  3.   (apply 'equal
  4.          (mapcar '(lambda (x)
  5.                     (if        (>= (setq an (angle p x)) pi)
  6.                       (- an pi)
  7.                       an
  8.                     )
  9.                   )
  10.                  (cdr ptl)
  11.          )
  12.   )
  13. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-10 07:56:15 | 显示全部楼层
最初由 eachy 发布
[B][code]
(defun ptonln (ptl / p)
  (setq p (car ptl))
  (apply 'equal
         (mapcar '(lambda (x)
                    (if        (>= (setq an (angle p x)) pi)
                      (- an pi)
                      an
                    )
                  )
                 (cdr ptl)
         ... [/B]

命令: !ptlst
((88.9966 -90.0683) (170.899 -79.6394) (243.811 -70.3552) (348.686 -57.0012)
(455.558 -43.3928) (800.145 0.484633) (777.172 -2.44053) (734.224 -7.90932)
(658.975 -17.491) (634.005 -20.6705) (576.075 -28.047) (481.188 -40.1292)
(336.362 -58.5704) (405.279 -49.7949) (558.096 -30.3363) (540.118 -32.6255)
(501.164 -37.5856) (447.229 -44.4533) (409.274 -49.2862) (361.332 -55.3909)
(329.37 -59.4607) (285.423 -65.0567) (212.51 -74.3409) (173.557 -79.301)
(133.605 -84.3882) (90.656 -89.857) (44.711 -95.7073) (29.729 -97.615)
(-55.1693 -108.425) (-73.1478 -110.715))

命令: (ptonln ptlst)
; 错误: 参数太多
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-10 10:14:23 | 显示全部楼层
[php]
;;测试:
(tt (c:gpt))  ;;返回T为共线,返回nil不共线
;;判断点集是否共线.
;; 方法一(角度判断)
(defun tt (lst / k lst ang a b roop)
  (setq k T roop T)
  (if(and (car lst)
          (cadr lst)
          (setq ang (rem (angle(car lst)(cadr lst)) PI))
     )
    (while (and roop
                (setq lst (cdr lst)
                       a  (car lst)
                       b  (cadr lst))
                )
      (if (and (not(equal a b 1e-4))
               (not(equal ang (rem (angle a b) PI) 1e-4)))
        (setq roop nil k nil)
      )
    )
)
k
)
;;在屏幕取点返回点集.
(defun c:gpt ()
  (setq ptlst nil)
  (while (setq pt (getpoint "\n选点:"))
    (setq ptlst (cons pt ptlst))
  )
  ptlst
)
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-10 10:48:40 | 显示全部楼层
利于余数,狂刀虽为陌生人,方法的确不错:)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-10 11:50:35 | 显示全部楼层
[php](defun pd-gx (lst / pt1 pt2 x dst1 dst2 pd ang)
(setq ang(+(angle(car lst)(cadr lst))(/ pi 2)))
(setq pt2(polar(setq pt1(car lst))ang 1e+3)pd t)
(mapcar '(lambda(x)
(if(not(equal(distance x pt2)
   (sqrt(+(*(setq dst1(distance x pt1))dst1)
    (*(setq dst2(distance pt1 pt2))dst2)))1e-3))
     (setq pd nil)
      )
       )(vl-remove(car lst)lst)
        )pd
           )
[/php]
我的方法,勾股定理
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-10 13:49:14 | 显示全部楼层
[php]
;;; 方法一(衍生1):
;; (tt2 (setq lst(c:gpt)))
(defun tt2 (lst / a)
  (setq lst (mapcar '(lambda (x) (rem x PI)) (mapcar 'angle (cdr lst) lst))
        a   (car lst))
  (apply 'and (mapcar '(lambda(x)(equal x a 1e-4)) lst))
)
[/php]

[php]
;;  方法二(距离判断):
;; (tt (setq lst(c:gpt)))
(defun tt (lst / k lst ang a b roop)
  (while
    (setq a   (car lst)
          b   (cadr lst)
          c   (caddr lst)
          lst (cdr lst)
          k   (if (and a b c (setq l1(distance a b) l2 (distance b c)l3(distance c a)))
                (equal (+ l1 l2 l3) (* 2 (max l1 l2 l3)) 1e-4)
                nil
              )
    )
  )
  (= 1 (length lst))
)
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2005-5-10 14:33:26 | 显示全部楼层
我一直用不好mapcar函数,哪位能解释一下下列函数的运行过程,先谢了!
(mapcar 'angle (cdr lst) lst)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-11 08:21:44 | 显示全部楼层

  1. ;|
  2. ;;BY LUCAS
  3. ;;把eachy的程序改了一下
  4. ;;(PTONLN (POINT LIST) (精確度))
  5. (setq PTL '((88.9966 -90.0683)
  6.             (170.899 -79.6394)
  7.             (243.811 -70.3552)
  8.             (348.686 -57.0012)
  9.             (455.558 -43.3928)
  10.             (800.145 0.484633)
  11.             (777.172 -2.44053)
  12.             (734.224 -7.90932)
  13.             (658.975 -17.491)
  14.             (634.005 -20.6705)
  15.             (576.075 -28.047)
  16.             (481.188 -40.1292)
  17.             (336.362 -58.5704)
  18.             (405.279 -49.7949)
  19.             (558.096 -30.3363)
  20.             (540.118 -32.6255)
  21.             (501.164 -37.5856)
  22.             (447.229 -44.4533)
  23.             (409.274 -49.2862)
  24.             (361.332 -55.3909)
  25.             (329.37 -59.4607)
  26.             (285.423 -65.0567)
  27.             (212.51 -74.3409)
  28.             (173.557 -79.301)
  29.             (133.605 -84.3882)
  30.             (90.656 -89.857)
  31.             (44.711 -95.7073)
  32.             (29.729 -97.615)
  33.             (-55.1693 -108.425)
  34.             (-73.1478 -110.715)
  35.            )
  36. )
  37. (PTONLN PTL 3)
  38. |;
  39. (defun PTONLN (PTL NOS / P)
  40.   (setq P (car PTL))
  41.   (apply '=
  42.          (mapcar '(lambda (X)
  43.                     (if        (>= (setq AN (angle P X)) pi)
  44.                       (rtos (- AN pi) 2 NOS)
  45.                       (rtos AN 2 NOS)
  46.                     )
  47.                   )
  48.                  (cdr PTL)
  49.          )
  50.   )
  51. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-11 11:11:42 | 显示全部楼层
再精简
[php]
;;(setq nos 3 ptl (c:gpt) )
;; 限制: 不适合于有多点和第一点重合的情况.
(defun tt3 (PTL NOS / P)
  (setq P (car PTL))
  (apply '=
         (mapcar '(lambda (X)
                      (rtos (rem (angle P X) pi) 2 NOS)
                  )
                 (cdr PTL)
         )
  )
)
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-11 11:28:53 | 显示全部楼层
除狂刀的方法2外,其它的都用到了ANGLE函数,ANGLE函数只能计算2D点的角度,如果点列表中加杂着3D点,判断肯定会失误。
我的想法是将点表向两个相互垂直的面进行投影,得到两组2D点表,然后用它们生成两条2D多义线,如果这两条多义线的面积属性为0,这样才能认为所给的点表中所有点共线。
具体代码如下:

  1.   [FONT=courier new]
  2. (defun pt_on_line_P (pt_list jd / OSMODE OUT1 OUT2 PL_OBJ)
  3.   (setq osmode (getvar "osmode"))
  4.   (setq cmdecho (getvar "cmdecho"))
  5.   (setvar "cmdecho" 0)
  6.   (setvar "osmode" 0)
  7.   (setq pt_list (gf_pt_list pt_list))
  8.   (command "pline")
  9.   (foreach pt (mapcar '(lambda (x)
  10.                          (list (car x) (cadr x))
  11.                        )
  12.                       pt_list
  13.               )
  14.     (command pt)
  15.   )
  16.   (command "")
  17.   (setq pl_obj (vlax-ename->vla-object (entlast)))
  18.   (setq out1 (equal (vla-get-area pl_obj) 0 jd))
  19.   (vla-delete pl_obj)
  20.   (command "pline")
  21.   (foreach pt (mapcar '(lambda (x)
  22.                          (list (car x) (caddr x))
  23.                        )
  24.                       pt_list
  25.               )
  26.     (command pt)
  27.   )
  28.   (command "")
  29.   (setq pl_obj (vlax-ename->vla-object (entlast)))
  30.   (setq out2 (equal (vla-get-area pl_obj) 0 jd))
  31.   (vla-delete pl_obj)
  32.   (setvar "osmode" osmode)
  33.   (setvar "cmdecho" cmdecho)
  34.   (and out1 out2)
  35. )
  36. (defun gf_pt_list (pt_list / I OUT OUT1)
  37.   (setq out '())
  38.   (foreach pt pt_list
  39.     (setq out1 '()
  40.           i    0
  41.     )
  42.     (repeat 3
  43.       (if (nth i pt)
  44.         (setq out1 (cons (nth i pt) out1))
  45.         (setq out1 (cons 0 out1))
  46.       )
  47.       (setq i (1+ i))
  48.     )
  49.     (setq out (cons (reverse out1) out))
  50.   )
  51.   (reverse out)
  52. )
  53.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-5-11 14:54:17 | 显示全部楼层
多义线求面积方法我也想过,但是一来写起来麻烦一些.二来还要进行自相交的判断.(班竹的程序没有自相交判断,理论上是有bug的)
否则如图自相交3d多义线,红线各点求出的任意两个面上多义线面积衡为0.但是他们实际上却不是在一条线上的
另外,我认为除了求距离比较可靠的还有ucs方法.

[php]
;;; 判断点集是否共线. ------by 狂刀.2005.5  适合于3d情况.点重合情况.
;;  方法三(ucs方法):
;;  共点返回nil,但有文字提示.
;;  nos = 精度. 为数值.
;; (tt  (setq lst(c:gpt)) (setq nos 4))
(defun tt (lst nos / lst2 a b k)
  (setq lst2 (mapcar '(lambda(x)(trans x 1 0)) lst))
  (while(and   (setq a (car lst2))
               (setq b (cadr lst2))
               (setq lst2 (cdr lst2))
               (equal a b 1e-4))
  )
  (if (and a b)
    (progn
      (command ".ucs" "n" "3" a b "")
      (setq k (and(apply '= (mapcar '(lambda(x)(rtos x nos))(print(mapcar 'cadr (mapcar '(lambda(x)(trans x 0 1)) lst2)))))
                  (apply '= (mapcar '(lambda(x)(rtos x nos))(print(mapcar 'caddr (mapcar '(lambda(x)(trans x 0 1)) lst2)))))
              )
      )
      (command ".ucs" "p")
    )
    (print "\n 共点!")
  )k
)
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-18 02:33 , Processed in 0.420695 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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