明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4275|回复: 15

[讨论] 一个画宗地图的lsp,有时候会出问题,请教为什么:(附图)

  [复制链接]
发表于 2011-4-9 15:39:40 | 显示全部楼层 |阅读模式
本帖最后由 mandala 于 2011-4-11 00:12 编辑

写了一个画宗地图的lsp,运行结果基本还是比较满意的。但发现在有些情况下,程序的运行会不正确,如附图中的几种情况。
在附图中的四条多段线,运行程序后分别会出现一种错误。

请各位大佬帮忙看看,原因何在,以及该如何改进呢?先谢谢了。

这是正常情况下程序make运行后的效果图:


这是正常情况下make1运行后的效果:


  1. ;;两种方式制作宗地图。
  2. ;;第一种方式make:
  3. ;;指定一条闭合的pline,指定起点,
  4. ;;程序会自动顺向标注界址点号、界址尺寸,加粗界址线、圈上界址点、输出界址点坐标(idout),并算出宗地面积。
  5. ;;程序中用到了本单位系统专用的几个层名,在上传时已屏蔽掉相关语句,用户可正常使用。
  6. (defun c:make (/       *error* os      zin     lay     ltp     pl
  7.          startpoint      mj      j       plst    ll      plename
  8.          p       plast   pnext   pt1     pt2     pt3     p4
  9.          n       ss1     jzx     jzxename         jzxout
  10.          jzxoutename     d       l       dist    m       angle1
  11.          angle2  start   end     col
  12.         )
  13.   (defun *error* (msg)
  14.     (prompt "\n没搞定")
  15.     (print msg)
  16.     (setvar "DIMZIN" zin)
  17.     (setvar "OSMODE" os)
  18.     (setvar "clayer" lay)
  19.     (setvar "celtype" ltp)
  20.     (setvar "cecolor" col)
  21.     (redraw pl 4)
  22.     (command "._UNDO" "E")
  23.     (prompt "\n可以用Undo命令返回起始状态。")
  24.   ) ;_ 结束defun
  25. ;;变量设置:
  26.   (setvar "CMDECHO" 0)
  27.   (command "._UNDO" "BE")
  28.   (setq  os  (getvar "OSMODE")
  29.   zin (getvar "DIMZIN")
  30.   ) ;_ 结束SETQ
  31.   (setq lay (getvar "clayer"))
  32.   (setq ltp (getvar "celtype"))
  33.   (setq col (getvar "cecolor"))
  34.   (setvar "DIMZIN" 0)
  35.   (setvar "celtype" "continuous")
  36.   (setvar "cecolor" "bylayer")
  37.   (princ "\n请选择已封闭的pline界址线: ")
  38.   (setq pl (car (entsel)))
  39.   (redraw pl 3)
  40.   (command "_.area" "o" pl)
  41.   (setq mj (getvar "area"))
  42.   (setq plename  (vlax-ename->vla-object pl))
  43. (while (or (= pl nil)
  44.      (/= (cdr (assoc 0 (entget pl))) "LWPOLYLINE")
  45.      (= mj 0)
  46.      (and  (= (vlax-curve-isclosed plename) nil)
  47.     (= (equal (vlax-curve-getstartpoint plename)
  48.         (vlax-curve-getendpoint plename)
  49.        ) ;_ 结束equal
  50.      nil) ;_ 结束=
  51.      ) ;_ 结束and
  52.        ) ;_ 结束or
  53. ;;所点中的东西,不可以为空、必须为pline、不可以为一直线、不可以为开口的pline。
  54.   (princ "\n你点错了……拜托请选择一条封闭的pline: ")
  55.   (redraw pl 4)
  56.   (setq pl (car (entsel)))
  57.   (redraw pl 3)
  58.   (command "_.area" "o" pl)
  59.   (setq mj (getvar "area"))
  60.   (setq plename  (vlax-ename->vla-object pl))
  61.   ) ;_ 结束while
  62.   (if (= (fangxiang pl) 0)
  63.     (reverselwp pl)
  64.   ) ;_ 结束if
  65.   (setq startpoint (getpoint "\n请指定界址线1号点的位置:"))
  66.   (while (= (equal startpoint
  67.        (vlax-curve-getclosestpointto
  68.          (vlax-ename->vla-object pl)
  69.          startpoint
  70.        ) ;_ 结束vlax-curve-getClosestPointTo
  71.        0.001
  72.       ) ;_ 结束equal
  73.       nil
  74.    ) ;_ 结束=
  75.     (setq startpoint
  76.      (getpoint "\n你指定的点不在线上……请重新指定1号点的位置:")
  77.     ) ;_ 结束setq
  78.   ) ;_ 结束while
  79.   (setvar "OSMODE" 0)
  80.   (redraw pl 4)
  81.   (setq ent (plchangestart pl startpoint))
  82.   (setq  j    0
  83.   plst (list)
  84.   ) ;_ 结束setq
  85. (repeat (length ent)
  86.     (if  (= (car (nth j ent)) 10)
  87.       (setq plst (append plst (list (cdr (nth j ent)))))
  88.     ) ;_ 结束IF
  89.     (setq j (1+ j))
  90.   ) ;_ 结束REPEAT

  91. (pointout plst)
  92. ;;将界址点坐标输出到idout.dat
  93. ;;以下开始标注点号:
  94.   (setq  j  0
  95.   ll (length plst)
  96.   ) ;_ 结束SETQ
  97.   (setq plename (vlax-ename->vla-object pl))
  98.   (repeat ll
  99.     (setq p (nth j plst))
  100.     (if  (= j 0)
  101.       (setq plast (nth (- ll 1) plst))
  102.       (setq plast (nth (- j 1) plst))
  103.     ) ;_ 结束if
  104.     (if  (= j (- ll 1))
  105.       (setq pnext (nth 0 plst))
  106.       (setq pnext (nth (1+ j) plst))
  107.     ) ;_ 结束if
  108. ;;确定上一点和下一点的位置,以求得角平分线
  109.     (setq pt1 (polar p (angle p plast) 1))
  110.     (setq pt2 (polar p (angle p pnext) 1))
  111.     (setq
  112.       pt3 (polar pt1 (angle pt1 pt2) (* 0.5 (distance pt1 pt2)))
  113.     ) ;_ 结束setq
  114. ;;以这种方式来求得角平分线,得到点位用以标注点号。
  115. ;;这样点号的位置会比较美观
  116.     (setq p4 (polar p (angle pt3 p) 2))
  117. ;    (setvar "clayer" "jzd")
  118.     (command "._circle" p "0.4")
  119. ;    (setvar "clayer" "jzdh")
  120.     (setq n (rtos (1+ j) 2 0))
  121.     (command "._text"  "j" "m" p4 "1.5" "0" n)
  122.     (setq j (1+ j))
  123.   ) ;_ 结束REPEAT
  124. ;;标注点号结束,接下来开始处理jzxout:
  125.   (command "_.explode" pl)
  126.   (setq  ss1 (ssget "P")
  127.   n   0
  128.   ) ;_ 结束setq
  129.   (repeat ll
  130.     (setq jzx (ssname ss1 n))
  131.     (setq jzxename (vlax-ename->vla-object jzx))
  132.     (vla-offset jzxename 0.1)
  133.     (setq jzxout (entlast))
  134.     (command "_.chprop" jzxout "" "la" "jzxout" "")
  135.     (setq jzxout (entlast))
  136.     (setq jzxoutename (vlax-ename->vla-object jzxout))
  137.     (vla-offset jzxoutename -0.1)
  138.     (entdel jzxout)
  139.     (setq jzxout (entlast))
  140.     (if  (= (cdr (assoc 0 (entget jzxout))) "ARC")
  141.       (setq d -2.5)
  142.       (setq d 2.5)
  143.     ) ;_ 结束if,该段为下面标注距离时的注记位置做准备。在宗地图里,绝大多数圆弧需要的d是负的。
  144.     (command "_.pedit" jzxout "y" "w" "0.3" "")
  145.     (setq jzxout (entlast))
  146.     ;;以上偏移了每段jzx,变成jzxout后偏移回原位,变粗,得到对应的图元jzxout。
  147.     (setq jzxoutename (vlax-ename->vla-object jzxout))
  148.     (setq l (vlax-curve-getdistatpoint
  149.         jzxoutename
  150.         (vlax-curve-getendpoint jzxoutename)
  151.       ) ;_ 结束vlax-curve-getDistAtPoint
  152.     ) ;_ 结束setq
  153.     ;;l为线长
  154.     (setq dist (rtos (/ l 2) 2 2))
  155.     (setq m (vlax-curve-getpointatdist jzxoutename (/ l 2)))
  156.     ;;m为中点
  157.     (setq angle1 (angle  (vlax-curve-getstartpoint jzxoutename)
  158.       (vlax-curve-getendpoint jzxoutename)
  159.      ) ;_ 结束angle
  160.     ) ;_ 结束setq
  161.     ;;angle1为距离注记的旋转弧度
  162.     (setq angle2 (/ (* angle1 180) pi))
  163.     ;;angle2为注记旋转的角度,在某些情况下注记的旋转角度需要反转
  164.     (if  (and (> angle2 90) (< angle2 270))
  165.       (setq angle2 (+ angle2 180))
  166.     ) ;_ 结束if
  167.     ;;以下的if分别考虑线长小于0.8和大于0.8两种情况下,jzxout的处理。
  168.     ;;为了留出界址点位置,jzxout小于0.8,删除;大于0.8,截短。
  169.     (if  (<= l 0.8)
  170.       (entdel jzxout)
  171.       (progn (setq start (vlax-curve-getstartpoint jzxoutename))
  172.        (setq end (vlax-curve-getendpoint jzxoutename))
  173.        (command "_.lengthen"
  174.           "de"
  175.           "-0.4"
  176.           (list jzxout start)
  177.           (list jzxout end)
  178.           ""
  179.        ) ;_ 结束command
  180.       ) ;_ 结束progn
  181.     ) ;_ 结束if
  182. ;    (setvar "clayer" "jzxl")
  183.     (command "._text"
  184.        "j"
  185.        "m"
  186.        (polar m (+ angle1 (/ pi 2)) d)
  187.        "2"
  188.        angle2
  189.        dist
  190.     ) ;_ 结束command
  191.     ;;标注距离
  192.     (setq n (1+ n))
  193.   ) ;_ 结束REPEAT
  194.   (setvar "OSMODE" os)
  195.   (setvar "clayer" lay)
  196.   (setvar "celtype" ltp)
  197.   (setvar "DIMZIN" zin)
  198.   (setvar "cecolor" col)
  199.   (command "._UNDO" "E")
  200.   (prompt "\n搞定!")
  201.   (prompt "\n该区域面积 = ")
  202.   (princ (rtos mj 2 4))
  203.   (prompt "  ")
  204.   (prompt "如果当前比例尺为1:500,那么实际面积= ")
  205.   (princ (rtos (/ mj 4) 2 4))
  206.   (princ)
  207. ) ;_ 结束DEFUN make
  208. ;;;;;;;;;;;;;;;;



  209. ;;另一种方式制作宗地图。
  210. ;;界址点不是默认全选,而是由用户来逐一指定。
  211. ;;也就是说,碰到一宗地的某段界址线形状复杂、点数较多、需要精简时,
  212. ;;可以用make1这种指定界址点的方式来跳开不需要的界址点。
  213. ;;例如,做耕地垦造的图纸时,往往会碰到一条界址线是河滩。


  214. (defun c:make1 ( /      *error*      os       zin     lay     ltp     col
  215.           pl      mj       plename srartpoint       ent
  216.           plst    pxlst   j       nextpoint       jzxout  n
  217.           psc1    ll       p       plast   pnext   pt1     pt2
  218.           pt3     pt4     px1     px2     lx       dist    m
  219.           angle1  angle2  jzxoutx
  220.          )
  221.   (defun *error* (msg)
  222.     (prompt "\n没搞定")
  223.     (print msg)
  224.     (setvar "DIMZIN" zin)
  225.     (setvar "OSMODE" os)
  226.     (setvar "clayer" lay)
  227.     (setvar "celtype" ltp)
  228.     (setvar "cecolor" col)
  229.     (redraw pl 4)
  230.     (command "._UNDO" "E")
  231.     (prompt "\n可以用Undo命令返回起始状态。")
  232.   ) ;_ 结束defun
  233.   (setvar "CMDECHO" 0)
  234.   (command "._UNDO" "BE")
  235.   (setq  os  (getvar "OSMODE")
  236.   zin (getvar "DIMZIN")
  237.   ) ;_ 结束SETQ
  238.   (setq lay (getvar "clayer"))
  239.   (setq ltp (getvar "celtype"))
  240.   (setq col (getvar "cecolor"))
  241.   (setvar "DIMZIN" 0)
  242.   (setvar "celtype" "continuous")
  243.   (setvar "cecolor" "bylayer")
  244.   (princ "\n请选择一条已封闭的pline界址线: ")
  245.   (setq pl (car (entsel)))
  246.   (redraw pl 3)
  247.   (command "_.area" "o" pl)
  248.   (setq mj (getvar "area"))
  249.   (setq plename (vlax-ename->vla-object pl))
  250.   (while (or (= pl nil)
  251.        (/= (cdr (assoc 0 (entget pl))) "LWPOLYLINE")
  252.        (= mj 0)
  253.        (and (= (vlax-curve-isclosed plename) nil)
  254.       (= (equal (vlax-curve-getstartpoint plename)
  255.           (vlax-curve-getendpoint plename)
  256.          ) ;_ 结束equal
  257.          nil
  258.       ) ;_ 结束=
  259.        ) ;_ 结束and
  260.    ) ;_ 结束or
  261.     ;;所点中的东西,不可以为空、必须为pline、不可以为一直线、不可以为开口的pline。
  262.     (princ "\n你点错了……拜托请选择一条封闭的pline: ")
  263.     (redraw pl 4)
  264.     (setq pl (car (entsel)))
  265.     (redraw pl 3)
  266.     (command "_.area" "o" pl)
  267.     (setq mj  (getvar "area"))
  268.     (setq plename (vlax-ename->vla-object pl))
  269.   ) ;_ 结束while
  270.   (setq mj (getvar "area"))
  271.   (if (= (fangxiang pl) 0)
  272.     (reverselwp pl)
  273.   ) ;_ 结束if
  274.   (setq startpoint (getpoint "\n请指定界址线1号点的位置:"))
  275.   (while (= (equal startpoint
  276.        (vlax-curve-getclosestpointto
  277.          (vlax-ename->vla-object pl)
  278.          startpoint
  279.        ) ;_ 结束vlax-curve-getClosestPointTo
  280.        0.001
  281.       ) ;_ 结束equal
  282.       nil
  283.    ) ;_ 结束=
  284.     (setq startpoint
  285.      (getpoint
  286.        "\n你指定的点不在线上……请重新指定1号点的位置:"
  287.      ) ;_ 结束getpoint
  288.     ) ;_ 结束setq
  289.   ) ;_ 结束while
  290.   (redraw pl 4)
  291.   (setq ent (plchangestart pl startpoint))
  292.   (setq  j     0
  293.   plst  (list)
  294.   pxlst (list)
  295.   pxlst (append (list startpoint))
  296.   ) ;_ 结束setq
  297.   (repeat (length ent)
  298.     (if  (= (car (nth j ent)) 10)
  299.       (setq plst (append plst (list (cdr (nth j ent)))))
  300.     ) ;_ 结束IF
  301.     (setq j (1+ j))
  302.   ) ;_ 结束REPEAT,得到所有顶点的列表plst。
  303. ;;;;;;;;;;;
  304.   (while (setq nextpoint (getpoint "\n请指定下一点的位置:"))
  305.     (while (= (equal nextpoint
  306.          (vlax-curve-getclosestpointto
  307.            (vlax-ename->vla-object pl)
  308.            nextpoint
  309.          ) ;_ 结束vlax-curve-getClosestPointTo
  310.          0.001
  311.         ) ;_ 结束equal
  312.         nil
  313.      ) ;_ 结束=
  314.       (setq
  315.   nextpoint (getpoint
  316.         "\n你指定的点不在线上……请重新指定下一点的位置:"
  317.       ) ;_ 结束getpoint
  318.       ) ;_ 结束setq
  319.     ) ;_ 结束while
  320.     (setq pxlst (append pxlst (list nextpoint)))
  321.   );结束while,定点结束,得到所有选定点的列表pxlst。
  322.   ;;开始处理jzxout:
  323.   (setvar "OSMODE" 0)
  324.   (setq plename (vlax-ename->vla-object pl))
  325.   (vla-offset plename 0.1)
  326.   (setq jzxout (entlast))
  327.   (command "_.chprop" jzxout "" "la" "jzxout" "")
  328.   (setq jzxout (entlast))
  329.   (vla-offset (vlax-ename->vla-object jzxout) -0.1)
  330.   (entdel jzxout)
  331.   (setq jzxout (entlast))
  332.   (command "_.pedit" jzxout "w" "0.3" "")
  333.   ;;将jzx平移,加粗,变为jzxout之后平移回去。
  334.   ;;然后开始圈界址点,并裁剪掉圈内的jzxout。
  335.   (setq n (- (length pxlst) 1))
  336.   (repeat (length pxlst)
  337.     (setq ps (nth n pxlst))
  338. ;    (setvar "clayer" "jzd")
  339.     (command "._circle" ps "0.4")
  340.     (setq c1 (entlast))
  341.     (command "._trim" c1 "" (list jzxout ps) "")
  342.     (setq n (- n 1))
  343.   );repeat,
  344.   ;;trim了界址点内之后,图元名jzxout变为该界址点之前的那段jzxout,所以要从最后一点trim起。
  345.   ;;开始标注点号和距离。考虑到今后可能有其它运用,所以没有和以上的repeat并到一起去。
  346.   (setq  j  0
  347.   ll (length plst)
  348.   ) ;_ 结束SETQ
  349.   (repeat (length pxlst)
  350.     (setq p (list (car (nth j pxlst)) (cadr (nth j pxlst))))
  351.     (setq n (- (length (member p (reverse plst))) 1))
  352.     ;;p为选定点,n为点p在所有顶点列表中的序号
  353.     (if  (= n 0)
  354.       (setq plast (nth (- ll 1) plst))
  355.       (setq plast (nth (- n 1) plst))
  356.     ) ;_ 结束if
  357.     (if  (= n (- ll 1))
  358.       (setq pnext (nth 0 plst))
  359.       (setq pnext (nth (1+ n) plst))
  360.     ) ;_ 结束if
  361.     ;;确定点p的上一点和下一点的位置,以求得角平分线
  362.     (setq pt1 (polar p (angle p plast) 1))
  363.     (setq pt2 (polar p (angle p pnext) 1))
  364.     (setq pt3 (polar pt1 (angle pt1 pt2) (* 0.5 (distance pt1 pt2)))) ;_ 结束setq
  365.     ;;以这种方式来求得角平分线,得到点位用以标注点号。
  366.     ;;这样点号的位置会比较美观
  367.     (setq pt4 (polar p (angle pt3 p) 2))
  368. ;    (setvar "clayer" "jzdh")
  369.     (setq nn (rtos (1+ j) 2 0))
  370.     (command "._text"  "j" "m" pt4 "1.5" "0" nn)
  371.     ;;标注点号结束
  372.     (setq px1 (nth j pxlst)
  373.     px2 (nth (1+ j) pxlst)
  374.     ) ;_ 结束setq
  375.     ;;px1为p的三维点形式,px2为p在pxlst中的下一点
  376.     (if  (= j (- (length pxlst) 1))
  377.       (setq lx (/ (- (getvar "PERIMETER") (vlax-curve-getDistAtPoint plename px1)) 2))
  378.       (setq lx (/ (- (vlax-curve-getDistAtPoint plename px2)
  379.          (vlax-curve-getDistAtPoint plename px1)
  380.       ) ;_ 结束-
  381.       2
  382.          ) ;_ 结束/
  383.       ) ;_ 结束setq
  384.     ) ;_ 结束if
  385.     ;;lx为每段的长度,即px1到px2的jzx线上距离。最后一段距离的计算方法与众不同。
  386.     (setq dist (rtos lx 2 2))
  387.     (setq m (vlax-curve-getpointatdist
  388.         plename
  389.         (+ lx (vlax-curve-getDistAtPoint plename px1))
  390.       ) ;_ 结束vlax-curve-getpointatdist
  391.     ) ;_ 结束setq
  392.     ;;m为中点
  393.     (setq angle1 (angle m
  394.         (mapcar '+
  395.           m
  396.           (vlax-curve-getFirstDeriv
  397.             plename
  398.             (vlax-curve-getparamatpoint plename m)
  399.           ) ;_ 结束vlax-curve-getFirstDeriv
  400.         ) ;_ 结束mapcar
  401.        ) ;_ 结束angle
  402.      ) ;_ 结束setq
  403.     ;;angle1为m点所在的jzx的法线角度,即注记的旋转弧度。
  404.     (setq angle2 (/ (* angle1 180) pi))
  405.     ;;angle2为注记旋转的角度,
  406.     (if  (and (> angle2 90) (< angle2 270))
  407.       (setq angle2 (+ angle2 180))
  408.     ) ;_ 结束if,在某些情况下注记的旋转角度需要反转

  409. ;    (setvar "clayer" "jzxl")
  410.     (command "._text"
  411.         "j"
  412.        "m"
  413.        (polar m (+ angle1 (/ pi 2)) 2.5)
  414.        "2"
  415.        angle2
  416.        dist
  417.     ) ;_ 结束command
  418.     ;;标注距离结束
  419.     (setq j (1+ j))
  420.   ) ;_ 结束REPEAT ,
  421.   (setvar "OSMODE" os)
  422.   (setvar "clayer" lay)
  423.   (setvar "celtype" ltp)
  424.   (setvar "DIMZIN" zin)
  425.   (setvar "cecolor" col)
  426.   (command "._UNDO" "E")
  427.   (prompt "\n搞定!")
  428.   (prompt "\n该区域面积 = ")
  429.   (princ (rtos mj 2 4))
  430.   (prompt "  ")
  431.   (prompt "如果当前比例尺为1:500,那么实际面积= ")
  432.   (princ (rtos (/ mj 4) 2 4))
  433.   (princ)
  434. ) ;_ 结束DEFUN make1
  435. ;;;;;;;;;;;;;;;;
  436. ;;程序make1在设计中使用了一些跟make不同的思路,如jzxout的处理、距离标注角度的确定等等。

  437. ;;子程序,判断pline方向,返回1为顺时针,0为逆时针
  438. (defun fangxiang (xx / fd ang offsetplineobj plineobj x fx)
  439.   (setq plineobj (vlax-ename->vla-object xx))
  440.   (setq fd (vlax-curve-getfirstderiv plineobj 0.5))
  441.   (setq ang (atan (/ (cadr fd) (car fd))))
  442.   (setq  offsetplineobj
  443.    (car
  444.      (vlax-safearray->list
  445.        (vlax-variant-value (vla-offset plineobj 0.0001)) ;_ 结束vlax-variant-value
  446.      ) ;_ 结束vlax-safearray->list
  447.    ) ;_ 结束car
  448.   ) ;_ 结束setq
  449.   (if (> (vla-get-length plineobj)
  450.    (vla-get-length offsetplineobj)
  451.       ) ;_ 结束>
  452.     (setq x 1)
  453.     (setq x 0)
  454.   ) ;_ 结束if
  455.   (vla-delete offsetplineobj)
  456.   (setq fx x)
  457. ) ;_ 结束defun

  458. ;;;子程序:pline顶点逆序
  459. (defun reverselwp (ent1 / a pl how li1 li2 li3)
  460.   (setq  pl  (entget ent1 '("*"))
  461.   how nil
  462.   ) ;_ 结束setq
  463.   (foreach an pl
  464.     (if  (setq a (member (car an) '(10 40 41 42)))
  465.       (setq how t)
  466.     ) ;_ 结束if
  467.     (cond ((not how) (setq li1 (cons an li1)))
  468.     ((and how a)
  469.      (cond ((= (car an) 40) (setq an (cons 41 (cdr an))))
  470.      ((= (car an) 41) (setq an (cons 40 (cdr an))))
  471.      ((= (car an) 42) (setq an (cons 42 (- 0 (cdr an)))))
  472.      (t an)
  473.      ) ;_ 结束cond
  474.      (setq li2 (cons an li2))
  475.     )
  476.     ((and how (not a)) (setq li3 (cons an li3)))
  477.     ) ;_ 结束cond
  478.   ) ;_ 结束foreach
  479.   (entmod
  480.     (append (reverse li1)
  481.       (append (cdddr li2) (list (car li2) (cadr li2) (caddr li2)))
  482.       (reverse li3)
  483.     ) ;_ 结束append
  484.   ) ;_ 结束entmod
  485. ) ;_ 结束defun

  486. ;;子程序,修改不闭合的pline使其闭合,并按指定点作为起点重绘pline,
  487. ;;返回pline的组码。
  488. (defun plchangestart
  489.        (ee p1 / pt dat ptfrst ename aa data datb dat0 dat1 dat9)
  490.   (setq pt (list (car p1) (cadr p1)))
  491.   (setq dat (entget ee))
  492.   (setq ptfrst (cons 10 pt))
  493.   (setq ename (vlax-ename->vla-object ee))
  494.   (if (vlax-curve-isclosed ename)
  495.     (setq dat dat)
  496.     (progn
  497.       (setq dat (subst (cons 70 129) (assoc 70 dat) dat))
  498.       (setq data (list (last dat)))
  499.       (setq datb (reverse (cdr (cdr (cdr (cdr (cdr (reverse dat))))))))
  500.       (setq dat (entmod (append datb data)))
  501.     ) ;_ 结束progn
  502.   ) ;_ 结束if
  503.   ;;以上一段:如果pl最终不是以“c”闭合而是以捕捉端点方式“闭合”,
  504.   ;;则修改组码使其达到闭合效果。
  505.   (setq
  506.     dat0 (reverse (member '(39 . 0.0) (reverse dat)))
  507.     dat1 (cdr (member '(39 . 0.0) dat))
  508.     dat9 (list (last dat1))
  509.     dat1 (reverse (cdr (reverse dat1)))
  510.     data (member ptfrst dat1)
  511.     datb (reverse (cdr (member ptfrst (reverse dat1))))
  512.   ) ;_ 结束setq
  513.   (entmod (append dat0 data datb dat9))
  514.   ;;以上一段:修改组码,使pline从指定点开始。
  515. ) ;_ 结束defun


  516. ;;子程序,将界址点号输出到idout.dat
  517. (defun pointout
  518.        (pointlist / f i point x y point1)
  519.        (setq f (open "idout.dat" "w"))
  520.        (setq i 0)
  521.        (repeat (length pointlist)
  522.         (setq point (nth i pointlist))
  523.         (setq x (/ (car point) 2)
  524.         y (/ (cadr point) 2)
  525.         ) ;_ 结束setq
  526.         (setq x (/ (fix (* x 1e5)) 1e5)
  527.         y (/ (fix (* y 1e5)) 1e5)
  528.         ) ;_ 结束setq
  529.         (princ (strcat (if (= i 0)
  530.              ""
  531.              "\n"
  532.            ) ;_ 结束if
  533.            (itoa (1+ i))
  534.            ","
  535.            (rtos x 2 5)
  536.            ","
  537.            (rtos y 2 5)
  538.          ) ;_ 结束strcat
  539.          f
  540.         ) ;_ 结束princ
  541.         (setq i (1+ i))
  542.        );repeat
  543.        (setq point1 (nth 0 pointlist)
  544.        x      (/ (car point1) 2)
  545.        y      (/ (cadr point1) 2)
  546.        ) ;_ 结束setq
  547.        (setq x (/ (fix (* x 1e5)) 1e5)
  548.        y (/ (fix (* y 1e5)) 1e5)
  549.        ) ;_ 结束setq
  550.        (princ (strcat "\n" (itoa 1) "," (rtos x 2 5) "," (rtos y 2 5))
  551.         f
  552.        ) ;_ 结束princ
  553.        (close f)
  554. ) ;_ 结束dufun

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2011-4-10 12:52:11 | 显示全部楼层
看来周末大家都要休息。
 楼主| 发表于 2011-4-10 13:23:06 | 显示全部楼层
本帖最后由 mandala 于 2011-4-10 23:44 编辑

第三个问题的原因已经找到,是子程序plchangestart中的问题,不是所有多段线的组码39都为0:

;子程序,修改不闭合的pline使其闭合,并按指定点作为起点重绘pline,
;;返回pline的组码。
(defun plchangestart
       (ee p1 / pt dat ptfrst ename aa data datb dat0 dat1 dat9)
  (setq pt (list (car p1) (cadr p1)))
  (setq dat (entget ee))
  (setq ptfrst (cons 10 pt))
  (setq ename (vlax-ename->vla-object ee))
  (if (vlax-curve-isclosed ename)
    (setq dat dat)
    (progn
      (setq dat (subst (cons 70 129) (assoc 70 dat) dat))
      (setq data (list (last dat)))
      (setq datb (reverse (cdr (cdr (cdr (cdr (cdr (reverse dat))))))))
      (setq dat (entmod (append datb data)))
    ) ;_ 结束progn
  ) ;_ 结束if
  ;;以上一段:如果pl最终不是以“c”闭合而是以捕捉端点方式“闭合”,
  ;;则修改组码使其达到闭合效果。
  (setq
    dat0 (reverse (member '(39 . 0.0) (reverse dat)))   =====》改为 dat0 (reverse (member (assoc 39 dat) (reverse dat)))
    dat1 (cdr (member '(39 . 0.0) dat))                         =====》
改为 dat1 (cdr (member (assoc 39 dat) dat))
    dat9 (list (last dat1))
    dat1 (reverse (cdr (reverse dat1)))
    data (member ptfrst dat1)
    datb (reverse (cdr (member ptfrst (reverse dat1))))
  ) ;_ 结束setq
  (entmod (append dat0 data datb dat9))
  ;;以上一段:修改组码,使pline从指定点开始。
) ;_ 结束defun
 楼主| 发表于 2011-4-10 13:31:45 | 显示全部楼层
本帖最后由 mandala 于 2011-4-10 13:34 编辑

第一、第二个问题,应该出在make和make1采用的两种裁剪方式上。

make里边是这么来裁剪的:(command "_.lengthen" "de"  "-0.4"  (list jzxout start)  (list jzxout end)  "")

make1里边是这么来裁剪的:(command "._trim" c1 "" (list jzxout ps) "")

c1是一个圆的图元名,jzxout是通过c1圆心的一条线的图元名,ps是圆心的点名。

可能这两种方式都未必百分之百靠得住?

第四个图形,不知道问题出在哪里。"Automation 错误。未提供说明。"是什么意思啊???
   
 楼主| 发表于 2011-4-10 22:36:08 | 显示全部楼层
本帖最后由 mandala 于 2011-4-11 00:14 编辑

唉,自己动手,又解决了问题2和问题4。

问题2不是因为trim的原因,而是因为判断顺逆时针方向的子程序的算法不可靠,明明是逆时针的也判断成顺时针了。现在换成Gu_xl版主以前写的一个lsp,程序相对复杂了一点,但问题解决。在这里顺便祝Gu_xl他老人家永远健康。

问题4原因还是不明,但是换成Gu_xl的那个判断方向的lsp后,问题也解决了。具体原因有待研究。

现在就剩下第一个问题解决不了。我想应该是lengthen的原因了。

怎么这个帖子就我一个人在自言自语。
发表于 2011-8-24 18:00:09 | 显示全部楼层
顶一下,呵呵!!!
 楼主| 发表于 2011-8-24 20:59:11 | 显示全部楼层
这个lsp其实可以卖点钱的,当时也写出了一身汗,嘻嘻。
发表于 2011-8-25 08:35:03 | 显示全部楼层
看到了就顶一下...要是能早点拿出来就好了..```
发表于 2011-8-30 10:30:20 | 显示全部楼层
不错很实用
发表于 2012-9-16 20:54:18 | 显示全部楼层
好东西,正在做宗地图,谢谢楼主的分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-7-21 05:49 , Processed in 0.206880 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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