找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 10625|回复: 61

[点表] (XD::Pnts:RemoveDup)点表消除重复点

[复制链接]

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-11-14 00:30:35 | 显示全部楼层 |阅读模式
函数发布
函数名称: XD::Pnts:RemoveDup
调用格式: (XD::Pnts:RemoveDup pts fuzz)
参数说明: pts ---- 点表
fuzz---- 模糊精度值
返回值: 点表
函数简介: 点表消除重复点
函数来源: 原创
函数作者: XDSoft
适用版本: XDRX API 
最后更新时间: 2013-11-14
备注: -
演示图片: -

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

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

×
  1. ;|
  2. 消除重复点
  3. 参数:
  4.    pts ----  点表
  5.    fuzz----  模糊精度值
  6. 返回:点表
  7. |;
  8. (defun XD::Pnts:RemoveDup (pts fuzz / coord oldprec ori x xline xmin y yline ymin)
  9.   (setq xMin (apply 'min (mapcar 'car pts))
  10.         yMin (apply 'min (mapcar 'cadr pts))
  11.         coord (XD::UCS:CoordSys)
  12.         ori (list xMin yMin 0.0)
  13.         xLine (list ori (mapcar '+ ori (cadr coord)))
  14.         yLine (list ori (mapcar '+ ori (caddr coord)))
  15.         pts (mapcar
  16.               'cdr
  17.               (XD::assocList:RemoveDupByNumKey  (mapcar
  18.                                             '(lambda (x)
  19.                                                (list (abs
  20.                                                           (xdrx_point_dist2line x
  21.                                                                                 (car yLine)
  22.                                                                                 (cadr yLine)
  23.                                                           )
  24.                                                      ) x
  25.                                                )
  26.                                              )
  27.                                             pts
  28.                                           ) fuzz
  29.               )
  30.             ) ;;X方向距离相等的构建关联表
  31.         pts (mapcar
  32.               'car
  33.               (mapcar
  34.                 '(lambda (x)
  35.                    (mapcar
  36.                      'car
  37.                      (mapcar
  38.                        'cdr
  39.                        (XD::assocList:RemoveDupByNumKey  (mapcar
  40.                                                      '(lambda (y)
  41.                                                         (list (abs
  42.                                                                    (xdrx_point_dist2line y
  43.                                                                                          (car xLine)
  44.                                                                                          (cadr xLine)
  45.                                                                    )
  46.                                                               ) y
  47.                                                         )
  48.                                                       )
  49.                                                      x
  50.                                                    ) fuzz
  51.                        );;X方向相等的字表里面Y方向相等的构建关联表
  52.                      )
  53.                    )
  54.                  )
  55.                 pts
  56.               )
  57.             );;只保留CAR,其他重复点
  58.   )
  59.   pts
  60. )



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

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-11-14 05:31:25 来自手机 | 显示全部楼层
本帖最后由 st788796 于 2013-11-14 05:35 编辑

