明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
123
返回列表 发新帖
楼主: mandala

[基础] 请教:如何重新指定一条封闭多段线的起点?(已解决,感谢andyhon)

  [复制链接]
 楼主| 发表于 2011-3-15 15:27:27 | 显示全部楼层
嗯,看来我只好硬改组码了,结果如下:

  1. ;;子程序,修改不闭合的pline使其闭合,并按指定点作为起点重绘pline,
  2. ;;返回pline的组码。
  3. (defun plchangestart (ee p1 / pt dat ptfrst ename aa data datb dat0 dat1 dat9)

  4. (setq pt (list (car p1) (cadr p1)))
  5. (setq dat (entget ee))     
  6. (setq   ptfrst (cons 10 pt))
  7. (setq ename (vlax-ename->vla-object ee))
  8. (if (vlax-curve-isClosed ename)
  9. (setq dat dat)
  10. (progn
  11. (setq dat (subst (cons 70 129) (assoc 70 dat) dat))
  12. (setq data (List (Last dat)))
  13. (setq datb (reverse(cdr(cdr(cdr(cdr(cdr(reverse dat))))))))
  14. (setq dat(entmod (append datb data)))
  15. )
  16. )
  17. ;;以上一段:如果pl最终不是以“c”闭合而是以捕捉端点方式“闭合”,
  18. ;;则修改组码使其达到闭合效果。
  19. (setq
  20.      dat0 (reverse (member '(39 . 0.0) (reverse dat)))
  21.      dat1 (cdr (member '(39 . 0.0)  dat))
  22.      dat9 (List (Last dat1))
  23.      dat1 (reverse (cdr (reverse dat1)))
  24.      data (member ptfrst dat1)
  25.      datb (reverse (cdr (member ptfrst (reverse dat1))))
  26. )
  27. (entmod (append dat0 data datb dat9))

  28. ;;以上一段:修改组码,使pline从指定点开始。

  29. )

 楼主| 发表于 2011-3-15 15:45:06 | 显示全部楼层
本帖最后由 mandala 于 2011-3-15 15:47 编辑

最后贴上制作宗地图的源码。
修改lsp中几个指定层名的语句后,即可正常使用。

  1. ;;制作宗地图。
  2. ;;指定一条闭合的pline,指定起点,程序会自动顺向标注界址点号、界址尺寸,加粗界址线、圈上界址点并算出宗地面积。
  3. ;;程序中用到了本单位系统专用的几个层名,随机用户要使用的话,必须修改相应语句。

  4. (defun c:make( / *error* os zin lay ltp pl startpoint mj j plst ll plename p plast pnext pt1 pt2 pt3 p4 n ss1 jzx jzxename jzxout jzxoutename d l dist m angle1 angle2 start end )
  5. (defun *error* (msg)
  6.     (prompt "\n没搞定")
  7.     (print msg )
  8.     (SETVAR "DIMZIN" ZIN)
  9.     (SETVAR "OSMODE" OS)
  10.     (setvar "clayer" lay)
  11.     (setvar "celtype" ltp)
  12.     (COMMAND ".UNDO" "E")
  13.   ) ;_ 结束defun
  14. (SETVAR "CMDECHO" 0)
  15.   (COMMAND ".UNDO" "BE")
  16.   (SETQ OS  (GETVAR "OSMODE")
  17. ZIN (GETVAR "DIMZIN")
  18.   ) ;_ 结束SETQ
  19.   (setq lay (getvar "clayer"))
  20.   (setq ltp (getvar "celtype"))
  21.     (SETVAR "DIMZIN" 0)
  22.   (setvar "celtype" "continuous")
  23.   (PRINC "\n请选择已封闭的界址线: ")
  24.    (setq pl (car (entsel)))
  25. (while (= pl nil)
  26. (PRINC "\n没点中……拜托请选择已封闭的界址线: ")
  27. (setq pl (car (entsel)))
  28. )
  29.     (command "area" "o" pl)
  30.     (setq mj (getvar "area"))
  31. (if (= (fangxiang pl) 0) (reverseLwp pl))
  32. (setq startpoint (getpoint "\n请指定界址线的起点:"))
  33. (while (= (equal startpoint (vlax-curve-getClosestPointTo (vlax-ename->vla-object pl) startpoint) 0.001) nil)
  34. (setq startpoint (getpoint "\n你指定的点不在线上,请指定界址线的起点:"))
  35. )
  36. (SETVAR "OSMODE" 0)
  37. (SETQ ent (plchangestart pl startpoint))
  38.     (setq J    0
  39.    PLST (LIST)
  40.     ) ;_ 结束setq
  41.     (REPEAT (LENGTH ENT)
  42.       (IF (= (CAR (NTH J ENT)) 10)
  43.         (SETQ PLST (APPEND PLST (LIST (CDR (NTH J ENT)))))
  44.       ) ;_ 结束IF
  45.       (SETQ J (1+ J))
  46.     ) ;_ 结束REPEAT
  47.     (SETQ J  0
  48.    LL (LENGTH PLST)
  49.     ) ;_ 结束SETQ
  50.     (setq plename (vlax-ename->vla-object pl))
  51.    
  52.     (REPEAT LL
  53.       (SETQ P (NTH J PLST))
  54.       (if (= j 0)
  55.         (setq plast (NTH (- ll 1) PLST))
  56.         (setq plast (NTH (- J 1) PLST))
  57.       ) ;_ 结束if
  58.       (if (= j (- ll 1))
  59.         (setq pnext (NTH 0 PLST))
  60.         (setq pnext (NTH (1+ J) PLST))
  61.       ) ;_ 结束if
  62.       (setq pt1 (polar p (angle p plast) 1))
  63.       (setq pt2 (polar p (angle p pnext) 1))
  64.       (setq
  65.         pt3 (polar pt1 (angle pt1 pt2) (* 0.5 (distance PT1 PT2)))
  66.    ;;以这种方式来求得角平分线,得到点位用以标注点号
  67.       ) ;_ 结束setq
  68.       (setq P4 (POLAR P (ANGLE Pt3 p) 3))
  69.       (setvar "clayer" "jzd")
  70.       (command "circle" p "0.4")
  71.       (setvar "clayer" "jzdh")
  72.       (setq n (rtos (1+ j) 2 0))
  73.       (command "text" "s" "等线体" "j" "c" p4 "2" "0" n)
  74.       (setq J (1+ J))
  75.     );_ 结束REPEAT
  76.     (command "_.explode" pl)
  77.     (setq ss1 (SSGET "P")
  78.    n   0
  79.     ) ;_ 结束setq
  80.     (REPEAT ll
  81.       (setq jzx (ssname ss1 n))
  82.       (setq jzxename (vlax-ename->vla-object jzx))
  83.       (vla-offset jzxename 0.1)
  84.       (setq jzxout (entlast))
  85.       (command "chprop" jzxout "" "la" "jzxout" "")
  86.       (setq jzxout (entlast))
  87.       (setq jzxoutename (vlax-ename->vla-object jzxout))
  88.       (vla-offset jzxoutename -0.1)
  89.       (entdel jzxout)
  90.       (setq jzxout (entlast))
  91.       (if (= (cdr (assoc 0 (entget jzxout))) "ARC")
  92.         (setq d -2.5)
  93.         (setq d 2.5)
  94.       ) ;_ 结束if,该段为下面标注距离时的注记位置做准备。绝大多数圆弧需要的d是负的。
  95.       (command "pedit" jzxout "y" "w" "0.3" "")
  96.       (setq jzxout (entlast))
  97.       ;;以上偏移了每段jzx,变成jzxout后偏移回原位,变粗,得到对应的图元jzxout。
  98.       (setq jzxoutename (vlax-ename->vla-object jzxout))
  99.       (setq l (vlax-curve-getDistAtPoint
  100.          jzxoutename
  101.          (vlax-curve-getEndPoint jzxoutename)
  102.        ) ;_ 结束vlax-curve-getDistAtPoint
  103.       ) ;_ 结束setq
  104.       ;;l为线长
  105.       (setq dist (rtos (/ l 2) 2 2))
  106.       (setq m (vlax-curve-getPointAtDist jzxoutename (/ l 2)))
  107.       ;;m为中点
  108.       (setq angle1 (angle (vlax-curve-getstartPoint jzxoutename)
  109.      (vlax-curve-getendPoint jzxoutename)
  110.      ) ;_ 结束angle
  111.       ) ;_ 结束setq
  112.       ;;angle1为距离注记的位置
  113.       (setq angle2 (/ (* angle1 180) pi))
  114.       ;;angle2为注记旋转的角度,在某些情况下注记的旋转角度需要反转
  115.       (if (and (> angle2 90) (< angle2 270))
  116.         (setq angle2 (+ angle2 180))
  117.       ) ;_ 结束if
  118.       ;;以下的if分别考虑线长小于0.8和大于0.8两种情况下,jzxout的处理。
  119.       ;;为了留出界址点位置,jzxout小于0.8,删除;大于0.8,截短。
  120.       (if (<= l 0.8)
  121.         (entdel jzxout)
  122.         (progn (setq start (vlax-curve-getStartPoint jzxoutename))
  123.         (setq end (vlax-curve-getendPoint jzxoutename))
  124.         (command "lengthen"
  125.           "de"
  126.           "-0.4"
  127.           (list jzxout start)
  128.           (list jzxout end)
  129.           ""
  130.         ) ;_ 结束command
  131.         ) ;_ 结束progn
  132.       );_ 结束if
  133.       (setvar "clayer" "jzxl")
  134.       (command "text"
  135.         "s"
  136.         "等线体"
  137.         "j"
  138.         "m"
  139.         (polar m (+ angle1 (/ pi 2)) d)
  140.         "2"
  141.         angle2
  142.         dist
  143.       ) ;_ 结束command
  144.       ;;标注距离
  145.       (setq n (1+ n))
  146.     ) ;_ 结束REPEAT
  147.   (SETVAR "OSMODE" OS)
  148.   (setvar "clayer" lay)
  149.   (setvar "celtype" ltp)
  150.   (SETVAR "DIMZIN" ZIN)
  151.   (COMMAND ".UNDO" "E")
  152.   (prompt "\n搞定!")
  153.   (prompt "\n该区域面积 = ")
  154.   (princ (rtos mj 2 4))
  155.   (prompt "  ")
  156.   (prompt "如果当前比例尺为1:500,那么实际面积= ")
  157.   (princ (rtos (/ mj 2) 2 4))
  158.   (PRINC)
  159. );_ 结束DEFUN

  160. ;;;;;;;;;;;;;;;;
  161. ;;子程序,判断pline方向,返回1为顺时针,0为逆时针
  162. (defun fangxiang (xx / fd ang offsetObj plineObj x fx)
  163.   (setq plineObj (vlax-ename->vla-object xx))
  164.   (setq fd (vlax-curve-getFirstDeriv plineObj 0.5))
  165.   (setq ang (atan (/ (cadr fd) (car fd))))
  166.   (setq offsetplineObj
  167.   (car
  168.     (vlax-safearray->list
  169.       (vlax-variant-value (vla-offset plineObj 0.0001)) ;_ 结束vlax-variant-value
  170.     ) ;_ 结束vlax-safearray->list
  171.   ) ;_ 结束car
  172.   ) ;_ 结束setq
  173.   (if (> (vla-get-length plineobj)
  174.   (vla-get-length offsetplineobj)
  175.       ) ;_ 结束>
  176.     (setq x 1)
  177.     (setq x 0)
  178.   ) ;_ 结束if
  179.   (vla-delete offsetplineObj)
  180.   (setq fx x)
  181. ) ;_ 结束defun
  182. ;;;子程序:pline顶点逆序
  183. (defun reverseLwp (ent1 / a pl how li1 li2 li3)
  184.   (setq pl  (entget ent1 '("*"))
  185. how nil
  186.   ) ;_ 结束setq
  187.   (foreach an pl
  188.     (if (setq a (member (car an) '(10 40 41 42)))
  189.       (setq how t)
  190.     ) ;_ 结束if
  191.     (cond ((not how) (setq li1 (cons an li1)))
  192.    ((and how a)
  193.     (cond ((= (car an) 40) (setq an (cons 41 (cdr an))))
  194.    ((= (car an) 41) (setq an (cons 40 (cdr an))))
  195.    ((= (car an) 42) (setq an (cons 42 (- 0 (cdr an)))))
  196.    (t an)
  197.     ) ;_ 结束cond
  198.     (setq li2 (cons an li2))
  199.    )
  200.    ((and how (not a)) (setq li3 (cons an li3)))
  201.     ) ;_ 结束cond
  202.   ) ;_ 结束foreach
  203.   (entmod
  204.     (append (reverse li1)
  205.      (append (cdddr li2) (list (car li2) (cadr li2) (caddr li2)))
  206.      (reverse li3)
  207.     ) ;_ 结束append
  208.   ) ;_ 结束entmod
  209. ) ;_ 结束defun
  210. ;;子程序,修改不闭合的pline使其闭合,并按指定点作为起点重绘pline,
  211. ;;返回pline的组码。
  212. (defun plchangestart (ee p1 / pt dat ptfrst ename aa data datb dat0 dat1 dat9)
  213. (setq pt (list (car p1) (cadr p1)))
  214. (setq dat (entget ee))     
  215. (setq   ptfrst (cons 10 pt))
  216. (setq ename (vlax-ename->vla-object ee))
  217. (if (vlax-curve-isClosed ename)
  218. (setq dat dat)
  219. (progn
  220. (setq dat (subst (cons 70 129) (assoc 70 dat) dat))
  221. (setq data (List (Last dat)))
  222. (setq datb (reverse(cdr(cdr(cdr(cdr(cdr(reverse dat))))))))
  223. (setq dat(entmod (append datb data)))
  224. )
  225. )
  226. ;;以上一段:如果pl最终不是以“c”闭合而是以捕捉端点方式“闭合”,
  227. ;;则修改组码使其达到闭合效果。
  228. (setq
  229.      dat0 (reverse (member '(39 . 0.0) (reverse dat)))
  230.      dat1 (cdr (member '(39 . 0.0)  dat))
  231.      dat9 (List (Last dat1))
  232.      dat1 (reverse (cdr (reverse dat1)))
  233.      data (member ptfrst dat1)
  234.      datb (reverse (cdr (member ptfrst (reverse dat1))))
  235. )
  236. (entmod (append dat0 data datb dat9))
  237. ;;以上一段:修改组码,使pline从指定点开始。
  238. )


本帖子中包含更多资源

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

x
发表于 2011-3-15 15:56:00 | 显示全部楼层
命令: MAKE
请选择已封闭的界址线:
选择对象:
请指定界址线的起点:
没搞定
"AutoCAD 变量设置被拒绝: \"clayer\" \"jzd\""
发表于 2011-3-15 16:30:43 | 显示全部楼层
下载后测试许久,总算有个结果了。
发表于 2011-3-15 17:09:12 | 显示全部楼层
楼上出错的应仔细阅读程序说明。程序完成了,也学到了东西,同谢ANDYHON!
 楼主| 发表于 2011-3-15 17:57:36 | 显示全部楼层
本帖最后由 mandala 于 2011-3-15 17:59 编辑

嗯,andyhon的那段lsp是最关键的,给了我一个可行的思路。

最终的宗地图程序其实还有不少可以改进的地方,比如设定entsel的结果只能是多段线等等。有空的时候再改进一下吧。
 楼主| 发表于 2011-3-15 17:58:08 | 显示全部楼层
zhongguola 发表于 2011-3-15 15:56
命令: MAKE
请选择已封闭的界址线:
选择对象:

买家电也得看说明书啊?何况是程序……
发表于 2011-12-9 09:53:00 | 显示全部楼层
高手们  。我想知道如何标注多段线的点号
发表于 2011-12-11 20:30:39 | 显示全部楼层
mandala 发表于 2011-3-15 15:27
嗯,看来我只好硬改组码了,结果如下:

问下 这个怎么连接起来呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-9 13:42 , Processed in 0.173839 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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