明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1616|回复: 28

[函数] 点集中最近两点-->>(距离 (p1 p2))

[复制链接]
发表于 2025-7-24 10:57:53 | 显示全部楼层 |阅读模式
本帖最后由 韩飞翔 于 2025-7-27 16:31 编辑

10000个点0.6秒完成,有需要的下载
;;    =============================================
;;    |          点集中距离最近的两点            |
;;    =============================================
;;说明:点集中距离最近两点-->>得到表 (距离 (p1 p2))
;;参数:ptn:点集
;;参数:mode: t 点集来自点选择集  nil其他图元处理得到的点集
;;返回:  (fx-ptn-minNear2pt ptn t)

本帖子中包含更多资源

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

x

评分

参与人数 1明经币 +2 收起 理由
xyp1964 + 2 赞一个!

查看全部评分

回复

使用道具 举报

发表于 2025-7-26 06:18:41 | 显示全部楼层
guosheyang 发表于 2025-7-25 09:01
哦  记错了  是递归哥   曾经写过

高大侠写过。
http://bbs.mjtd.com/forum.php?mo ... E%D0%A1%BE%E0%C0%EB

点评

我也把最终的代码贴到高飞鸟大师的这个帖子后面了;  发表于 2025-7-26 14:14
我去这个帖子下载了代码测试了一下,貌似我这个代码速度比高飞鸟大师的还要快3倍多  发表于 2025-7-26 14:07
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2025-7-25 09:33:35 | 显示全部楼层
gzxl 发表于 2025-7-24 21:18
综合经验来说(个人观点),lisp 与 arx 以一万个点求解最近点对的话,在同一算法基础上两者速度综合约10~2 ...

