明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4461|回复: 16

[原创]圆弧转多段线

[复制链接]
发表于 2008-3-11 10:23:00 | 显示全部楼层 |阅读模式

;圆弧转多段线
;h为弓高(即弦中心至相对应弧之中心的距离)
;它用来描述以弦代弧的光滑程度,一般化取0.005mm(图上距离)即可
(defun arc->pline(ent h / xtblm xtblz db r po a0 h n)
(setq xtblm '("cmdecho" "osmode")
xtblz (mapcar 'getvar xtblm)
db (entget ent) r (cdr (assoc 40 db))
po (cdr (assoc 10 db))
a0 (cdr (assoc 50 db))
db (- (cdr (assoc 51 db)) a0)
db (cond ((< db 0) (+ (* 2.0 pi) db))
(t db)
)
n (fix (/ db (atan (/ (sqrt (- (* 2.0 r h) (* h h))) (- r h)))))
db (/ db n)
)
(mapcar 'setvar xtblm '(0 0))
(command "_pline" (polar po a0 r))
(repeat n (command (polar po (setq a0 (+ a0 db)) r)))
(command "" "_matchprop" ent (entlast) "" "_erase" ent "" "redraw")
(mapcar 'setvar xtblm xtblz)(princ)
)

;测试程序
(defun cc()
(setq t0 (getvar "cdate"))
(arc->pline (car (entsel "\n请选取要转化多段线的圆弧:")) 0.005)
(princ (strcat "\n耗时:" (rtos (* 1000000 (- (getvar "cdate") t0) 2 3)) "秒"))
(princ)
)

发表于 2025-3-9 12:09:12 | 显示全部楼层
可以试下这个程序,可以多选!
  1. ;;;-----------------------------------------------------
  2. ;;; 功能:批量将圆弧转换为多段线(支持逆向圆弧)
  3. ;;;-----------------------------------------------------

  4. (defun c:ARC2PL ( / *error* acadObj doc ss i ename oldVars h)
  5.   ;; 错误处理函数
  6.   (defun *error* (msg)
  7.     (if doc (vla-endundomark doc))
  8.     (if oldVars (mapcar 'setvar '("CMDECHO" "OSMODE") oldVars))
  9.     (princ (strcat "\n错误: " msg))
  10.   )
  11.   
  12.   (setq acadObj (vlax-get-acad-object)
  13.         doc (vla-get-activedocument acadObj)
  14.         oldVars (list (getvar "CMDECHO") (getvar "OSMODE"))) ; 修正变量存储方式
  15.   
  16.   (setvar "CMDECHO" 0)
  17.   (setvar "OSMODE" 0)
  18.   
  19.   ;; 用户输入弓高(默认0.005)
  20.   (initget 6)
  21.   (setq h (getreal "\n输入弓高精度<0.005>: "))
  22.   (if (not h) (setq h 0.005))
  23.   
  24.   (if (setq ss (ssget '((0 . "ARC"))))
  25.     (progn
  26.       (vla-startundomark doc)
  27.       (setq i 0)
  28.       (repeat (sslength ss)
  29.         (setq ename (ssname ss i))
  30.         (arc->polyline ename h)
  31.         (setq i (1+ i))
  32.       )
  33.       (vla-endundomark doc)
  34.       (princ (strcat "\n成功转换 " (itoa i) " 个圆弧"))
  35.     )
  36.     (princ "\n未选择任何圆弧")
  37.   )
  38.   (mapcar 'setvar '("CMDECHO" "OSMODE") oldVars)
  39.   (princ)
  40. )

  41. ;;;-----------------------------------------------------
  42. ;;; 核心转换函数
  43. ;;; 参数:ename - 圆弧图元名
  44. ;;;       h     - 最大允许弓高
  45. ;;;-----------------------------------------------------
  46. (defun arc->polyline (ename h / elst r pts)
  47.   ;; 获取圆弧关键参数
  48.   (setq elst (entget ename)
  49.         r (cdr (assoc 40 elst)))
  50.   
  51.   ;; 计算顶点列表
  52.   (setq pts (arc-divide ename h r)) ; 增加半径参数传递
  53.   
  54.   ;; 构建多段线数据
  55.   (entmakex
  56.     (append
  57.       (list
  58.         '(0 . "LWPOLYLINE")
  59.         '(100 . "AcDbEntity")
  60.         (assoc 8 elst)   ; 保留图层
  61.         (if (assoc 62 elst) (assoc 62 elst) '(62 . 256)) ; 处理未设置颜色
  62.         (if (assoc 6 elst) (assoc 6 elst) '(6 . "BYLAYER")) ; 处理未设置线型
  63.         '(100 . "AcDbPolyline")
  64.         (cons 90 (length pts))
  65.         '(70 . 0)
  66.         (if (assoc 38 elst) (assoc 38 elst) '(38 . 0.0)) ; 处理标高
  67.         (if (assoc 210 elst) (assoc 210 elst) '(210 (0.0 0.0 1.0))) ; 默认法向量
  68.       )
  69.       (mapcar '(lambda (p) (cons 10 p)) pts) ; 简化坐标处理
  70.     )
  71.   )
  72.   (entdel ename) ; 删除原始圆弧
  73.   (princ)
  74. )

  75. ;;;-----------------------------------------------------
  76. ;;; 圆弧分割算法(修正版)
  77. ;;; 返回顶点坐标列表(包含起点和终点)
  78. ;;;-----------------------------------------------------
  79. (defun arc-divide (ename h r / startParam endParam totalAngle segAngle n pts param)
  80.   (setq startParam (vlax-curve-getStartParam ename)
  81.         endParam (vlax-curve-getEndParam ename)
  82.         totalAngle (abs (- endParam startParam)))
  83.   
  84.   ;; 计算分段数(基于弓高公式)
  85.   (if (> r h)
  86.     (progn
  87.       (setq segAngle (* 2 (acos (/ (- r h) r)))
  88.       (setq n (max (fix (/ totalAngle segAngle)) 1))
  89.       (setq segAngle (/ totalAngle n))
  90.     )
  91.     (setq n 1) ; 处理半径过小的情况
  92.   )
  93.   
  94.   ;; 生成顶点参数表
  95.   (setq pts (list (vlax-curve-getStartPoint ename)))
  96.   (repeat (1- n)
  97.     (setq param (+ startParam (* segAngle (length pts))))
  98.     (setq pts (cons (vlax-curve-getPointAtParam ename param) pts))
  99.   )
  100.   (reverse (cons (vlax-curve-getEndPoint ename) pts))
  101. )

  102. ;;;-----------------------------------------------------
  103. ;;; 辅助函数:反余弦计算(修正括号匹配)
  104. ;;;-----------------------------------------------------
  105. (defun acos (x)
  106.   (cond
  107.     ((>= x 1.0) 0.0)
  108.     ((<= x -1.0) pi)
  109.     (t (atan (sqrt (- 1.0 (* x x))) x)
  110.   )
  111. )

  112. (princ "\n圆弧转多段线命令已加载,请输入 ARC2PL 执行")
  113. (princ)

点评

括号都不匹配  发表于 2025-3-9 12:19
回复 支持 反对

使用道具 举报

发表于 2021-6-25 10:36:45 | 显示全部楼层
去掉了command命令,重新写了一遍,速度快多了
  1. ;圆弧转多段线
  2. ;h为弓高(即弦中心至相对应弧之中心的距离)
  3. ;它用来描述以弦代弧的光滑程度,一般化取0.005mm(图上距离)即可
  4. (defun arc->pline (en h / xtblm xtblz ALEN ENT LEN LST N PT PTLST R SUM)
  5.   (setq #t0# (getvar "cdate"))
  6.   (setq        xtblm '("cmdecho" "osmode")
  7.         xtblz (mapcar 'getvar xtblm)
  8.         r     (yj-dxf 40 en)
  9.         len   (vlax-curve-getDistAtPoint en (vlax-curve-getEndPoint en))
  10.         alen  (* (atan (/ (sqrt (- (* 2.0 r h) (* h h))) (- r h))) r)
  11.         n     (fix (/ len alen))
  12.         alen  (/ len n)
  13.         sum   alen
  14.         ptlst '()
  15.   )
  16.   (repeat n
  17.     (setq pt (vlax-curve-getpointatdist en sum))
  18.     (setq ptlst (append ptlst (list (cons 10 pt)(cons 40 0)(cons 41 0)(cons 42 0)) ))
  19.     (setq sum (+ sum alen))
  20.     )
  21.   (setq ent (entget en))
  22.   (setq lst '((0 . "LWPOLYLINE")))
  23.      (foreach x '(100 67 410 8 62 6 370)
  24.        (if (assoc x
  25.                   ent
  26.            ) ;_  assoc
  27.          (setq lst (cons (assoc x ent) lst))
  28.        ) ;_  if
  29.      ) ;_  foreach
  30.      (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
  31.      (entmakex
  32.        (append
  33.          (reverse lst)
  34.          (list
  35.            '(100 . "AcDbPolyline")
  36.            (cons 90 (1+ n))
  37.            '(70 . 0)
  38.            (cons 38 (cadddr (assoc 10 ent)))
  39.            (cons
  40.              10
  41.              (vlax-curve-getStartPoint en
  42.              ) ;_  reverse
  43.            ) ;_  cons
  44.            '(40 . 0)
  45.            '(41 . 0)
  46.            '(42 . 0)
  47.          )
  48.          ptlst
  49.          (list
  50.            (assoc 210 ent)
  51.          ) ;_  list
  52.        ) ;_  append
  53.      ) ;_  entmakex
  54.      ;(Vlax-Put-Property (Vlax-Ename->Vla-Object (entlast)) 'Color 1)
  55.      (entdel en)
  56.      (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
  57.   (mapcar 'setvar xtblm xtblz)
  58.   (princ)
  59. )
  60. ;;;按指组码找出全图元的组码值
  61.     (defun yj-dxf (key ename) (cdr (assoc key (entget ename))))   
  62. ;测试程序
  63. (defun cc ()
  64.   (arc->pline (car (entsel "\n请选取要转化多段线的圆弧:"))
  65.               0.05
  66.   )
  67.   (princ
  68.     (strcat "\n耗时:"
  69.             (rtos (* 1000000 (- (getvar "cdate") #t0#) 2 3))
  70.             "秒"
  71.     )
  72.   )
  73.   (princ)
  74. )
发表于 2025-3-9 12:25:16 | 显示全部楼层


  1. (defun c:tt ()
  2.   "圆弧转多段线"
  3.   (princ "\n选择圆弧实体<退出>: ")
  4.   (if (setq ss (ssget '((0 . "arc"))))
  5.     (progn
  6.       (setvar "PEDITACCEPT" 1)
  7.       (command "pedit" "m" ss "" "")
  8.     )
  9.   )
  10.   (princ)
  11. )

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

发表于 2008-3-11 13:47:00 | 显示全部楼层

这个程序楼主改进成为

圆弧多线段转pline会有用些吧?

发表于 2021-6-25 21:20:00 | 显示全部楼层
yjtdkj 发表于 2021-6-25 10:36
去掉了command命令,重新写了一遍,速度快多了

大师,这个程序 在cad里面是哪一个命令啊。
发表于 2021-6-26 06:33:29 | 显示全部楼层
ninja37 发表于 2021-6-25 21:20
大师,这个程序 在cad里面是哪一个命令啊。

把(defun cc ()改为(defun c:cc ()
然后在CAD里就可以用CC命令了,也可以改成你想要的
发表于 2021-6-27 12:33:19 | 显示全部楼层
yjtdkj 发表于 2021-6-26 06:33
把(defun cc ()改为(defun c:cc ()
然后在CAD里就可以用CC命令了,也可以改成你想要的

谢谢 已经在用了  很好用
发表于 2021-6-27 21:33:56 | 显示全部楼层
yjtdkj 发表于 2021-6-26 06:33
把(defun cc ()改为(defun c:cc ()
然后在CAD里就可以用CC命令了,也可以改成你想要的

大神,有没有办法批量把选中的弧线分别直接替换成直线呢?就是弧变成弦,弦的形式是直线
发表于 2021-6-28 09:28:36 | 显示全部楼层
caocaosasd 发表于 2021-6-27 21:33
大神,有没有办法批量把选中的弧线分别直接替换成直线呢?就是弧变成弦,弦的形式是直线

  1. (defun c:tt ()
  2.   (setq en (car (entsel)))
  3.   (setq pt1 (vlax-curve-getStartPoint en))
  4.   (setq pt2 (vlax-curve-getendPoint en))
  5.   (entmake
  6.     (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt2))
  7.   )
  8.   (entdel en)
  9.   (entlast)
  10. )
发表于 2021-11-26 09:21:16 | 显示全部楼层
很不错,要是能多选就更好了
发表于 2022-12-21 00:36:45 | 显示全部楼层
程序运行流畅  能修改成框选就完美了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-4-1 09:09 , Processed in 0.207880 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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