明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 123|回复: 7

[提问] 圆孔分类统计程序请大神优化,外径相同的圆经常被分成2种统计

[复制链接]
发表于 昨天 17:39 | 显示全部楼层 |阅读模式
5明经币
程序也是论坛找的,觉得很方便,但是用起来有几个小问题,希望有大神帮忙修改一下:

1.相同直径的圆经常会统计成不一样的(这是3D软件导出的2D图),希望同样外径的只有一种规格。
程序里面同心圆已经修改成只找外圆忽略内圆了,算一个沉头孔,这个不是BUG,需要保留。
2.块中的圆目前无法统计,如果能一起统计就更好了。
3.鼠标点击的位置是生成文字的左下角,希望改成左上角(不改变排列,还是直径小的在上面大的在下面)。

主要是第一点,其他点都可以用,只是希望能好,希望大神帮忙优化一下,谢谢,以下是目前程序的演示
源程序
测试的DWG

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

使用道具 举报

发表于 10 小时前 | 显示全部楼层
燕秀工具箱--圆数量统计--yx_ctu很好用而且准确

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 10 小时前 | 显示全部楼层
本帖最后由 llsheng_73 于 2024-11-18 11:15 编辑

因为半径是实数的,实数就存在精度问题,看似相等的几个实数完全可能不相等,所以建议在判断半径大小的地方通过equal带上你的容忍的精度进行判断,那样才能避免出现你图上那样的结果


(foreach c g
      (if (> (cadr c) (cadr max-circle))
        (setq max-circle c)))


改为 (foreach c g
     (or(equal (cadr c)  (cadr max-circle) fuzz)
            (setq max-circle c)))
应该就可以了,如果还不行,需要根据实际情况修改 (setq fuzz 0.01)的数值

回复

使用道具 举报

 楼主| 发表于 7 小时前 | 显示全部楼层
llsheng_73 发表于 2024-11-18 11:00
因为半径是实数的,实数就存在精度问题,看似相等的几个实数完全可能不相等,所以建议在判断半径大小的地方 ...

谢谢大佬,我修改了试了下,还是和之前一样会算错, (setq fuzz 0.01)的数值 好像是那个同心圆的模糊距离,我改了以后 有多少偏差以外就还是算同心圆,还有其他办法吗
回复

使用道具 举报

 楼主| 发表于 7 小时前 | 显示全部楼层
GEGEYANG88 发表于 2024-11-18 10:45
燕秀工具箱--圆数量统计--yx_ctu很好用而且准确

我是想在相同的孔边上写上字母,然后又能输出统计
回复

使用道具 举报

