明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2121|回复: 2

[原创][LISP]以距离限差、角度限差和步进长度控制的SPLINE2PLINE

[复制链接]
发表于 2004-1-9 00:27:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2004-2-1 21:06:43 编辑
  1. ;;;==================================================================
  2. ;;;转换SPLINE至PLINE
  3. (DEFUN c:test (/ angle_dlta dist_dlta dist_step num1 ss1)
  4. ;;;       (SETQ dist_step 1                                                         ;步进距离
  5. ;;;                   dist_dlta 10                                                       ;允许偏离距离
  6. ;;;                   angle_dlta 0.1                                                   ;允许偏离角度,360
  7. ;;;       )
  8.        (SETQ dist_step   (GETREAL "步进距离:")               ;步进距离
  9.                    dist_dlta   (GETREAL "距离限差:")               ;允许偏离距离
  10.                    angle_dlta (GETREAL "角度限差:")               ;允许偏离角度,360
  11.        )
  12.        (PRINC "\n\t选择SPLINE:")
  13.        (spline2pline (SSGET '((0 . "SPLINE"))) dist_step dist_dlta angle_dlta)
  14.        (PRINC)
  15. )
  16. ;;;转换SPLINE为LWPOLYLINE的折线
  17. ;;;ENAME  实体名
  18. ;;;思路:以SPLINE线上所有连续的两个拟合点为一个单位,进行插入处理。
  19. ;;;  先以第一个拟合点作为基点,当基点前进若干个步进单位内的点的范围夹角大于偏离角度,
  20. ;;;  或者范围夹角开口处的距离大于允许偏离距离,则插入一点,
  21. ;;;  把插入点作为基点再继续,直到基点超过第二个拟合点为止。
  22. ;;;  新生成LWPOLYLINE线中将保留原来的拟合点。
  23. ;;;2/1/04 9:00 下午修改:非三阶拟合线没有拟合点时,只有起点和终点作为拟合点
  24. ;;;2/1/04 9:00 下午修改:线方向与原SPLINE方向反了
  25. ;;;ss1  实体或者选择集
  26. ;;;DIST_STEP  步进距离
  27. ;;;DIST_DLTA  允许偏离距离
  28. ;;;ANGLE_DLTA  允许偏离角度,360
  29. (DEFUN spline2pline (ss1                   dist_step
  30.                                          dist_dlta       angle_dlta
  31.                                          /                       angle_max
  32.                                          angle_min       angle_now
  33.                                          angle_tmp       curve-obj
  34.                                          data                 dist_end
  35.                                          dist_start     ename
  36.                                          num1                 points_new
  37.                                          points_old     point_base
  38.                                          point_now
  39.                                        )
  40.        (IF (NOT ss1)
  41.                (SETQ ss1 (SSADD))
  42.        )
  43.        (IF (OR (/= 'pickset (TYPE ss1))
  44.                        (AND (/= 'real (TYPE dist_step)) (/= 'int (TYPE dist_step)))
  45.                        (AND (/= 'real (TYPE dist_dlta)) (/= 'int (TYPE dist_dlta)))
  46.                        (AND (/= 'real (TYPE angle_dlta)) (/= 'int (TYPE angle_dlta)))
  47.                )
  48.                (*error* "参数类型错。")
  49.        )
  50.        (IF (> (SSLENGTH ss1) 0)
  51.                (PRINC (STRCAT "\n\t0\tSPLINE转换为LWPOLYLINE,共< " (ITOA (SSLENGTH ss1)) " >。"))
  52.        )
  53.        (SETQ angle_dlta (ABS (* (/ (REM angle_dlta 360.0) 180.0) PI))
  54.                    num1             0
  55.        )
  56.        (REPEAT (SSLENGTH ss1)
  57.                (SETQ ename           (SSNAME ss1 num1)
  58.                            num1             (1+ num1)
  59.                            data             (ENTGET ename)
  60.                            points_old (IF (ASSOC '11 data)
  61.                                                          (MAPCAR 'CDR (VL-REMOVE-IF '(LAMBDA (x) (/= 11 (CAR x))) data))
  62.                                                          (LIST (CDR (ASSOC '10 data)) (CDR (ASSOC '10 (REVERSE data))))
  63.                                                  )
  64.                            points_new (LIST (CAR points_old))
  65.                            points_old (CDR points_old)
  66.                            curve-obj   (VLAX-ENAME->VLA-OBJECT ename)
  67.                )
  68.                (PRINC (STRCAT "\r\t" (ITOA num1)))
  69.                ;;对拟合点进行循环
  70.                (WHILE points_old
  71.                        (SETQ dist_start (VLAX-CURVE-GETPARAMATPOINT curve-obj (CAR points_new))
  72.                                    dist_end     (VLAX-CURVE-GETPARAMATPOINT curve-obj (CAR points_old))
  73.                        )
  74.                        ;;步进没到结束下一个拟合点
  75.                        (WHILE (< (SETQ dist_start (+ dist_start dist_step)) dist_end)
  76.                                (SETQ point_base (CAR points_new) ;指定方向的第一点
  77.                                            angle_max   (ANGLE point_base (VLAX-CURVE-GETPOINTATPARAM curve-obj dist_start))
  78.                                            angle_min   angle_max
  79.                                )
  80.                                ;;步进没有到第一点插入点
  81.                                (WHILE (AND (< dist_start dist_end) ;没有到下一个拟合点
  82.                                                        (SETQ point_now (VLAX-CURVE-GETPOINTATPARAM curve-obj dist_start)
  83.                                                                    angle_now (ANGLE point_base point_now)
  84.                                                        )
  85.                                                        (< (SETQ angle_tmp (MAX (ABS (- angle_max angle_now)) (ABS (- angle_min angle_now)))) angle_dlta)
  86.                                                                                                    ;角度在限差内
  87.                                                        (< (* angle_tmp (DISTANCE point_base point_now)) dist_dlta) ;距离在限差内
  88.                                              )
  89.                                        (SETQ dist_start (+ dist_start dist_step))
  90.                                        (IF (> angle_now angle_max)
  91.                                                (SETQ angle_max angle_now)
  92.                                                (IF (< angle_now angle_min)
  93.                                                        (SETQ angle_min angle_now)
  94.                                                )
  95.                                        )
  96.                                )
  97.                                (IF (< (SETQ angle_tmp (MAX (ABS (- angle_max angle_now)) (ABS (- angle_min angle_now)))) angle_dlta)
  98.                                        (PRINC "\nangle>")
  99.                                )
  100.                                (IF (< (* angle_tmp (DISTANCE point_base point_now)) dist_dlta)
  101.                                        (PRINC "\ndist>")
  102.                                )
  103.                                (IF (< dist_start dist_end)
  104.                                        (SETQ points_new (CONS point_now points_new))
  105.                                )
  106.                        )
  107.                        (SETQ points_new (CONS (CAR points_old) points_new)
  108.                                    points_old (CDR points_old)
  109.                        )
  110.                )
  111.                ;;生成多义线
  112.                (COMMAND "pline")
  113.                (FOREACH x (REVERSE points_new) (COMMAND x))
  114.                (IF (= 1 (LOGAND 1 (CDR (ASSOC '70 data))))
  115.                        (COMMAND "u" "c")                                         ;闭合的
  116.                        (COMMAND "")
  117.                )
  118.                ;;删除SPLINE
  119.                (ENTDEL ename)
  120.        )
  121.        (PRINC)
  122. )
  123. ;;;==================================================================
  124. (PRINC)
复制代码
说明:对于距离限差和角度限差,并不能保证在限差范围之内的最大值,只可以保证在允许限差内。
请大家发表保贵意见。

评分

参与人数 1威望 +2 金钱 +20 贡献 +10 激情 +20 收起 理由
mccad + 2 + 20 + 10 + 20 【好评】好

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2004-1-9 08:56:00 | 显示全部楼层

  1. ;;利用OFFSET特性(对SPLINE & ELLIPSE  OFFSET后会增加控制点)
  2. ;;SPLINE & ELLIPSE TO PLINE
  3. ;;BY  龙龙仔(LUCAS)
  4. (defun C:S2P (/        HOLDOSMODE HOLDECHO SSS        SSL N N1 ENT PT_LIST NUMPT ED PT PT1)
  5.   ;;T. Tanzillo
  6.   (defun VLISP-REMOVE-IF-NOT (KEY LST)
  7.     (mapcar 'cdr
  8.             (vl-remove-if-not
  9.               '(lambda (E) (eq (car E) KEY))
  10.               LST
  11.             )
  12.     )
  13.   )

  14.   (defun MIDPOINT (PT1 PT2)
  15.     (mapcar
  16.       '(lambda (X Y)
  17.          (* 0.5 (+ X Y))
  18.        )
  19.       PT1
  20.       PT2
  21.     )
  22.   )

  23.   (setq HOLDECHO (getvar "cmdecho"))
  24.   (setvar "cmdecho" 0)
  25.   (command "_.undo" "group")
  26.   (setq HOLDOSMODE (getvar "osmode"))
  27.   (setvar "osmode" 0)
  28.   (prompt "\n选取SPLINE,ELLIPSE:")
  29.   (setq SSS (ssget '((0 . "ELLIPSE,SPLINE"))))
  30.   (setq        SSL (sslength SSS)
  31.         N   0
  32.   )
  33.   (repeat SSL
  34.     (prompt (strcat "\r余 " (itoa (- SSL N)) " 个物件     "))
  35.     (setq ENT (vlax-ename->vla-object (ssname SSS N)))
  36.     (vl-catch-all-apply
  37.       'vla-offset
  38.       (list ENT 0.001)
  39.     )
  40.     (setq ENT (entlast))
  41.     (vl-catch-all-apply
  42.       'vla-offset
  43.       (list (vlax-ename->vla-object ENT) -0.001)
  44.     )
  45.     (entdel ENT)
  46.     (setq ENT (entlast))
  47.     (setq PT_LIST (VLISP-REMOVE-IF-NOT 10 (setq ED (entget ENT))))
  48.     (setq ENT (vlax-ename->vla-object ENT))
  49.     (setq N1 0)
  50.     (vl-cmdf "_.pline" (nth N1 PT_LIST) "A")
  51.     (if        (or (and (= (cdr (assoc 0 ED)) "ELLIPSE")
  52.                  (= (cdr (assoc 42 ED)) (* pi 2))
  53.             )
  54.             (and (= (cdr (assoc 0 ED)) "SPLINE")
  55.                  (= (logand (cdr (assoc 70 ED)) 1) 1)
  56.             )
  57.         )
  58.       (setq NUMPT (- (length PT_LIST) 2))
  59.       (setq NUMPT (- (length PT_LIST) 1))
  60.     )
  61.     (repeat NUMPT
  62.       (setq PT (vlax-curve-getclosestpointto
  63.                  ENT
  64.                  (MIDPOINT (nth N1 PT_LIST)
  65.                            (setq PT1 (nth (1+ N1) PT_LIST))
  66.                  )
  67.                )
  68.       )
  69.       (vl-cmdf "S"
  70.                (vlax-curve-getclosestpointto ENT PT)
  71.                (vlax-curve-getclosestpointto ENT PT1)
  72.       )
  73.       (setq N1 (1+ N1))
  74.     )
  75.     (if        (or (and (= (cdr (assoc 0 ED)) "ELLIPSE")
  76.                  (= (cdr (assoc 42 ED)) (* pi 2))
  77.             )
  78.             (and (= (cdr (assoc 0 ED)) "SPLINE")
  79.                  (= (logand (cdr (assoc 70 ED)) 1) 1)
  80.             )
  81.         )
  82.       (vl-cmdf "CL")
  83.       (vl-cmdf "")
  84.     )
  85.     (vla-delete ENT)
  86.     (setq N (1+ N))
  87.   )
  88.   (setvar "osmode" HOLDOSMODE)
  89.   (command "_.undo" "end")
  90.   (setvar "cmdecho" HOLDECHO)
  91.   (princ)
  92. )
发表于 2004-1-11 15:50:00 | 显示全部楼层
虽然offset的距离很小。但从理论上说,是不是还有不可能正确生成单一新实体的缺陷?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-10-2 03:34 , Processed in 0.172978 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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