明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: 004

[wkq004]由三角网生等高线-我的Alisp之路

    [复制链接]
 楼主| 发表于 2012-12-16 00:49:38 | 显示全部楼层
本帖最后由 004 于 2012-12-16 00:55 编辑

这个三角网我写了4个版本的1.相邻边法,2.ssget法(用坐标构造的选择集好像不可靠,未写完放弃了)3.三角形编号法4.短线相接法。感谢gzxl大侠的指引。1,3,4都能运行,短线相接法的速度快了好多(60个三角网0.5秒),基本满足了我的要求,但总觉得啰嗦,还请大侠们优化,连夜贴出代码就是想得到大侠们的指点。请不吝赐教。
  1. ;|功能:由三角网生等高线-相邻边法
  2. 日期:wkq004@qq.com于2012-12-9|;
  3. (vl-load-com)
  4. (setq myms (vla-get-ModelSpace
  5.       (vla-get-ActiveDocument (vlax-get-acad-object))
  6.     )
  7. )
  8. (defun mk2polyline (pts bh /)
  9.   ;;功能:生成二次拟合的二维多段线
  10.   ;;参数:pts  点表  bh 闭合否T nil
  11.   ;;返回:未指定
  12.   ;;全局变量:elev 高程
  13.   ;;日期:wkq004@qq.com于2012-12-9
  14.   (setq pts (apply 'append pts))
  15.   (setq pts
  16.   (vlax-safearray-fill
  17.     (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length pts))))
  18.     pts
  19.   )
  20.   )
  21.   (setq my2dpoly (vla-AddPolyline myms (vlax-make-variant pts)))
  22.   (vla-put-Elevation my2dpoly elev) ;_标高
  23.   (if bh
  24.     (vla-put-Closed my2dpoly T) ;_闭合
  25.   )
  26.   (vla-put-type my2dpoly acQuadSplinePoly) ;_二次拟合
  27. )
  28. (defun chuan (a b / az bz)
  29.   ;;等高线是否穿过此边
  30.   (setq az (caddr a))
  31.   (setq bz (caddr b))
  32.   (if (< (* (- az elev) (- bz elev)) 0)
  33.     T ;_返回穿过边
  34.     nil
  35.   )
  36. )
  37. (defun funbian (a b /)
  38.   ;;坐标排序,按x从小到大排,如相等就按y从小到大排
  39.   (if (< (car a) (car b))
  40.     (list a b)
  41.     (if (= (car a) (car b))
  42.       (if (< (cadr a) (cadr b))
  43. (list a b)
  44. (list b a)
  45.       )
  46.       (list b a)
  47.     )
  48.   )
  49. )
  50. (defun nbian (n xlb / comeN)
  51.   ;;求相邻三角形的编号
  52.   (setq xlb (cdr xlb))
  53.   (if (= n (car xlb))
  54.     (if (setq comeN (caddr xlb))
  55.       (list comeN (cadddr xlb))
  56.     )
  57.     (list (car xlb) (cadr xlb))
  58.   )
  59. )
  60. (defun funptxlb (xlb / A AZ B BZ DIST DT GAO GAOC PT)
  61. ;;;计算边与等高线相交的控制点坐标.
  62. ;;;返回坐标点
  63.   (setq a (car xlb))
  64.   (setq b (cadr xlb))
  65.   (setq az (caddr a))
  66.   (setq bz (caddr b))
  67.   (setq a (list (car a) (cadr a) 0))
  68.   (setq dist (distance a (list (car b) (cadr b))))
  69.   (setq gaoc (abs (- az bz)))
  70.   (setq gao (abs (- az elev)))
  71.   (setq dt (* dist (/ gao gaoc)))
  72.   (setq pt (polar a (angle a b) dt))
  73.   (setq ptlst (append ptlst (list pt)))
  74. )
  75. (defun qpt (ee /)
  76.   ;;求三角网顶点坐标
  77.   (setq e (entnext ee))
  78.   (cdr (assoc '10 (entget e)))
  79. )
  80. (defun c:tt (/ DGJ ELEV MAXZ MINZ PTLST SJXELST SJXLBLST SJXNLST SJXNNN
  81.       sjxlbnn sjxlbn SS
  82.      )
  83. ;;;作者:wkq004@qq.com  2012.11.16
  84. ;;;功能:由三角网生等高线
  85.   (command ".undo" "end")
  86.   (command ".undo" "begin")
  87.   (defun qssjx (i / A AZ B BZ C CZ E PT XH XLB1 XLB2 NGOBIAN)
  88.     ;;搜索起始三角形
  89.     ;;全局变量 (ELEV SJXELST SJXNLST qsi qsbian)
  90.     (setq xh 1)
  91.     (while (and xh (setq e (nth i sjxelst)))
  92.       (setq a (qpt e))
  93.       (setq b (qpt e))
  94.       (setq c (qpt e))
  95.       (setq az (caddr a)) ;_顶点z坐标
  96.       (setq bz (caddr b))
  97.       (setq cz (caddr c))
  98.       (setq xlb1 '())
  99.       (setq xlb2 '())
  100.       (if (< (* (- az elev) (- bz elev)) 0)
  101. (if (< (* (- cz elev) (- az elev)) 0)
  102.    (setq xlb1 (funbian a b)
  103.   xlb2 (funbian c a)
  104.    )
  105.    (setq xlb1 (funbian a b)
  106.   xlb2 (funbian b c)
  107.    )
  108. )
  109. (if (< (* (- cz elev) (- az elev)) 0)
  110.    (setq xlb1 (funbian c a)
  111.   xlb2 (funbian b c)
  112.    )
  113. )
  114.       )
  115.       (if xlb1 ;_只要有一边穿过肯定是还有一边也能穿过.
  116. (progn (funptxlb xlb1)
  117.         (funptxlb xlb2)
  118.         (setq sjxnlst (subst -1 i sjxnlst)) ;_将处理后的三角形编号改为-1
  119.         (setq qsbian (assoc xlb1 sjxlblst)) ;_起始边
  120.         (setq qsi i) ;_起始边
  121.         (setq xh nil)
  122.         (setq ngobian (list i xlb2)) ;_n三角形的离开边
  123. )
  124. (progn (setq sjxnlst (subst -1 i sjxnlst))
  125.         (while (= -1 (nth (setq i (+ i 1)) sjxnlst))) ;_用边编号找起始边能快一半
  126. )
  127.       )
  128.     )
  129.     ngobian ;_返回
  130.   )
  131.   (defun funxlbsjx (lst / A AB B BC C CA E GONUM go NUMLST PT)
  132. ;;;进入三角形cn
  133. ;;;进入边xlb
  134. ;;;相邻边三角形
  135.     (setq cn (car lst))
  136.     (setq cnum (cadr lst))
  137.     (setq e (nth cn sjxelst))
  138.     (setq a (qpt e))
  139.     (setq b (qpt e))
  140.     (setq c (qpt e))
  141.     (cond ((= cnum 1)
  142.     (if (chuan b c)
  143.       (setq go (funbian b c))
  144.       (setq go (funbian c a))
  145.     )
  146.    )
  147.    ((= cnum 2)
  148.     (if (chuan c a)
  149.       (setq go (funbian c a))
  150.       (setq go (funbian a b))
  151.     )
  152.    )
  153.    ((= cnum 3)
  154.     (if (chuan a b)
  155.       (setq go (funbian a b))
  156.       (setq go (funbian b c))
  157.     )
  158.    )
  159.     )
  160.     (setq sjxnlst (subst -1 cn sjxnlst))
  161.     (funptxlb go)
  162.     (list cn go)
  163.   )
  164.   (defun sdgx (/ BH COMEN COMENUM ELEV FX GCNUM GO I LST N NGO QSBIAN
  165.         SJXN XH XH2 XLB XLBLST lst
  166.        )
  167.     ;;生等高线
  168.     ;;全局变量:等高距 dgj minz maxz
  169.     (setq dgj 1) ;_等高距
  170.     (setq minz (* (+ 1 (fix (/ minz dgj))) dgj)) ;_最小Z
  171.     (setq maxz (* (fix (/ maxz dgj)) dgj)) ;_最大Z
  172.     (setq gcnum (/ (- maxz minz) dgj)) ;_高差算出等高线数量
  173.     (setq elev minz) ;_从最小的高程画起
  174.     (repeat gcnum ;_等高线数量
  175.       ;;(maxz minz sjxelst sjxlblst sjxnlst sjxnnn)
  176.       (setq ptlst '())
  177.       (setq sjxnlst sjxnnn) ;_本条等高线的三角形编号表
  178.       (setq i -1)
  179.       (setq xh T) ;_切换高程
  180.       (setq xh2 T) ;_同一高程的新线
  181.       (while (progn (while xh2
  182.         (setq sjxn (nth (setq i (+ 1 i)) sjxnlst))
  183.         (cond ((not sjxn) (setq xh nil) (setq xh2 nil))
  184.        ((/= -1 sjxn) (setq xh T) (setq xh2 nil))
  185.         )
  186.       )
  187.       xh
  188.       )
  189. (setq xh2 T)
  190. ;;调用起始三角形返回编号和离开边
  191. (setq ngo (qssjx i))
  192. (setq fx 0)
  193. (while ngo
  194.    (setq n (car ngo)) ;_离开三角形的编号
  195.    (setq go (cadr ngo)) ;_离开的边
  196.    (setq xlblst (assoc go sjxlblst))
  197.    (if (setq lst (nbian n xlblst)) ;_进入三角形的编号
  198.      (if (= (car lst) qsi)
  199.        (progn (setq ngo nil)
  200.        (mk2polyline ptlst T)
  201.        (setq ptlst '())
  202.        )
  203.        (setq ngo (funxlbsjx lst))
  204.      )
  205.      (if (= fx 0) ;_如闭合为nil说明在起点处开始的不用反向直接生线
  206.        (setq ngo   (list qsi (car qsbian))
  207.       ptlst (reverse ptlst)
  208.       fx   1
  209.        ) ;_起始边的邻边
  210.        (progn (setq ngo nil)
  211.        (mk2polyline ptlst nil)
  212.        (setq ptlst '())
  213.        )
  214.      )
  215.    )
  216. )
  217.       )
  218.       (setq elev (+ elev dgj))
  219.     )
  220.   )
  221.   (defun sjzl (/ E EL EMAIN EXDATA EXPTLST I PTA PTB PTC PTZ)
  222.     ;;数据整理(sjxelst sjxnlst sjxddlst ddsjxlst bxllst sjxsblst /)
  223.     ;;全局变量 maxz minz sjxelst sjxlblst sjxnlst sjxnnn
  224.     (setq sjxnlst  '() ;_三角形编号表
  225.    sjxelst  '() ;_三角形与编号对应的图元表
  226.    sjxlblst '() ;_三角形邻边表
  227.    i    -1
  228.    minz    9999
  229.    maxz    -9999
  230.    sjxnnn   (repeat (sslength ss)
  231.        (setq i (+ 1 i))
  232.        (setq sjxnlst (append sjxnlst (list i)))
  233.      ) ;_三角形原始编号表
  234.    i    -1
  235.     )
  236.     (repeat (sslength ss)
  237.       (setq e (ssname ss (setq i (+ 1 i))))
  238.       (setq sjxelst (append sjxelst (list e)))
  239.       (defun funqpt (ee / el pt ptz)
  240. (setq e (entnext ee))
  241. (setq el (entget e))
  242. (setq pt (cdr (assoc '10 el)))
  243. (setq ptz (caddr pt))
  244. (if (< ptz minz)
  245.    (setq minz ptz)
  246.    (if (> ptz maxz)
  247.      (setq maxz ptz)
  248.    )
  249. )
  250. pt ;_返回
  251.       )
  252.       (setq pta (funqpt e))
  253.       (setq ptb (funqpt e))
  254.       (setq ptc (funqpt e))
  255.       (defun funxl (a b i n / ab findab)
  256. (setq ab (funbian a b))
  257. (setq findab (assoc ab sjxlblst))
  258. (if findab
  259.    (setq sjxlblst
  260.    (subst (append findab (list i n)) findab sjxlblst)
  261.    )
  262.    (setq sjxlblst (append sjxlblst (list (list ab i n))))
  263. )
  264.       )
  265.       (funxl pta ptb i 1) ;_点a 点b 三角形编号  边编号
  266.       (funxl ptb ptc i 2)
  267.       (funxl ptc pta i 3)
  268.     )
  269.   )
  270.   (if (setq ss (ssget '((0 . "OLYLINE") (8 . "SJW"))))
  271.     (progn (setq ti (car (_VL-TIMES)))
  272.     (sjzl)
  273.     (sdgx)
  274.     (setq time (strcat "\n "
  275.          (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4)
  276.          " secs."
  277.         )
  278.     );_计算程序耗时
  279.     (setq fl (open "d:\\111.txt" "a"))
  280.     (print time fl)
  281.     )
  282.   )
  283.   (command ".undo" "end")
  284.   (princ)
  285. );_程序完毕

 楼主| 发表于 2012-12-16 00:50:43 | 显示全部楼层
  1. ;|功能:由三角网生等高线-短线连接法(较快)
  2. 日期:wkq004@qq.com于2012-12-16
  3. |;
  4. (vl-load-com)
  5. (defun mk2polyline (pts bh elev / lenn pts my2dpoly)
  6.   ;;功能:生成二次拟合的二维多段线
  7.   ;;参数:pts  点表  bh 闭合否T nil
  8.   ;;返回:未指定
  9.   ;;全局变量:elev 高程
  10.   ;;日期:wkq004@qq.com于2012-12-16
  11.   (setq
  12.     pts        (apply 'append (mapcar '(lambda (x) (append x (list 0))) pts))
  13.   )
  14.   (setq lenn (length pts))
  15.   (if (>= lenn 6)
  16.     ;;有遇到两点相同的一段线,以为是闭合去掉一点后,就创建不了线而出错.
  17.     (progn (setq
  18.              pts (vlax-safearray-fill
  19.                    (vlax-make-safearray vlax-vbDouble (cons 0 (1- lenn)))
  20.                    pts
  21.                  )
  22.            )
  23.            (setq my2dpoly (vla-AddPolyline myms (vlax-make-variant pts)))
  24.            (vla-put-Elevation my2dpoly elev) ;_标高
  25.            (if bh
  26.              (vla-put-Closed my2dpoly T) ;_闭合
  27.            )
  28.            (if (> lenn 6)
  29.              (vla-put-type my2dpoly acQuadSplinePoly) ;_二次拟合
  30.            )
  31.     )
  32.   )
  33. )

  34. (defun c:tt (/ A ABLST B BCLST C CALST DGJ E ELEVG END FL FUN FX G I JO
  35.              LEN LINE LINELST N        NN ONE PTLST QSI SS START TI TIME TWO XH
  36.              Y
  37.             )
  38.   (command ".undo" "end")
  39.   (command ".undo" "begin")
  40.   (setq        myms (vla-get-ModelSpace
  41.                (vla-get-ActiveDocument (vlax-get-acad-object))
  42.              )
  43.   )
  44.   (if (setq ss (ssget '((0 . "POLYLINE") (8 . "SJW"))))
  45.     (progn
  46.       (setq ti (car (_VL-TIMES))) ;_获得程序开始时间
  47.       (foreach elevg elevglst (set (read elevg) nil))
  48.       (setq elevglst nil)
  49.       (setq dgj 1) ;_等高距
  50.       (setq i -1)
  51.       (repeat (sslength ss)
  52.         (setq e (ssname ss (setq i (+ 1 i))))
  53.         (defun qpt (ee / el pt ptz)
  54.           ;;求三角形的顶点坐标
  55.           (setq e (entnext ee))
  56.           (setq el (entget e))
  57.           (setq pt (cdr (assoc '10 el)))
  58.         )
  59.         (setq a (qpt e))
  60.         (setq b (qpt e))
  61.         (setq c (qpt e))
  62.         (defun bianpt (a b / ANG AZ BZ DIST DT ELEV GAOC GCNUM MAXZ MINZ
  63.                        PT TMP
  64.                       )
  65.           (setq y t) ;_等高线是否经过
  66.           (setq az (caddr a))
  67.           (setq bz (caddr b))
  68.           (if (= bz az)
  69.             ;;判断两点之间是否有指定等高距的等高线穿过
  70.             (setq y nil)
  71.             (progn (if (< (- bz az) 0)
  72.                      ;;使bz>az
  73.                      (setq tmp az
  74.                            az  bz
  75.                            bz  tmp
  76.                            tmp a
  77.                            a   b
  78.                            b   tmp
  79.                      )
  80.                    )
  81.                    (if (< (- bz az) dgj)
  82.                      (if (< (- bz (rem bz dgj)) az)
  83.                        (setq y nil)
  84.                      )
  85.                    )
  86.             )
  87.           )
  88.           (if y
  89.             ;;计算此边所有等高线的穿过点
  90.             (progn (setq a (list (car a) (cadr a) 0))
  91.                    (setq dist (distance a (list (car b) (cadr b))))
  92.                    (setq gaoc (- bz az))
  93.                    (setq ang (angle a b))
  94.                    (setq minz (* (+ 1 (fix (/ az dgj))) dgj)) ;_最小Z
  95.                    (setq maxz (* (fix (/ bz dgj)) dgj)) ;_最大Z
  96.                    (setq gcnum (/ (- maxz minz) dgj)) ;_高差算出等高线数量
  97.                    (setq elev minz) ;_从最小的高程画起
  98.                    (setq dt (* dist (/ (- elev az) gaoc)))
  99.                    (setq pt (polar a ang dt))
  100.                    (setq pt (list (car pt) (cadr pt)))
  101.                    (setq ptlst (append ptlst (list (list elev pt))))
  102.                    (setq dt (* dist (/ dgj gaoc)))
  103.                    (repeat gcnum
  104.                      (setq elev (+ elev dgj))
  105.                      (setq pt (polar pt ang dt))
  106.                      (setq pt (list (car pt) (cadr pt)))
  107.                      (setq ptlst (append ptlst (list (list elev pt))))
  108.                    )
  109.             )
  110.           )
  111.         )
  112.         (setq ptlst '())
  113.         (setq ablst (bianpt a b))
  114.         (setq bclst (bianpt b c))
  115.         (setq calst (bianpt c a))
  116.         (while ptlst
  117.           ;;将此三角形三边等高线的穿过点整理成小短线,并加入同高名变量表
  118.           (setq bb (rem (length ptlst) 2))
  119.           (setq one (car ptlst))
  120.           (setq g (car one))
  121.           (setq ptlst (cdr ptlst))
  122.           (setq two (assoc g ptlst))
  123.           (setq ptlst (vl-remove two ptlst))
  124.           (setq one (cadr one))
  125.           (setq two (cadr two))
  126.           (setq elevg (strcat "g" (itoa g)))
  127.           ;;创建符号名为elevg的表,或在elevg表的尾部加上此段线
  128.           (if (member elevg elevglst)
  129.             (set (read elevg)
  130.                  (append (eval (read elevg))
  131.                          (list (list one two) (list two one))
  132.                  )
  133.             )
  134.             (progn
  135.               (set (read elevg) (list (list one two) (list two one)))
  136.               (setq elevglst (append elevglst (list elevg))) ;_将此高加入等值线变量名表
  137.             )
  138.           )
  139.         )
  140.       )
  141.       ;;依次取出等值线变量名表
  142.       (foreach elevg elevglst
  143.         (setq g (atoi (substr elevg 2))) ;_高程值
  144.         (setq linelst (eval (read elevg))) ;_等值短线表
  145.         (setq len (length linelst))
  146.         (setq a nil)
  147.         (setq b nil)
  148.         ;;短线按x坐标排序,x相同,用y坐标排
  149.         (setq nn (vl-sort-i linelst
  150.                             (function (lambda (a b)
  151.                                         (setq ax (caar a))
  152.                                         (setq ay (cadar a))
  153.                                         (setq bx (caar b))
  154.                                         (setq by (cadar b))
  155.                                         (if (equal ax bx 0.001)
  156.                                           (if (equal ay by 0.001)
  157.                                             T
  158.                                             (if        (< ay by)
  159.                                               T
  160.                                               nil
  161.                                             )
  162.                                           )
  163.                                           (if (< ax bx)
  164.                                             T
  165.                                             nil
  166.                                           )
  167.                                         )
  168.                                       )
  169.                             )
  170.                  )
  171.         )
  172.         (setq ptlst '())
  173.         (setq qsi 0)
  174.         ;;同一高程的等高线有三种情况的组合,
  175.         ;;1.单条2.闭合,3.多条
  176.         (while (setq n (nth qsi nn))
  177.           (setq i qsi)
  178.           (setq line (nth n linelst))
  179.           (setq ptlst line)
  180.           (setq jo (rem n 2))
  181.           (setq nn (subst -1 n nn))
  182.           (setq        nn (subst -1
  183.                           (if (= 0 jo)
  184.                             (1+ n)
  185.                             (1- n)
  186.                           )
  187.                           nn
  188.                    )
  189.           )
  190.           (setq start (car line))
  191.           (setq end (cadr line))
  192.           (while (= -1 (nth i nn)) (setq i (1+ i)))
  193.           (setq xh T)
  194.           ;;确定搜索方向
  195.           (setq        fx 1
  196.                 fun >
  197.           )
  198.           (while (and xh (setq n (nth i nn)))
  199.             (setq two (nth n linelst))
  200.             (if        (equal end (car two) 0.001)
  201.               (progn (setq n (nth i nn))
  202.                      (setq nn (subst -1 n nn))
  203.                      (setq jo         (rem n 2)
  204.                            nn         (subst        -1
  205.                                         (if (= 0 jo)
  206.                                           (1+ n)
  207.                                           (1- n)
  208.                                         )
  209.                                         nn
  210.                                  )
  211.                            ptlst (append ptlst (list (cadr two)))
  212.                            start (car two)
  213.                            end         (cadr two)
  214.                      )
  215.                      (if (> (car end) (car start))
  216.                        (setq fx        1
  217.                              fun >
  218.                        )
  219.                        (setq fx        -1
  220.                              fun <
  221.                        )
  222.                      )
  223.               )
  224.               (if (fun (car end) (caar two))
  225.                 (setq i (+ i fx))
  226.                 (setq xh nil)
  227.               )
  228.             )
  229.             (while (and (/= -1 i) (= -1 (nth i nn))) (setq i (+ i fx)))
  230.             (if        (= i -1)
  231.               (setq xh nil)
  232.             )
  233.           )
  234.           (if ptlst
  235.             (progn (if (equal (car ptlst) (last ptlst) 0.001)
  236.                      ;;判断闭合
  237.                      (setq bh         T
  238.                            ptlst (cdr ptlst)
  239.                      )
  240.                      (setq bh nil)
  241.                    )
  242.                    (mk2polyline ptlst bh g)
  243.                    (setq ptlst '())
  244.             )
  245.           )
  246.           (setq i qsi)
  247.           (while (= -1 (nth i nn)) (setq i (1+ i)))
  248.           (setq qsi i)
  249.         )
  250.       )
  251.       ;;清空定义的序列变量
  252.       (foreach elevg elevglst (set (read elevg) nil))
  253.       (setq elevglst nil)
  254.       (setq time (strcat "\n "
  255.                          (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4)
  256.                          " secs."
  257.                  )
  258.       ) ;_计算程序耗时
  259.       (princ time)
  260.       (setq fl (open "d:\\111.txt" "a"))
  261.       (print time fl)
  262.     )
  263.   )
  264.   (command ".undo" "end")
  265.   (princ)
  266. ) ;_程序完毕
 楼主| 发表于 2012-12-16 01:00:15 | 显示全部楼层
本帖最后由 004 于 2012-12-16 01:01 编辑

再贴个再论坛上找到的生三角网的程序,很快,最后一个子程序的算法,看了几遍都晕,还望大侠指点。
  1. (defun c:tt (/ i pl s)
  2. ;;;-------------------------------------------------------------------
  3. ;;;来自:明经通道网站   作者:雷锋
  4. ;;;功能:用高程点生成三角网
  5. ;;;参数:pl 点集
  6. ;;;分类:专业程序-测绘-高程点-三角网-TIN
  7.   (princ (strcat "\n选择高程点..."))
  8.   (setq lstlst '())
  9.   (setq delsl (ssadd))
  10.   (if (setq i 0
  11.             s (ssget '((8 . "GCD") (0 . "INSERT") (2 . "GC200")))
  12.       )
  13.     (progn (repeat (sslength s)
  14.              (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
  15.                    i  (1+ i)
  16.              )
  17.            )
  18.            (triangulate pl)
  19.     )
  20.   )
  21.   (print lstlst)
  22. )
  23. (defun triangulate (pl / a b c i i1 i2 bb sl al        el tl L        ma mi ti tr x1
  24.                     x2 y1 y2 p r cp)
  25.   (if pl
  26.     (progn
  27.       (setq ti (car (_VL-TIMES));_获取时间
  28.             i  1
  29.             i1 (/ (length pl) 100.)
  30.             i2 0
  31.             pl (vl-sort pl (function (lambda (a b) (< (car a) (car b)))));_将点集按x坐标从小到大排序
  32.             bb (list (apply 'mapcar (cons 'min pl));_取得点集X的最小坐标Y的最小坐标
  33.                      (apply 'mapcar (cons 'max pl));_取得点集X的最大坐标Y的最大坐标
  34.                )
  35.             x1 (caar bb);_x方向最小值
  36.             x2 (caadr bb);_x方向最大值
  37.             y1 (cadar bb);_y方向最小值
  38.             y2 (cadadr bb);_y方向最大值
  39.       )
  40.       
  41.       (command "rectang" (car bb) (cadr bb))
  42.       (command "text" (car bb) "" "" "x1 y1")
  43.       (command "text" (cadr bb) "" "" "x2 y2")
  44.       (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0));_点集的中心点平面坐标
  45.             r  (* (distance cp (list x1 y1)) 20);_搜索半径,中心点到左下角点的20倍
  46.             ma (+ (car cp) r);_x最大设为中心点x加r
  47.             mi (- (car cp) r);_x最小设为中心点x减r
  48.             sl (list (list ma (cadr cp) 0);_初始化        x最大 y中心 0
  49.                      (list mi (+ (cadr cp) r) 0);_初始化  x最小 y最大 0
  50.                      (list mi (- (cadr cp) r) 0);_初始化  x最小 y最小 0
  51.                )
  52.             al (list (cons x2 (cons cp (cons (* 20 r) sl))));_((x大 (中心点) r*20 (x最大y中心 0) (x最小 y最大 0) (x最小 y最小 0)))
  53.             ma (1- ma);_                                      ((2.55524e+007 (2.55523e+007 4.29672e+006) 13900.2 (2.5553e+007 4.29672e+006 0) (2.55516e+007 4.29742e+006 0) (2.55516e+007 4.29603e+006 0)))
  54.             mi (1+ mi)
  55.       )
  56. ;;;      (command "circle" cp 2)
  57. ;;;      (command "circle" cp r)
  58. ;;;      (command "pline" (car sl) "h" 2 0 (cadr sl) (caddr sl) "")
  59. ;;;      (command "text" cp "" "" "cp")
  60. ;;;      
  61. ;;;      (command "text" (car sl) "" "" "sl-1")
  62. ;;;      (ssadd (entlast) delsl)
  63. ;;;      (command "text" (cadr sl) "" "" "sl-2")
  64. ;;;      (ssadd (entlast) delsl)
  65. ;;;      (command "text" (caddr sl) "" "" "sl-3")
  66. ;;;      (ssadd (entlast) delsl)
  67. ;;;      (command "pline" (car sl) (cadr sl) (caddr sl) (car sl) "")
  68.       (repeat (length pl)
  69.         (setq p         (car pl);_点集中的第一个点
  70.               pl (cdr pl)
  71.               el nil
  72.         )
  73.         (while al
  74.           (setq        tr (car al);_(x大 (中心点) r*20 (x最大y中心 0) (x最小 y最大 0) (x最小 y最小 0))
  75.                 al (cdr al);_((中心点) r*20 (x最大y中心 0) (x最小 y最大 0) (x最小 y最小 0))
  76.           )
  77.           (cond        ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)));_x大小于p的x
  78.                 ((< (distance p (cadr tr)) (caddr tr))
  79.                  ;;p到中心点cp的距离小于r*20
  80.                  (setq tr (cdddr tr);_((x最大y中心 0) (x最小 y最大 0) (x最小 y最小 0))
  81.                        a  (car tr);_(x最大y中心 0)
  82.                        b  (cadr tr);_(x最小 y最大 0)
  83.                        c  (caddr tr);_(x最小 y最小 0)
  84.                        el (cons
  85.                             (list (+ (car a) (car b)) (+ (cadr a) (cadr b)) a b)
  86.                             (cons (list        (+ (car b) (car c))
  87.                                         (+ (cadr b) (cadr c))
  88.                                         b
  89.                                         c
  90.                                   )
  91.                                   (cons        (list (+ (car c) (car a))
  92.                                               (+ (cadr c) (cadr a))
  93.                                               c
  94.                                               a
  95.                                         )
  96.                                         el
  97.                                   )
  98.                             )
  99.                           );_((ax+bx ay+by a b) (bx+cx by+cy b c) (cx+ax cy+ay c a))
  100.                  )
  101.                 )
  102.                 (t (setq L (cons tr L)))
  103.           )
  104. ;;;          (command "text" a "" "" "a")
  105. ;;;          (command "text" b "" "" "b")
  106. ;;;          (command "text" c "" "" "c")
  107. ;;;          (command "pline" a "h" 2 0 b c a"")
  108.         )
  109.         (setq al L
  110.               L         nil
  111.               el (vl-sort el
  112.                           (function (lambda (a b)
  113.                                       (if (= (car a) (car b))
  114.                                         (<= (cadr a) (cadr b))
  115.                                         (< (car a) (car b))
  116.                                       )
  117.                                     )
  118.                           )
  119.                  );_用x的和排序,相等的再用y排
  120.         )
  121.         (while el
  122.           (if (and (= (caar el) (caadr el)) (= (cadar el) (cadadr el)))
  123.             (setq el (cddr el));_如ax+bx=bx+cx 且ay+by=by+cy
  124.             (setq al (cons (getcircumcircle p (cddar el)) al);_传入p 和 a b
  125.                   el (cdr el)
  126.             )
  127.           )
  128.         )
  129.         (if (and (< (setq i (1- i)) 1) (< i2 100))
  130.           (progn (setvar "MODEMACRO"
  131.                          (strcat "◎正在连三角网"
  132.                                  (itoa (setq i2 (1+ i2)))
  133.                                  " % "
  134.                                  (substr "..." 1 (- 100 i2))
  135.                          )
  136.                  )
  137.                  (setq i i1)
  138.           )
  139.         )
  140.       )
  141.       (foreach tr al (setq tl (cons (cdddr tr) tl)))
  142.       (setq tl
  143.              (vl-remove-if-not
  144.                (function (lambda (a)
  145.                            (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
  146.                          )
  147.                )
  148.                tl
  149.              )
  150.       )
  151.       (or (tblsearch "LAYER" "SJW")
  152.           (entmake (list '(0 . "LAYER")
  153.                          '(100 . "AcDbSymbolTableRecord")
  154.                          '(100 . "AcDbLayerTableRecord")
  155.                          '(2 . "SJW")
  156.                          '(70 . 0)
  157.                          '(62 . 8)
  158.                          '(6 . "Continuous")
  159.                          '(290 . 1)
  160.                          '(370 . -3)
  161.                         )
  162.           )
  163.       )
  164.       (setvar "CLAYER" "SJW")
  165.    
  166.       
  167.       (foreach tr tl
  168.         (entmake '((0 . "POLYLINE")
  169.                    (8 . "SJW")
  170.                    (100 . "AcDb3dPolyline")
  171.                    (70 . 9)
  172.                    (62 . 5)
  173.                   )
  174.         )
  175.         (setq a (car tr))
  176.         (setq b (cadr tr))
  177.         (setq c (caddr tr))
  178.         (entmake
  179.           (list '(0 . "VERTEX") (cons 10 (car tr)) '(70 . 32))
  180.         )
  181.         (entmake
  182.           (list '(0 . "VERTEX") (cons 10 (cadr tr)) '(70 . 32))
  183.         )
  184.         (entmake
  185.           (list '(0 . "VERTEX") (cons 10 (caddr tr)) '(70 . 32))
  186.         )
  187.         (entmake (list '(0 . "SEQEND")))
  188.         
  189.         
  190.         
  191.       )
  192.     )
  193.   )
  194.   
  195.   
  196.   (setvar "MODEMACRO" "")
  197.   (princ (strcat "\n "
  198.                  (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4)
  199.                  " secs."
  200.          )
  201.   )
  202.   (princ)
  203. )
  204. ;;这段麻烦哪位高人详细讲解下算法,我看了几遍还是晕.
  205. (defun getcircumcircle (a el / b c c2 cp r ang)
  206.   (setq        b  (car el)
  207.         c  (cadr el)
  208.         c2 (list (car c) (cadr c))
  209.   )
  210. ;;;  (command "pline" a "h" 2 0 b c "")
  211.   (if (not (zerop (setq ang (- (angle b c) (angle b a))))) ;_a b c不在同一方向的直线上
  212.     (progn (setq cp (polar c2
  213.                            (+ -1.570796326794896 (angle c a) ang)
  214.                            (setq r (/ (distance a c2) (sin ang) 2.0))
  215.                     )
  216.                  r  (abs r)
  217.            )
  218. ;;;           (command "circle" cp r)
  219.            (list (+ (car cp) r) cp r a b c)
  220.     )
  221.   )
  222. )

评分

参与人数 2明经币 +2 收起 理由
flytoday + 1 顶你。。楼主给测试图瞧下功能啊~
gzxl + 1 佩服

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2012-12-16 04:08:50 | 显示全部楼层
004 发表于 2012-12-16 00:49
这个三角网我写了4个版本的1.相邻边法,2.ssget法(用坐标构造的选择集好像不可靠,未写完放弃了)3. ...

我可不是大侠,学lisp时间不长

真够服你很有钻研精神

最后一个是外接圆吧
发表于 2013-1-15 21:38:06 | 显示全部楼层
这个真的要顶起来,给我写我一个都写不出来,何况是四个思路
发表于 2013-2-3 21:05:05 | 显示全部楼层
好厉害啊,学习了
发表于 2013-3-18 12:02:07 | 显示全部楼层
顶一下,希望楼主再写个读三角网文件的等高线生成程序!
 楼主| 发表于 2013-4-11 11:33:35 | 显示全部楼层
本帖最后由 004 于 2013-4-11 11:36 编辑

发个关于动态生等高线的,还没弄完,先给大家看看吧,请高手提供,不用command trim的裁切算法。
要求参看http://bbs.mjtd.com/thread-100359-1-1.html





本帖子中包含更多资源

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

x
发表于 2013-4-11 12:34:55 | 显示全部楼层
004 发表于 2013-4-11 11:33
发个关于动态生等高线的,还没弄完,先给大家看看吧,请高手提供,不用command trim的裁切算法。
要求参看 ...

谢谢分享!
收藏了。学习学习
谢谢
发表于 2013-7-14 18:57:15 | 显示全部楼层
004 发表于 2012-12-11 14:58
这个方法好,我想试试用生成lwpolyline短线的点表直接组织点集,估计会更快点,但对大量点表的穷举判断也是很 ...

楼主,你好!1米的等高距可以画出来,如果改到0.5的等高距就不行了!
“; 错误: 参数类型错误: fixnump: 5.0”
是怎么回事呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-18 22:50 , Processed in 0.173110 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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