发表于 4 小时前 来自手机 | 显示全部楼层
帮顶,希望高手帮忙解决
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层
  1. (defun c:K()
  2.   (princ "\n选择要进行统计的圆对象")
  3.   (setq ss (ssget (list (cons 0 "CIRCLE"))))
  4.   
  5.   ;; 获取用户输入的文字高度
  6.   (setq text-height (getreal "\n请输入文字高度(默认3.0)
  7. : "))
  8.   (if (not text-height)
  9.     (setq text-height 3.0)  ;; 如果未输入,使用默认值3.0
  10.   )
  11.   
  12.   ;; 选择输出基点
  13.   (setq pt (getpoint "\n选择输出基点:"))
  14.   
  15.   (setq si 0 tx 65 px (car pt) py (cadr pt) li '() lii 0)
  16.   (setq os (getvar "osmode") om (getvar "cmdecho"))
  17.   
  18.   (command "cmdecho" 0 "osmode" 0)
  19.   
  20.   ;; 设置文字高度
  21.   (setq circle-text-height text-height)  ;; 圆右上角字母高度
  22.   (setq stats-text-height text-height)   ;; 统计文字高度
  23.   
  24.   ;; 设置模糊距离
  25.   (setq fuzz 0.01) ;; 同心圆判断的模糊距离

  26.   ;; 启动事务,以便一起撤销
  27.   (command "UNDO" "Begin")

  28.   ;; 筛选出最大圆
  29.   (setq filtered-circles (filter-largest-circles ss fuzz))

  30.   ;; 按圆半径对选择集进行排序
  31.   (setq filtered-circles (BF-pickset-sortwithdxf filtered-circles 40 nil 0.1 nil))

  32.   ;; 遍历筛选后的圆集合,生成字母
  33.   (repeat (sslength filtered-circles)
  34.     (setq cs (ssname filtered-circles si) ce (entget cs))
  35.     (setq cp (cdr (assoc 10 ce))) ;; 获取圆心
  36.     ;(setq cr (cdr (assoc 40 ce))) ;; 获取半径
  37.     (setq cr (atof (rtos (* 1 (cdr (assoc 40 ce))) 2 2))) ;; 获取半径
  38.     (if (setq lst (assoc cr li))
  39.       (setq ct (nth 1 lst) li (subst (list cr ct (1+ (nth 2 lst))) lst li))
  40.       (setq ct tx tx (1+ tx) li (cons (list cr ct 1) li))
  41.     )

  42.     ;; 圆右上角计算
  43.     (setq cp1 (polar cp (/ pi 4) (* cr 1.2))) ;; 在圆外右上角,距离调整为1.2倍半径
  44.     (setq cp1 (trans cp1 0 1)) ;; 转换坐标

  45.     ;; 在右上角生成字母
  46.     (command "_.text" cp1 circle-text-height 0 (chr ct))
  47.     (command "_.chprop" "l" "" "p" "c" 5 "")
  48.     (setq si (1+ si))
  49.   )

  50. ;; 输出统计文字
  51.   (foreach l li
  52.     (setq cp (list px (+ py (* lii (* stats-text-height 1.5))))) ;; 间距为统计文字高度的1.5倍
  53.     (setq cr (nth 0 l) ct (nth 1 l) cn (nth 2 l))
  54.     ;; 拼接文字格式为 "A-1 %%c5.5"
  55.     (command "_.text" cp stats-text-height 0 (strcat (chr ct) "-" (itoa cn) "  %%c" (rtos (* cr 2) 2 1)))
  56.     (command "_.chprop" "l" "" "p" "c" 255 "")
  57.     (setq lii (1+ lii))
  58.   )


  59.   ;; 结束事务
  60.   (command "UNDO" "End")

  61.   ;; 恢复设置
  62.   (setvar "osmode" 4159)
  63.   (princ "\n统计完成!")
  64.   (princ)
  65. )

  66. ;; 筛选同心圆,只保留半径最大的圆
  67. (defun filter-largest-circles (ss fuzz / circles grouped result)
  68.   (setq circles '()
  69.         grouped '()
  70.         result (ssadd))
  71.   ;; 提取圆心和半径
  72.   (repeat (sslength ss)
  73.     (setq ent (entget (ssname ss 0)))
  74.     (setq center (cdr (assoc 10 ent)))
  75.     ;(setq radius (cdr (assoc 40 ent)))
  76.     (setq radius (atof (rtos (* 1 (cdr (assoc 40 ent))) 2 2)))
  77.     (setq circles (cons (list center radius (cdr (assoc 5 ent))) circles))
  78.     (setq ss (ssdel (ssname ss 0) ss))
  79.   )
  80.   ;; 分组同心圆
  81.   (foreach c1 circles
  82.     (setq found nil)
  83.     (foreach g grouped
  84.       (if (and (not found)
  85.                (< (distance (car c1) (car (car g))) fuzz)) ;; 判断是否同心
  86.         (progn (setq g (cons c1 g)) (setq found t))
  87.       )
  88.     )
  89.     (if (not found) (setq grouped (cons (list c1) grouped)))
  90.   )
  91.   ;; 选出每组中半径最大的圆
  92.   (foreach g grouped
  93.     (setq max-circle (car g))
  94.     (foreach c g
  95.       (if (> (cadr c) (cadr max-circle))
  96.         (setq max-circle c)))
  97.     ;; 添加最大圆到结果集
  98.     (setq result (ssadd (handent (caddr max-circle)) result))
  99.   )
  100.   result
  101. )

  102. (defun BF-pickset-sortwithdxf (SE i INT FUZZ K / ENT INDEX LST NEWLST NEWSE TMP)
  103.   (setq LST '() INDEX 0)
  104.   (repeat (sslength SE)
  105.     (setq ENT (entget (ssname SE INDEX))
  106.           TMP (cdr (assoc i ENT)))
  107.     (if (and INT
  108.              (= (type INT) 'INT)
  109.              (= (type TMP) 'list)
  110.              (< INT (length TMP)))
  111.       (setq TMP (nth INT TMP)))
  112.     (setq LST (cons (list TMP (cdr (assoc 5 ENT))) LST))
  113.     (setq INDEX (1+ INDEX))
  114.   )
  115.   (if (and FUZZ
  116.            (or (= (type FUZZ) 'INT)
  117.                (= (type FUZZ) 'REAL))
  118.            (or (= (type TMP) 'INT)
  119.                (= (type TMP) 'REAL)))
  120.     (setq NEWLST
  121.           (vl-sort LST
  122.                    (function (lambda (E1 E2)
  123.                                (< (+ (car E1) FUZZ) (car  E2))))))
  124.     (setq NEWLST
  125.           (vl-sort LST
  126.                    (function (lambda (E1 E2)
  127.                                (< (car E1) (car E2))))))
  128.   )
  129.   (if K
  130.     (setq NEWLST (reverse NEWLST)))
  131.   (setq NEWSE (ssadd))
  132.   (foreach TMP NEWLST
  133.     (setq NEWSE (ssadd (handent (cadr TMP)) NEWSE)))
  134.   NEWSE
  135. )

  136. (prompt "\n 本程序可用圆孔统计;启动命令【K】")
  137. (prin1)
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层
好厉害啊!
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-18 21:30 , Processed in 0.188522 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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