;测试代码;直接复制到命令行;同时加载那个vlx文件;看看大概差多少
(defun c:tt(/ fx-ssget-10pt-ptn fx-time-st l ptn)
        (defun fx-ssget-10pt-ptn (ss / i l a b c)
                (setq i 0)
                (if ss
                        (repeat (sslength ss)
                                (setq a (ssname ss i))
                                (setq i (1+ i))
                                (setq b (entget a))
                                (setq c (cdr (assoc 10 b)))
                                (setq l (cons c l))
                        )
                )
                (reverse l)
        )
        (setq ptn (fx-ssget-10pt-ptn (ssget '((0 . "point")))))
        (setq fx-time-st (car (_vl-times)))
        (setq l (fx-ptn-minNear2pt ptn t))       
        (if fx-time-st (print (strcat "花费" (rtos (* 0.001 (- (car (_vl-times)) fx-time-st)) 2 4) "秒")))
        (vl-princ-to-string l)
)
回复 支持 反对

使用道具 举报

发表于 2025-7-24 13:51:48 | 显示全部楼层

以前收集的,粗暴的解决方式,感觉执行效率或许有点差强人意
  1. ;---点集的最远点和最近点(提前删除重复点)
  2. (defun xpts-lensort (plst / pt d maxd mind maxl minl)
  3.   (setq minl(list(car plst)(cadr plst)))
  4.   (setq mind(apply 'distance minl))
  5.   (setq maxd 0)
  6.   (while
  7.     (setq pt(car plst))
  8.     (setq plst(cdr plst))
  9.     (foreach n plst
  10.       (setq d(distance n pt))
  11.       (cond
  12.         ((< maxd d)(setq maxd d maxl(list n pt)))
  13.         ((> mind d)(setq mind d minl(list n pt)))
  14.       )
  15.     )
  16.   )
  17.   (list maxl minl)
  18. )

点评

aws
我一万个点,耗时23秒  发表于 2025-7-24 17:18
aws
或许是编译和未编译的区别,编译后效率提高很多  发表于 2025-7-24 17:03
那看来我电脑比较差;用你这个函数,我电脑处理10000个点,花费840.89秒;大概14分钟  发表于 2025-7-24 15:30
测试10000点大概需要2分钟  发表于 2025-7-24 14:37
这个少量点还可以,数量级过千后;效率极慢;  发表于 2025-7-24 14:16
回复 支持 反对

使用道具 举报

发表于 2025-7-24 12:15:22 | 显示全部楼层
好像高飞鸟版主也写过这个

点评

这个倒不清楚,我见过高飞鸟大师的写的点集的最小包围圆,根据这个可以比较容易的得到点集的最远两点;但是点集内最近两点,是完全不一样的,相信,如果让高飞鸟大师写一个点集最近两点的函数,应该比我的效率高。  发表于 2025-7-24 13:55
回复 支持 反对

使用道具 举报

发表于 2025-7-24 13:57:03 | 显示全部楼层
本帖最后由 bskidtf 于 2025-7-24 14:08 编辑

我可以说下我用C++写过的一个思路
点集根据先Y后X排序,排序时候就把重合点检测出来。有重合点那么就自然是距离最近的点了。
然后用四叉树,把点放进树里,第一个点和第二个点暂时当做是结果距离最近的两个点,记录距离,
然后遍历点集,每个点在这个记录的最近距离范围内搜索点,看有没有 比那个距离更小的点,记录那对点计算过距离,减少计算量。有点话就更新那个记录的最短距离和对应的点索引,这样遍历完就拿到了结果。我这十多年前的破电脑,10W点是秒出。20毫秒吧大概。

点评

这个方法用于lisp效率要慢很多很多;这个方法我之前用lisp试过一次了;虽然比普通挨个暴力循环快不少,但是还是慢;c++这么高效的语言,这几万个点确实又快又好,lisp比不了。  发表于 2025-7-24 14:12
回复 支持 反对

使用道具 举报

发表于 2025-7-24 14:46:29 | 显示全部楼层
感谢韩天师的分享
回复 支持 反对

使用道具 举报

发表于 2025-7-24 14:51:04 | 显示全部楼层
bskidtf 发表于 2025-7-24 13:57
我可以说下我用C++写过的一个思路
点集根据先Y后X排序,排序时候就把重合点检测出来。有重合点那么就自然 ...

这里关键点是四叉树,lisp不好解决这个问题,所以慢,并不是思路的问题。你可以说说你的思路,用C++写出来试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-24 15:13:38 | 显示全部楼层
bskidtf 发表于 2025-7-24 14:51
这里关键点是四叉树,lisp不好解决这个问题,所以慢,并不是思路的问题。你可以说说你的思路,用C++写出 ...

1、求得点集数量为n,按照每堆100个点分堆;即n/100; 2、得到点集的9点坐标的p1和p9点;以p1和p9的距离除以分堆数量;得到一个距离dis;根据这个距离将点集划分成小网格;每个网格的p1和p9再外扩这个dis的1/10;相当于让每个相邻网格都进行了部分重叠;然后每个网格内;形成点集;再根据你上面的算法得到最小距离的两点;然后最后取小网格的点集对比得到最小距离两点
回复 支持 反对

使用道具 举报

发表于 2025-7-24 16:10:42 | 显示全部楼层
分治法, 这样的重复计算量也不小的。我感觉速度不会比我说的那样快

点评

c++有可能是的;但是lisp就不一样了;您可以尝试一下,对比一下。  发表于 2025-7-24 18:33
回复 支持 反对

使用道具 举报

发表于 2025-7-24 16:18:38 | 显示全部楼层
本帖最后由 gzxl 于 2025-7-24 16:29 编辑

分治算法求解最近点对,速度也是可以的。




分治算法求解最近点对核心代码
http://bbs.mjtd.com/thread-191978-1-1.html

本帖子中包含更多资源

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

x

点评

c语言牛逼  发表于 2025-7-25 09:14
c语言牛逼  发表于 2025-7-24 18:35
回复 支持 反对

使用道具 举报

发表于 2025-7-24 21:18:34 | 显示全部楼层
综合经验来说(个人观点),lisp 与 arx 以一万个点求解最近点对的话,在同一算法基础上两者速度综合约10~20倍。lisp的速度 10000个点2秒那么应该不是最佳的算法。

点评

不过按照您说的那个10~20倍的速度差;那这个程序离最优也差蛮多  发表于 2025-7-25 09:51
也跟电脑配置有关系的,这个程序,在我电脑上2秒;昨天在我同事电脑上测试了一下0.6秒;应该在同一配置下测试看看;您拿我这个在您电脑上分别用lisp和c语言测试看看呢  发表于 2025-7-25 09:29
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-19 04:27 , Processed in 0.175482 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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