找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 749|回复: 2

[求助] [求助]:n条多段线的最小外包线(附带一个最小范围判断程序)

[复制链接]
发表于 2005-11-9 14:01:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
已知N个多断线,需要放置在D宽的范围内:
1.如何判断线段不会超过范围?如果允许旋转(0-M)度是否有不超过范围的情况?
2.如何可以放置的长度最短?允许旋转180度时候最小长度又是多少?允许任意旋转长度又是多少?
;;;;;
(defun c:fw (/ pl_ss pt0 n1 n2 n3 pt ex0 ey0 xmax xmin ymax ymin jd d x y ex ey
             xmax0 xmin0 ymax0 ymin0 eex jd0 pl_n)
  (princ "\n请输入精度")
  (if (or (= jqd0 nil)(eq jqd0 ""))(setq jqd0 1))
  (princ jqd0)(princ ":")
  (setq jqd (getreal))
  (if (or (= jqd0 nil)(eq jqd0 ""))(setq jqd jqd0) (setq jqd0 jqd))
  (princ "\n请选择多段线")
  (setq pl_ss (ssget (list (cons 0' "LWPOLYLINE"))))
  (setq pt0 (getpoint "\n去请输入基准点"))
  (sta)
  (setq eex 0)
  (setq n1 0)
  (setq ey_max -100000000 ey_min 100000000)
  (while (< n1 (sslength pl_ss));取线段
    (setq pl_n (ssname pl_ss n1))
    (pl_duandian pl_n);;;; 返回点集合pl_dd2
    ;;;   
    (setq ex0 100000000 ey0 100000000);定义最长最宽
    (setq n2 0)
    (while (< n2 (* 2 pi))
      (setq n3 0)
      (setq xmax -100000000 xmin 100000000 ymax -100000000 ymin 100000000)
      (while (< n3 (length pl_dd2))
        (setq pt (nth n3 pl_dd2));取判断点
        (setq jd (- (angle pt (list 0 0 0)) n2));取角度
        (setq d (distance pt (list 0 0 0)));取长度
        (setq x (* d (sin jd))
              y (* d (cos jd)));取x y
        (cond
          ((> x xmax) (setq xmax x) (setq ptxmax pt3) (setq jd1 n2)));x小
        (cond
          ((< x xmin) (setq xmin x) (setq ptxmin pt3) (setq jd1 n2)));x大
        (cond
          ((> y ymax) (setq ymax y) (setq ptymax pt3) (setq jd1 n2)));y小
        (cond
          ((< y ymin) (setq ymin y) (setq ptymin pt3) (setq jd1 n2)));x大
        (setq n3 (1+ n3))
        )
      (setq ex (- xmax xmin)
            ey (- ymax ymin));求宽度和长度
      (cond
          ((< ey ey0);ey小
           (setq ey0 ey)
           (setq ex0 ex)
           (setq jd0 jd1)
           (setq xmax0 xmax)
           (setq ymax0 ymax)
           (setq xmin0 xmin)
           (setq ymin0 ymin))          
          )
      (setq n2 (+ (* pi (/ jqd 180)) n2))
      )
    (setq pt1 (polar (list 0 0 0) (+ pi jd0) ymax0))
    (setq pt2 (polar (list 0 0 0) (+ pi jd0) ymin0))
    (setq pt3 (polar pt1 (+ jd0 (* 1.5 pi)) xmax0))
    (setq pt4 (polar pt1 (+ jd0 (* 1.5 pi)) xmin0))
    (setq pt5 (polar pt2 (+ jd0 (* 1.5 pi)) xmax0))
    (setq pt6 (polar pt2 (+ jd0 (* 1.5 pi)) xmin0))
    (setq eex (+ eex ex0))
    (command "pline" pt3 pt4 pt6 pt5 "c")
    (setq ssl_1 (ssget "l"))
    (command "dimaligned" pt3 pt4 pt4)
    (setq ssl_2 (ssget "l"))
    (command "dimaligned" pt6 pt4 pt4)
    (setq ssl_3 (ssget "l"))
    (command "ROTATE" ssl_1 ssl_2 ssl_3 pl_n "" pt3 (+ 90 (* 180 (/ (* -1 jd0) pi))))
    (command "move" "p" "" pt3 (list (+ eex (nth 0 pt0)) (nth 1 pt0)))
    (if (> ey0 ey_max) (setq ey_max ey0))
    (if (< ey0 ey_min) (setq ey_min ey0))
  (setq n1 (1+ n1))
  )
  (princ "\n最大宽度")(princ ey_max)(princ ";最小宽度")(princ ey_min)
  (end)
  )
(defun pl_duandian (pl_name / n pl_dd1 pl_en_n )
  (setq pl_en (entget pl_name))
  (setq n 0)
  (while (< n (length pl_en));;;读表取点
    (setq pl_en_n (nth n pl_en))
    (cond
      ((eq '10 (nth 0 pl_en_n))
       (setq pl_dd1 (cons (cdr pl_en_n) pl_dd1))
       ))
    (setq n (1+ n))
  )
  (if (= 1 (cdr (assoc '70 pl_en)))
    (setq pl_dd1 (cons (cdr (assoc '10 pl_en)) pl_dd1)))
  (setq pl_dd2 pl_dd1)
  ;..........
  ;(princ "顶点")(princ pl_dd_0)(princ);;读点
  )
(defun sta();开始
    (command "undo" "be") ; 定义返回点
    (setvar "cmdecho" 0)  ; 关闭命令提示
    (setq osn (getvar "OSMODE"));记忆捕捉
    (setvar "OSMODE" 0)
    (if (= (getvar "ucsname") nil)
        (command "ucs" "s" "sl"); 记忆UCS
        (command "ucs" "s" "sl" "y")
     )
    (command "ucs" "w")
  )
(defun end();结束
  (command "ucs" "r" "sl"); 返回UCS
  (setvar "OSMODE" osn);恢复捕捉
  (command "undo" "e"); 定义返点
  (setvar "cmdecho" 1); 打开命令提示
  (princ)
)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-11-11 13:28:15 | 显示全部楼层
值得研究。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-11 15:19:39 | 显示全部楼层

更改多段线顶点间距程序,三维多段线顶点重复判定

(defun c:pld (/ n pl_ss pl_n pl_name pl_dd_0 pl_dd_tz sc_pd bg_pd)
  (princ "请选择多段线")
  (setq pl_ss (ssget (list (cons 0' "LWPOLYLINE"))))
  (princ "\n请输入顶点间距")
  (if (/= pl_jl0 nil) (princ pl_jl0)((setq pl_jl0 200) (princ pl_jl0)))(princ ":")
  (setq pl_jl (getint))
  (princ "\n请输入最大转角")
  (if (/= pl_jd0 nil) (princ pl_jd0)((setq pl_jd0 5) (princ pl_jd0)))(princ ":")
  (setq pl_jd (getint))
  (sta)
  (if (= pl_jl nil) (setq pl_jl pl_jl0) (setq pl_jl0 pl_jl))
  (if (= pl_jd nil) (setq pl_jd pl_jd0) (setq pl_jd0 pl_jd))
  (setq n 0)
  (while (< n (sslength pl_ss))
    (setq pl_n (ssname pl_ss n))
    (pl_duandian pl_n);;;; 返回点集合pl_dd2
    (pl_duandian_tiaozhen pl_dd2 pl_jl pl_jd);;;返回调整后点集合pl_dd4
    (pl_huizhi pl_dd4);;绘制
    (setq n (1+ n))
   )
  (setq sc_pd (getstring "\n是否删除原有多段线(Y)"))
    (if (or (eq sc_pd "") (eq sc_pd "y") (eq sc_pd "Y") (= sc_pd nil))
      (command "ERASE" pl_ss ""))
     (end)
  )
;;;;********************
;;;;读多段线端点    输入多段线   返回点表pl_dd2                                 
(defun pl_duandian (pl_name / n pl_dd1 pl_en_n )
  (setq pl_en (entget pl_name))
  (setq n 0)
  (while (< n (length pl_en));;;读表取点
    (setq pl_en_n (nth n pl_en))
    (cond
      ((eq '10 (nth 0 pl_en_n))
       (setq pl_dd1 (cons (cdr pl_en_n) pl_dd1))
       ))
    (setq n (1+ n))
  )
  (if (= 1 (cdr (assoc '70 pl_en)))
    (setq pl_dd1 (cons (cdr (assoc '10 pl_en)) pl_dd1)))
  (setq pl_dd2 pl_dd1)
  ;..........
  ;(princ "顶点")(princ pl_dd_0)(princ);;读点
  )
;;**********************
;;;重组多断线端点           输入端点 距离 转角  返回点表pl_dd_4
(defun pl_duandian_tiaozhen(pl_dd2 ld0 pl_jd / m ptst pten jdst jden jd ldst lden pl_dd3)
  (setq ptst (nth 0 pl_dd2))
  (setq pten (nth 1 pl_dd2))
  (setq jdst (angle ptst pten))
  (setq ldst ld0)
  (setq pl_dd3 (cons ptst pl_dd3));;加入
  (setq m 1)  
  (while (< m (length pl_dd2))
    (setq pten (nth m pl_dd2));;;取第m个坐标
    (setq jden (angle ptst pten));;;读取方向
;;;;角度判定                                       
    (setq jd (- jden jdst));;计算角度
    (if (< jd 0) (setq jd (* -1 jd)))
    (cond
      ((> jd (/ (* pl_jd pi) 180));;;角度过大
        (setq pl_dd3 (cons ptst pl_dd3));;加入
        (setq ldst ld0);;,归零
        (setq jden (angle ptst pten))
        (setq jdst (angle ptst pten))
       ))
;;;距离判定                                       
        (setq lden (distance ptst pten))
        (while (> lden ldst);;;距离过大
          (setq ptst (polar ptst jden ldst))
          (setq pl_dd3 (cons ptst pl_dd3));;加入
          (setq lden (distance ptst pten))
          (setq jdst jden)
          (setq ldst ld0)
          )
    (cond ((<= lden ldst);;;距离过小
           (setq ptst pten)
           (setq ldst (- ldst lden))
           (setq jdst jden))
          )
    (setq m (1+ m))
         )

  (setq pl_dd3 (cons ptst pl_dd3));;加入
  (setq pl_dd4 pl_dd3)
  ;;.........
  ;(princ "调整后顶点")(princ pl_dd_tz)(princ)
  )
;;;**************
;;;;;由点表画线  输入点表  返回线
(defun pl_huizhi (pl_dd4 / m ss ss0)
  (setq m 1)
  (setq ss (ssadd))
  (command "CECOLOR" 2)
  (while (< m (length pl_dd4))
     (command "line" (trans (nth (1- m) pl_dd4) 0 1) (trans (nth m pl_dd4) 0 1)"");;;坐标转换
    (setq ss0 (ssadd (ssname (ssget "l") 0) ss))
    ;(princ ss)
    (setq m (1+ m)))
  
  (command "pedit" "m" ss0 "" "y" "j" "" "")
  (command "CECOLOR" "bylayer")
  )
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
(defun 3l0_zx (bjm_dx / ptss ptss n bjm_dx1 bjm_dx1 lb)
  (setq n 0)
  (setq ptss (list))
  (while (= n 0)
    (setq bjm_dx (entnext bjm_dx));顺序选取下个对象
    (setq bjm_dx1 (entget bjm_dx))
    (setq lb (cdr (assoc '0 bjm_dx1)));取的类别
    (if (/= lb "SEQEND")
      (progn
    (setq pt (cdr (assoc '10 bjm_dx1)));取坐标
    (setq ptss (cons pt ptss))
      )
    (setq n 1)
  ))
  (ptch_zx ptss)
  (princ "\n长度:")(princ cd0)(princ)
  (ptpd_zx ptss)
  (princ "重复的端点数:")(princ n0)(princ"组;")
  (princ "距离小于5的端点数:")(princ n1)(princ"组;")
  )
;;;;索长度
(defun c:sch (/ bjm_dx wz)
  (princ "\n请选择三维多段线")
  (setq bjm_dx (car (entsel)))
  (3l0_zx bjm_dx)
  (princ "\n请选择文字")
  (setq wz (car (entsel)))
  (ggwz_hz wz (rtos cd0 2 0))
  (princ "\n已经更改为")(princ (rtos cd0 2 0))
  (princ)
  )
;

;;点集合重合判断
(defun ptpd_zx (ptss / pt1 pt2 n m)
  (setq n 0)
  (setq n0 0)
  (setq n1 0)
  (while (< n (length ptss))
    (setq pt1 (nth n ptss))
    (setq m 0)
    (setq m0 -1)
    (setq m1 -1)
    (while (< m (length ptss))
      (setq pt2 (nth m ptss))
;;;      (princ "\n")(princ pt1)(princ "...")(princ pt2)
      (if
        (equal pt1 pt2)
        (progn
        (setq m0 (1+ m0))
;;;        (princ "T")
;;;        (princ m0)
        ))
      (if (< (distance pt1 pt2) 5);小于5
        (progn
        (setq m1 (1+ m1))
        ))
      (setq m (1+ m))
      )
;;;   (princ "\n")(princ m0)
   (setq n0 (+ n0 m0))
   (setq n1 (+ n1 m1))
   (setq n (1+ n)))
  (setq n0 (* 0.5 n0))
  (setq n1 (* 0.5 n1))
  )
;;点集长度
(defun ptch_zx (ptss / pt1 pt2 n)
  (setq n 1)
  (setq cd0 0)
  (while (< n (length ptss))
    (setq pt1 (nth (- n 1) ptss))
    (setq pt2 (nth n ptss))
    (setq cd0 (+ cd0 (distance pt1 pt2)))
    (setq n (1+ n)))
  )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-28 20:46 , Processed in 0.342852 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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