明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1776|回复: 33

[讨论] 求平面全等直线段封闭多边形最佳算法

[复制链接]
发表于 2023-3-23 09:23 | 显示全部楼层 |阅读模式
100明经币
本帖最后由 x_s_s_1 于 2023-3-23 14:51 编辑

本人几何水平及算法水平有限,写了一个求平面全等直线段封闭多边形的函数,用的是全部边角相等则全等的定理,感觉速度很慢,而且不是最佳算法。哪位能加个测速函数更好,谢谢。
下面是我写的函数
在我的电脑上92边形用时3869毫秒;四边形2902毫秒;自交四边形2949毫秒。

  1. ;;;=============================================
  2. ;;;      通用函数  全等多边形
  3. ;;;参数:en---------基准型
  4. ;;;      enlst------图元表
  5. ;;;返回值:(全等表)
  6. (defun xty-get-eqpl (en        enlst    fuzz  /   mirr_x
  7.          append_sas         eq_list  lst1   lst2
  8.          lst3     sasl1    sasl2
  9.          )
  10. ;;;单位向量
  11.   (defun vec-unit (v / dis)
  12.     (setq dis (distance v '(0 0 0)))
  13.     (cond ((= 1. dis) v)
  14.     ((> dis 1e-14) (mapcar '(lambda (n) (* n (/ 1.0 dis))) v))
  15.     ((equal 0. dis 1e-14) nil)
  16.     )
  17.     )
  18. ;;;内积
  19.   (defun vec-Dot (v1 v2)
  20.     (apply '+ (mapcar '* v1 v2))
  21.     )
  22. ;;;Y轴镜像表
  23.   (defun mirr_x  (ptl)
  24.     (mapcar '(lambda (x) (mapcar '* '(-1 1 1) x)) ptl)
  25.     )
  26. ;;;判断点列表是否顺时针方向
  27.   (defun Clockwise-p (lst)
  28.     (minusp
  29.       (apply '+
  30.        (mapcar
  31.          (function
  32.      (lambda (a b)
  33.        (- (* (car b) (cadr a)) (* (car a) (cadr b)))
  34.        )
  35.      )
  36.          lst
  37.          (cons (last lst) lst)
  38.          )
  39.        )
  40.       )
  41.     )

  42. ;;;形成反向sa表(边 角 ... 边 角),为效率,未reverse
  43.   (defun append_sas (lst / a b lst1 lst2 lst3 lst4)
  44.     (setq a    (list (car lst))
  45.     b    (list (cadr lst))
  46.     lst1 (append lst a)
  47.     lst2 (mapcar 'distance lst (cdr lst1))
  48.     lst  (append lst1 b)
  49.     )
  50.     (setq lst3 (mapcar '(lambda (x y) (vec-unit (mapcar '- y x)))
  51.            lst1
  52.            (cdr lst)
  53.            )
  54.     lst3 (mapcar '(lambda (v1 v2) (vec-Dot v1 v2))
  55.            lst3
  56.            (cdr lst3)
  57.            )
  58.     )
  59.     (while lst2
  60.       (setq lst4 (cons (car lst2) lst4)
  61.       lst2 (cdr lst2)
  62.       lst4 (cons (car lst3) lst4)
  63.       lst3 (cdr lst3)
  64.       )
  65.       )
  66.     lst4
  67.     )
  68. ;;;两等长sa表对比
  69.   (defun eq_list (lst1 lst2 fuzz / i n oi)
  70.     (setq n (* 0.5 (length lst1))
  71.     i 0
  72.     )
  73.     (while (< i n)
  74.       (if (vl-position
  75.       'nil
  76.       (mapcar '(lambda (x y) (equal x y fuzz)) lst1 lst2)
  77.       )
  78.   (setq lst2 (append (cddr lst2) (list (car lst2) (cadr lst2)))
  79.         i     (1+ i)
  80.         oi   nil
  81.         )
  82.   (setq oi t
  83.         i   n
  84.         )
  85.   )
  86.       )
  87.     oi
  88.     )
  89. ;;;获取lwpline点表
  90.   (defun get-plptlist (en /)
  91.     (mapcar 'cdr
  92.       (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget en))
  93.       )
  94.     )
  95.   (setq  lst1  (get-plptlist en)
  96.   lst1  (if (Clockwise-p lst1)
  97.     lst1
  98.     (reverse lst1)
  99.     )
  100.   sasl1 (append_sas lst1)
  101.   )
  102.   (foreach n enlst
  103.     (setq lst2  (get-plptlist n)
  104.     lst2  (if (Clockwise-p lst2)
  105.       lst2
  106.       (reverse lst2)
  107.       )
  108.     sasl2  (append_sas lst2)
  109.     )
  110.     (if  (eq_list sasl1 sasl2 fuzz)
  111.       (setq lst3 (cons n lst3))
  112.       (progn (setq lst2   (mirr_x lst2)
  113.        lst2   (if (Clockwise-p lst2)
  114.          lst2
  115.          (reverse lst2)
  116.          )
  117.        sasl2 (append_sas lst2)
  118.        )
  119.        (if (eq_list sasl1 sasl2 fuzz)
  120.          (setq lst3 (cons n lst3))
  121.          )
  122.        )
  123.       )
  124.     )
  125.   lst3
  126.   )
  127. (defun xty-tr-ss2lst (ss form / n en lst)
  128.   (repeat (setq n (sslength ss))
  129.     (setq en (ssname ss (setq n (1- n))))
  130.     (setq lst (cons en lst))
  131.     )
  132.   (setq lst (reverse lst))
  133.   (if form
  134.     lst
  135.     (mapcar (function vlax-ename->vla-object) lst)
  136.     )
  137.   )
  138. (defun xty-put-dxf (en code ch / ent)
  139.   (setq ent (entget en))
  140.   (if (assoc code ent)
  141.     (entmod (subst (cons code ch) (assoc code ent) ent))
  142.     (entmod (append ent (list (cons code ch))))
  143.     )
  144.   (entupd en)
  145.   )
  146. (defun c:tt (/ en ss time)
  147.   (setq    en (car (entsel"\n拾取基准型:"))
  148.     ss (ssget)
  149.     ss (xty-tr-ss2lst ss t)
  150.     )
  151.   (setq time (getvar "millisecs"))
  152.   (foreach n (xty-get-eqpl en ss 1e-6) (xty-put-dxf n 62 1))
  153.   (setq time (- (getvar "millisecs") time))
  154.   (print (strcat "经历时间为:" (itoa time) "毫秒"))
  155.   )

下面是测试图形



附件: 您需要 登录 才可以下载或查看,没有账号?注册
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2023-3-23 11:44 | 显示全部楼层
平移、旋转、镜像。
回复

使用道具 举报

发表于 2023-3-23 12:20 | 显示全部楼层
(defun c:t2 (/ en ss time xtjd-test xtjd-test2)
  (defun xtjd-test(en ss fuzz / s)
    (defun get(o)(list(length(vlax-get o 'Coordinates))(vla-get-Length o)(vla-get-area o)))
    (setq  s(get(vlax-ename->vla-object en)))
    (vl-remove-if-not(function(lambda(x)(equal s(get x)fuzz)))(mapcar 'vlax-ename->vla-object(ss->ens ss)))
  )
  (defun xtjd-test2(o)(vla-put-color o 1))
  (setq en(car(entsel"\n拾取基准型:"))ss(ssget))
  (setq time (getvar "millisecs"))
  (mapcar 'xtjd-test2(xtjd-test en ss 1e-6))
  (setq time (- (getvar "millisecs") time))
  (print (strcat "经历时间为:" (itoa time) "毫秒"))
)

评分

参与人数 1明经币 +1 金钱 +5 收起 理由
x_s_s_1 + 1 + 5 赞一个!

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2023-3-23 13:06 来自手机 | 显示全部楼层
xtjd 发表于 2023-3-23 12:20
(defun c:t2 (/ en ss time xtjd-test xtjd-test2)
  (defun xtjd-test(en ss fuzz / s)
    (defun get( ...

谢谢,不过面积和周长应该不是充分条件
回复

使用道具 举报

 楼主| 发表于 2023-3-23 13:11 来自手机 | 显示全部楼层
mahuan1279 发表于 2023-3-23 11:44
平移、旋转、镜像。

谢谢,但是由于基点和基线的不确定性,效率应该有问题
回复

使用道具 举报

发表于 2023-3-23 13:33 | 显示全部楼层
x_s_s_1 发表于 2023-3-23 13:11
谢谢,但是由于基点和基线的不确定性,效率应该有问题

你是判断平面内两个闭合图形全等?还是找出所有全等的图形?
回复

使用道具 举报

发表于 2023-3-23 14:11 | 显示全部楼层
x_s_s_1 发表于 2023-3-23 13:06
谢谢,不过面积和周长应该不是充分条件


本帖子中包含更多资源

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

x
回复

使用道具 举报

 楼主| 发表于 2023-3-23 14:41 来自手机 | 显示全部楼层
mahuan1279 发表于 2023-3-23 13:33
你是判断平面内两个闭合图形全等?还是找出所有全等的图形?

找出所有全等图形
回复

使用道具 举报

 楼主| 发表于 2023-3-23 14:44 来自手机 | 显示全部楼层
xtjd 发表于 2023-3-23 14:11

针对本测试图形是可以的,但是逻辑上不严密,有特例,仔细看92边形,有共线点,随便挪个点,你的代码就不对了。虽然边长和面积相等,但不是全等多边形。
回复

使用道具 举报

 楼主| 发表于 2023-3-23 14:52 | 显示全部楼层

我在一楼添加了一个测试图形,您再试试
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 00:53 , Processed in 0.215843 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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