一般这样写
  1. (defun XD::Pnts:RemoveDup (pts fuzz /  ptl)
  2. (setq ptl (car pts))
  3.   (while (setq pts (cdr pts)
  4.                         pts (vl-remove-if '(lambda (p) (equal p (car ptl) fuzz)) pts))
  5.               (setq ptl (cons (car pts) ptl))
  6.       )
  7.       (reverse ptl)
  8.   )
  9. )

点评

(defun XD:nts:RemoveDup (ptLst fuzz / p pl) (while ptLst (setq p (car ptLst) pl (cons p pl) ptLst (vl-remove-if '(lambda (x) (equal p x fuzz)) ptLst ) ) ) (re  详情 回复 发表于 2013-11-14 08:13
你这个要N方,通过排序,能转化到N级别。  详情 回复 发表于 2013-11-14 07:48
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

 楼主| 发表于 2013-11-14 07:48:49 | 显示全部楼层

你这个要N方,通过排序,能转化到N级别。

点评

(defun XD:nts:RemoveDup (ptLst fuzz / p pl) (while ptLst (setq p (car ptLst) pl (cons p pl) ptLst (vl-remove-if '(lambda (x) (equal p x fuzz)) ptLst ) ) ) (  详情 回复 发表于 2013-11-14 08:11
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 191个

财富等级: 日进斗金

发表于 2013-11-14 07:52:35 | 显示全部楼层
感谢老大的回复 这么晚了还回复者及时,并且还专门写了这长的代码,不过我测试了下 这个函数貌似不能工作。  (XD::Pnts:RemoveDup (list '(1 0 0) '(2 0 0) '1(1 0 0)) 0) 就根本没有返回值

点评

你参数不都是点,能对吗 (list '(1 0 0) '(2 0 0) '1(1 0 0)) - 本文出自晓东CAD家园-论坛,原文地址:http://bbs.xdcad.net/thread-671604-1-1.html 怎么有个 ‘1  详情 回复 发表于 2013-11-14 08:08
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

 楼主| 发表于 2013-11-14 08:08:21 | 显示全部楼层
口味虾 发表于 2013-11-14 07:52
感谢老大的回复 这么晚了还回复者及时,并且还专门写了这长的代码,不过我测试了下 这个函数貌似不能工作。 ...

你参数不都是点,能对吗

(list '(1 0 0) '(2 0 0) '1(1 0 0))
- 本文出自晓东CAD家园-论坛,原文地址:http://bbs.xdcad.net/thread-671604-1-1.html

怎么有个 ‘1

点评

抱歉 回复贴的时候笔误,不过我这这个函数确实不能运行。  详情 回复 发表于 2013-11-14 09:36
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1757个

财富等级: 堆金积玉

发表于 2013-11-14 08:11:51 | 显示全部楼层
本帖最后由 守仁格竹GM 于 2013-11-14 08:14 编辑

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

使用道具 举报

已领礼包: 1757个

财富等级: 堆金积玉

发表于 2013-11-14 08:13:46 | 显示全部楼层

(defun XD:nts:RemoveDup (ptLst fuzz / p pl)
  (while ptLst
    (setq p (car ptLst)
   pl (cons p pl)
   ptLst (vl-remove-if
    '(lambda (x) (equal p x fuzz))
    ptLst
    )
    )
  )
  (reverse pl)
)
我觉得这样计算 看上去差不多 但是应该会减少很多重复判断的步骤。

点评

vl-remove-if这个函数 要遍历整个表的, 所以这个算法的时间效率上应该是N平方级的  详情 回复 发表于 2013-11-14 08:27
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-11-14 08:27:04 | 显示全部楼层
守仁格竹GM 发表于 2013-11-14 08:13
(defun XD:nts:RemoveDup (ptLst fuzz / p pl)
  (while ptLst
    (setq p (car ptLst)

vl-remove-if这个函数 要遍历整个表的, 所以这个算法的时间效率上应该是N平方级的

点评

对一般来说 vl 函数的效率足够了,原来离的近的点在排序后在表中位置可能有离的远了,这是有过实例的  详情 回复 发表于 2013-11-14 08:29
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-11-14 08:29:47 | 显示全部楼层
本帖最后由 st788796 于 2013-11-14 08:38 编辑
newer 发表于 2013-11-14 08:27
vl-remove-if这个函数 要遍历整个表的, 所以这个算法的时间效率上应该是N平方级的

对一般来说 vl 函数的效率足够了,原来离的近的点在排序后在表中位置可能有离的远了,这是有过实例的
最坏的情况是N的平方,vl-remove 后 lst 的长度可能是逐步缩短的

点评

不管,vl-remove的效率如何,那怕它秒杀,但如果把他放到一个两次循环的内部,那整个时间上还是慢的。这个是算法的时间,和单个函数无关。 如果能走一次N,就把X方向距离相等的都放到一起,再走一个N,再把X相等  详情 回复 发表于 2013-11-14 09:01
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-11-14 09:01:14 | 显示全部楼层
本帖最后由 newer 于 2013-11-14 09:03 编辑
st788796 发表于 2013-11-14 08:29
对一般来说 vl 函数的效率足够了,原来离的近的点在排序后在表中位置可能有离的远了,这是有过实例的
最 ...


不管,vl-remove的效率如何,那怕它秒杀,但如果把他放到一个两次循环的内部,那整个时间上还是慢的。这个是算法的时间,和单个函数无关。

如果能走一次N,就把X方向距离相等的都放到一起,再走一个N,再把X相等的里面的Y相等的在放一起。 然后哪怕再用你上面写的N方的函数分别对排序后的表再操作,这个时间也应该是质的提升的。你可以试试。

点评

这个不能放循环里的,即使在循环内, lst 的数量级不会大的  详情 回复 发表于 2013-11-14 09:02
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-11-14 09:02:56 | 显示全部楼层
newer 发表于 2013-11-14 09:01
不管,vl-remove的效率如何,那怕它秒杀,但如果把他放到一个两次循环的内部,那整个时间上还是慢的。这 ...

这个不能放循环里的,即使在循环内, lst 的数量级不会大的:)

点评

你现在这个写法,本身就是N2级别的。两个整表两辆元素比较。 你试试先排序下,然后用你的函数对小表操作,看看时间是不是质的提升。因为通过排序,把不可能相等的无关的都排除掉了。  详情 回复 发表于 2013-11-14 09:06
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-11-14 09:06:35 | 显示全部楼层
st788796 发表于 2013-11-14 09:02
这个不能放循环里的,即使在循环内, lst 的数量级不会大的

你现在这个写法,本身就是N2级别的。两个整表两辆元素比较。

你试试先排序下,然后用你的函数对小表操作,看看时间是不是质的提升。因为通过排序,把不可能相等的无关的都排除掉了。

点评

这个排序不能用 xyz 排序,以前用 xyz 排序后发现有问题才用这个简单方法,懒得再去深究  详情 回复 发表于 2013-11-14 09:09
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-11-14 09:09:49 | 显示全部楼层
newer 发表于 2013-11-14 09:06
你现在这个写法,本身就是N2级别的。两个整表两辆元素比较。

你试试先排序下,然后用你的函数对小表操 ...

这个排序不能用 xyz 排序,以前用 xyz 排序后发现有问题才用这个简单方法,懒得再去深究{:soso_e113:}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 191个

财富等级: 日进斗金

发表于 2013-11-14 09:36:50 | 显示全部楼层
XDSoft 发表于 2013-11-14 08:08
你参数不都是点,能对吗

(list '(1 0 0) '(2 0 0) '1(1 0 0))

抱歉 回复贴的时候笔误,不过我这这个函数确实不能运行。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-11-14 09:43:59 | 显示全部楼层
本帖最后由 st788796 于 2013-11-14 09:47 编辑

这个不排序直接用 vl-remove-if 在数量大的时候 CAD会死掉,不过这样写了下, 用 XD::List:GroupByIndex

  1. (defun Pnts:RemoveDup (pts fuzz /  pj ptl)
  2.   (setq        pj  (car (apply 'xdrx_points_box pts))
  3.         ptl (mapcar '(lambda (x) (list (distance x pj) x)) pts)
  4.         ptl (xd::list:groupbyindex ptl fuzz)
  5.   )
  6.   (mapcar 'cadr ptl)
  7. )
  8. (defun getutime () (* 86400 (getvar "tdusrtimer")))
  9. (defun c:tt (/ ss pts pts1 t0)
  10.   (if (setq ss (ssget '((0 . "point"))))
  11.     (progn
  12.       (setq pts        (mapcar        '(lambda (x) (xdrx_getpropertyvalue x "Position"))
  13.                         (xdrx_pickset->ents ss)
  14.                 )
  15.             t0        (getutime)
  16.       )
  17.       (setq pts1 (Pnts:Removedup pts 0.0001))
  18.       (princ (- (getutime) t0))
  19.       (princ "\n")
  20.       (princ (- (length pts1) (length pts)))
  21.     )
  22.   )
  23.   (princ)
  24. )

命令: TT
选择对象: 指定对角点: 找到 39312 个

选择对象:
0.795
-21

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 11:33 , Processed in 0.375873 second(s), 72 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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