明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: 20060510412

[提问] lisp能否实现四叉树算法?

[复制链接]
发表于 2024-3-14 12:30 | 显示全部楼层
本帖最后由 dcl1214 于 2024-3-14 12:42 编辑
你有种再说一遍 发表于 2024-3-13 16:40
要把优化进行到底,想想导航软件要是20秒出结果,那你也不用了,所以太长时间的操作只能是玩具,图算法不就是 ...

地图导航的时候,你从起点到终点,就一条数据,我说的四万是不同的起点和终点,单线程共计耗时20秒,仔细用脑想想

地图导航的方法可能更加简单了,比如说,你从北京到上海,那么可以在程序里面先导航省份到省份,因为省份到省份就几个高速路口,然后进入到省份的高速路口以后,再次调用城市的出入口,意思是可以区块化导航,该省略的节点信息可以省略掉,只用关键节点作为寻址
发表于 2024-3-14 14:37 | 显示全部楼层
(defun c:zdlj (/     a           b         dxf   dxf2  ents  ents2 es    jb
               jb2   jb-ks jb-pt jdcds l     old   old-cdr     p
               p2    ss
              )
        ;最短路径
  (vl-catch-all-apply 'load (list (findfile "zdlj.vlx")))
                                        ;声明引用zdlj.vlx这个模块
  (vl-catch-all-apply 'vl-doc-import (list "zdlj")) ;声明引用函数
  (SETQ JDCDS NIL)
  (SETQ ES NIL)
  (setq jb-pt nil)
  (SETQ SS (SSGET))
  (and ss(setq        ents (vl-remove-if
               (function listp)
               (mapcar (function cadr) (ssnamex SS))
             )
  ))
  (setq jb-ks nil)
  (while (setq a (car ents))
    (setq dxf nil)
    (setq jb nil)
    (setq p nil)
    (setq ents2 nil)
    (setq dxf (entget a))
    (setq jb (cdr (assoc 5 dxf)))
    (setq p (cdr (assoc 10 dxf)))
    (setq ents2 (cdr ents))
    (while (setq b (car ents2))
      (setq dxf2 nil)
      (setq jb2 nil)
      (setq p2 nil)
      (setq l nil)
      (setq old nil)
      (setq old-cdr nil)
      (setq dxf2 (entget B))
      (setq jb2 (cdr (assoc 5 dxf2)))
      (setq p2 (cdr (assoc 10 dxf2)))
      (SETQ L (DISTANCE P P2))
      (SETQ L (VL-PRINC-TO-STRING L))
      (setq old (assoc jb jb-ks));建立索引
      (setq old-cdr (cdr old))
      (setq old-cdr (cons (CONS (cons JB JB2) L) old-cdr))
      (setq jb-ks (vl-remove old jb-ks))
      (setq jb-ks (cons (cons jb old-cdr) jb-ks)) ;建立数据库索引
      (setq ents2 (cdr ents2))
    )
    (setq jb-pt (cons (cons jb p) jb-pt)) ;建立数据库索引
    (setq ents (cdr ents))
  )
  (setq
    jb-ks
     (mapcar
       (function
         (lambda (a)
           (cons
             (car a)
             (vl-sort (cdr a)
                      (function (lambda (x y) (< (cdr x) (cdr y))))
             )
           )
         )
       )
       jb-ks
     )
  )
  (setq jb-ks (reverse jb-ks))
  (mapcar (function (lambda (a / e1 e2 p1 p2)
                      (setq e1 (car a))
                      (setq e2 (cdr (car (car (cdr a)))))
                      (setq p1 (cdr (assoc e1 jb-pt))) ;启用索引
                      (setq p2 (cdr (assoc e2 jb-pt))) ;启用索引
                      (and p1
                           p2
                           (vla-addLine
                             (vla-Get-ModelSpace
                               (vla-get-ActiveDocument
                                 (vlax-get-acad-object)
                               )
                             )
                             (vlax-3D-Point p1)
                             (vlax-3D-Point p2)
                           )
                      )
                    )
          )
          jb-ks
  )
)
发表于 2024-3-14 16:09 | 显示全部楼层
本帖最后由 Gu_xl 于 2024-3-14 17:17 编辑

我觉得根据楼主题意,既然是在AutoCAD 的图上,那我们首要就是要充分利用AutoCAD本身的功能来实现目标,而不是去讨论算法什么的,这不是它的强项!下面是实现按半径查找代码,不管图上有多少个点,速度都很快!

  1. ;;参数 pt 位置点坐标
  2. ;;     jd 查找半径
  3. (defun gxl-sel-SSgetByPoint (pt jd / px py px0 px1 py0 py1 ss pz rtn e)
  4.   (setq  px  (car pt)
  5.   px0 (- px jd)
  6.   px1 (+ px jd)
  7.   py  (cadr pt)
  8.   py0 (- py jd)
  9.   py1 (+ py jd)
  10.   pz 1e99
  11.   )

  12.   (setq  ss
  13.    (ssget  "x"
  14.     (list '(0 . "point")
  15.           '(-4 . "<and")
  16.           '(-4 . ">=,>=,<>")
  17.           (list 10 px0 py0 pz)
  18.           '(-4 . "<=,<=,<>")
  19.           (list 10 px1 py1 pz)
  20.           '(-4 . "and>")
  21.     )
  22.    )
  23.   )
  24.   (if ss
  25.     (progn
  26.       (repeat (setq n (sslength ss))
  27.   (if (<= (distance (list (car pt) (cadr pt)) (cdr (assoc 10 (entget (setq e (ssname ss (setq n (1- n)))))))) jd)
  28.     (setq rtn (cons e rtn))
  29.     )
  30.   )
  31.       )
  32.   )
  33.   ;;颜色变红提示
  34.   (foreach e rtn (entmod (append (entget e) '((62 . 1)))))
  35.   ;;返回选中点图元名列表
  36.   rtn
  37. )
  38. ;;测试
  39. (defun c:tt (/ pt jd)
  40.   (setq rtn (gxl-sel-SSgetByPoint (setq pt (getpoint "\n位置点:")) (setq jd (getdist pt "\n半径:"))))
  41.   (command "circle" "_non" pt jd)
  42.   (princ (strcat "\n选中" (itoa (length rtn)) "个点."))
  43.   (princ)
  44.   )

本帖子中包含更多资源

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

x

点评

看到顾版回贴太激动人心了,这个图像个星云  发表于 2024-3-15 22:47

评分

参与人数 1金钱 +20 收起 理由
tigcat + 20 很给力!

查看全部评分

发表于 2024-3-14 16:14 | 显示全部楼层
dcl1214 发表于 2024-3-14 12:30
地图导航的时候,你从起点到终点,就一条数据,我说的四万是不同的起点和终点,单线程共计耗时20秒,仔细 ...

那你试试double改float能快多少
 楼主| 发表于 2024-3-14 19:09 | 显示全部楼层
本帖最后由 20060510412 于 2024-3-14 19:10 编辑
Gu_xl 发表于 2024-3-14 16:09
我觉得根据楼主题意,既然是在AutoCAD 的图上,那我们首要就是要充分利用AutoCAD本身的功能来实现目标,而 ...

顾版好,其实我本来的目的,是想找出距离某多段线特定距离范围内的点。

本来想的是对多段线进行偏移,使用形成的封闭区域再配合ssget,进行筛选。但是该方法的弊端,就是有时候多段线偏移之后无法形成有效的封闭区域。

全部遍历,根据每个点到多段线的距离进行筛选,效率又不高,所以才想到能否用四叉树的算法。
发表于 2024-3-15 08:54 | 显示全部楼层
20060510412 发表于 2024-3-14 19:09
顾版好,其实我本来的目的,是想找出距离某多段线特定距离范围内的点。

本来想的是对多段线进行偏移, ...

先按直线包围框用(ssget "x" )方法选出点,然后再逐点判断距离,可以大大减小计算量。
 楼主| 发表于 2024-3-15 09:10 | 显示全部楼层
Gu_xl 发表于 2024-3-15 08:54
先按直线包围框用(ssget "x" )方法选出点,然后再逐点判断距离,可以大大减小计算量。

谢谢顾版,目前用lisp的话,应该只能通过ssget的方式,减小计算量。
肯定比全部遍历要高效得多。
发表于 2024-3-16 12:59 | 显示全部楼层
本帖最后由 guosheyang 于 2024-3-16 13:17 编辑

多段线偏移之后无法形成有效的封闭区域 的情况     应该是偏移距离过大  造成自相交了   将偏移距离减小些就可以

本帖子中包含更多资源

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

x
 楼主| 发表于 2024-3-16 20:12 | 显示全部楼层
guosheyang 发表于 2024-3-16 12:59
多段线偏移之后无法形成有效的封闭区域 的情况     应该是偏移距离过大  造成自相交了   将偏移距离减小些 ...

是的,所以说偏移多段线的方法不通用。

还是取最小包围盒,更通用一些。
发表于 2024-3-17 19:16 | 显示全部楼层
你有种再说一遍 发表于 2024-3-14 16:14
那你试试double改float能快多少

跟这个没关系的,路径计算一定是先找到路径,最后计算,而不是一边找路径,一边计算
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 12:02 , Processed in 0.212864 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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