明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5761|回复: 28

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

  [复制链接]
发表于 2011-3-13 22:48:47 | 显示全部楼层 |阅读模式
本帖最后由 mandala 于 2011-3-15 20:59 编辑

在试着编写一个做宗地图的lisp,其它都解决了,剩下这个问题困扰了好久,请教一下各位前辈:

一条封闭多段线,比如一个梯形,先假设它必定是顺时针走向的(要设定走向不难),如何指定一个顶点,让其变为起点?如图:




本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2011-3-13 22:51:22 | 显示全部楼层
本帖最后由 mandala 于 2011-3-13 22:59 编辑

先谢谢各位啦。

明经上有过类似的讨论,也有一些lisp贴出来,但我没找到可以让用户指定起点的lisp程序。

我只求一段lisp即可,错误处理什么的俺自己来,不麻烦各位,呵呵。
 楼主| 发表于 2011-3-14 09:09:53 | 显示全部楼层
星期一顶起来。
发表于 2011-3-14 09:14:40 | 显示全部楼层
本帖最后由 xiaxiang 于 2011-3-14 09:52 编辑

回复 mandala 的帖子

1. http://bbs.mjtd.com/thread-44291-1-3.html
2.
  1. ;;点集按Pl起点到终点排序,返回(pline实体 排序后的点表)
  2. ;;参数 pl --- pline 实体或Object,pts ---- 点集
  3. ;;其实 pl 可以是任何 Curve

  4. (defun xdl-pts-sortonpl  (pl pts)
  5.   (setq  pts (mapcar
  6.         '(lambda (x)
  7.      (list (vlax-curve-getdistatpoint
  8.        pl
  9.        (vlax-curve-getclosestpointto pl x)
  10.            )
  11.            x
  12.      )
  13.          )
  14.         pts
  15.       )
  16.   pts (vl-sort pts
  17.          '(lambda (e1 e2)
  18.       (< (car e1) (car e2))
  19.           )
  20.       )
  21.   )
  22.   (list  pl
  23.   (mapcar
  24.     'cadr
  25.     pts
  26.   )
  27.   )
  28. )
3 http://bbs.mjtd.com/thread-51145-1-3.html

希望对楼主有所帮助

本帖子中包含更多资源

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

x
 楼主| 发表于 2011-3-14 10:27:19 | 显示全部楼层
本帖最后由 mandala 于 2011-3-14 10:36 编辑

先谢谢楼上。不过我的问题还没有解决。

首先你提供的这个lsp不能指定pline的起点;其次你转的那个帖子里,那个lsp的作用只是重新标号,并没有改变pline本身的起点。最后那个拓扑的,我可能一下子用不上。

我希望达到的效果是指定一点后,能重新将pline重绘,以指定点为起点。
发表于 2011-3-14 10:39:57 | 显示全部楼层
回复 mandala 的帖子

如何指定一点?输入坐标吗?GETPOINT?
发表于 2011-3-14 10:39:58 | 显示全部楼层
您试试这段代码
(setq dat (entget ee)      ;  LwPolyLine ee
   ptfrst (cons 10 pt)     ; pt ==> 新起点 say '(100 200)
     dat0 (reverse (member '(39 . 0.0) (reverse dat)))
     dat1 (cdr (member '(39 . 0.0)  dat))
     dat9 (List (Last dat1))
     dat1 (reverse (cdr (reverse dat1)))
     data (member ptfrst dat1)
     datb (reverse (cdr (member ptfrst (reverse dat1))))
)
(entmod (append dat0 data datb dat9))
 楼主| 发表于 2011-3-14 10:47:59 | 显示全部楼层
xiaxiang 发表于 2011-3-14 10:39
回复 mandala 的帖子

如何指定一点?输入坐标吗?GETPOINT?

嗯,我的想法是getpoint。
发表于 2011-3-14 11:51:39 | 显示全部楼层
回复 mandala 的帖子

先测试一个,还不能指定点。
可选择闭合与否。
绘制pline程序。
命令:CC


本帖子中包含更多资源

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

x
 楼主| 发表于 2011-3-14 13:43:59 | 显示全部楼层
本帖最后由 mandala 于 2011-3-14 14:29 编辑

在实际作业时,画界址线的时候不会从1号点(通常在左上角)开始完整的画一条pline,如果不指定起点让界址线重画的话,我这个lisp的实用性不高。

贴上我写的画宗地图的lsp源码。如果能指定起点,那就完美喽!



  1. ;;制作宗地图,删除了错误处理程序。区域变量太多,这里就懒得标注了。
  2. ;;先依次以顺时针方向画好界址线,然后用make程序会自动标注点号、距离、加粗jzxout、圈上界址点并算出面积。
  3. ;;子程序暂时无用……等解决了指定起点的问题后再用。
  4. ;;需要引用字体“等线体”,随机用户可修改相应语句,用其它字体代替。


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

  143. ;;;;;;;;;;;;;;;;
  144. ;;子程序,判断pline方向,返回1为顺时针,0为逆时针
  145. (defun fangxiang (xx / fd ang offsetObj plineObj x fx)
  146.   (setq plineObj (vlax-ename->vla-object xx))
  147.   (setq fd (vlax-curve-getFirstDeriv plineObj 0.5))
  148.   (setq ang (atan (/ (cadr fd) (car fd))))
  149.   (setq offsetplineObj
  150.   (car
  151.     (vlax-safearray->list
  152.       (vlax-variant-value (vla-offset plineObj 0.0001)) ;_ 结束vlax-variant-value
  153.     ) ;_ 结束vlax-safearray->list
  154.   ) ;_ 结束car
  155.   ) ;_ 结束setq
  156.   (if (> (vla-get-length plineobj)
  157.   (vla-get-length offsetplineobj)
  158.       ) ;_ 结束>
  159.     (setq x 1)
  160.     (setq x 0)
  161.   ) ;_ 结束if
  162.   (vla-delete offsetplineObj)
  163.   (setq fx x)
  164. ) ;_ 结束defun

  165. ;;;子程序:pline顶点逆序,disign by gu_xl
  166. (defun reverseLwp (ent1 / a pl how li1 li2 li3)
  167.   (setq pl  (entget ent1 '("*"))
  168. how nil
  169.   ) ;_ 结束setq
  170.   (foreach an pl
  171.     (if (setq a (member (car an) '(10 40 41 42)))
  172.       (setq how t)
  173.     ) ;_ 结束if
  174.     (cond ((not how) (setq li1 (cons an li1)))
  175.    ((and how a)
  176.     (cond ((= (car an) 40) (setq an (cons 41 (cdr an))))
  177.    ((= (car an) 41) (setq an (cons 40 (cdr an))))
  178.    ((= (car an) 42) (setq an (cons 42 (- 0 (cdr an)))))
  179.    (t an)
  180.     ) ;_ 结束cond
  181.     (setq li2 (cons an li2))
  182.    )
  183.    ((and how (not a)) (setq li3 (cons an li3)))
  184.     ) ;_ 结束cond
  185.   ) ;_ 结束foreach
  186.   (entmod
  187.     (append (reverse li1)
  188.      (append (cdddr li2) (list (car li2) (cadr li2) (caddr li2)))
  189.      (reverse li3)
  190.     ) ;_ 结束append
  191.   ) ;_ 结束entmod
  192. ) ;_ 结束defun

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

本版积分规则

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

GMT+8, 2025-7-23 12:06 , Processed in 0.188489 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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