stonedesign 发表于 2022-6-22 11:44:26

修改 原【高飞鸟】] 【飞鸟集】画衣柜的LISP程序的画平面衣柜

【飞鸟集】画衣柜的LISP程序(更新至2014.11.27)

原来的帖子地址:【飞鸟集】画衣柜的LISP程序(更新至2014.11.27)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=86629&fromuid=7328064
(出处: 明经CAD社区)


改了一点点看上去好看点,能力有限。希望有大佬在改下。


小毛草 发表于 2022-6-24 11:11:52

我这也是YG的修改版,不过设置了出入了默认图层


(vl-load-com)
(prompt "命令是YG")
;;;画衣柜的LISP程序-----------------------------------------------------
;;;Copyright Highflybird------------------------------------------------
;;;2011.04.30 ----------------------------------------------------------
(defun c:YG(/ lst doc size pIn str pnt pts scr dlt dist1 dist2 Vec dist
            lst1 lst2 lst3 cur1 cur2 Cur3 obj1 obj2 Obj3 Objs sLen ang1 ang2 ang par
         )
;;;出错处理
(defun *error* (msg)
(setvar "cecolor""bylayer") ;_ 恢复颜色随层;
(setvar "clayer" mylayer)   ;恢复原有图层
(princ "错误信息: ")
(princ msg)      ;_ 打印错误信息
(princ)         
)
(setvar "measurement" 0)   ; 设置公制单位
(setvar "cmdecho" 0)         ; 关闭命令响应
(setvar "hpassoc" 0)          ;设置填充时不关联
(setq mylayer (getvar "clayer"))    ;保存当前层
(setq oldcolor (getvar "cecolor"))   ;保存原有颜色


(if (< (setq size (getvar "USERR5")) 100.)                            ;初始化衣柜深
    (progn
      (setvar "USERR5" 600.)                                          
      (setq size 600.)
    )
)

;;获取布置一侧,或设置衣柜深
(setq str "\n点取布置的一侧[设置(Set)] <走向右侧>:")                  ;获取布置方向
(initget 8 "Set")
(setq pIn (getpoint str))
(while (= pIn "Set")
    (setq size (getvar "USERR5"))
    (initget 14)
    (setq size (getdist (strcat "\n输入衣柜深<" (rtos size) ">:")))   ;如果需要设置衣柜深
    (if (>= size 100)
      (setvar "USERR5" size)
      (setq size (getvar "USERR5"))
    )
    (initget 8 "Set")
    (setq pIn (getpoint str))
)

;;获取靠墙边
(initget 9)                                                         ;防止空输入,点可在画面外
(setq pnt (getpoint "\n起点:"))
(setq pts (cons pnt nil))
(setq str "\n选取点<回车,空格或右键结束点取>:")
(while (setq pnt (getpoint (car pts) str))                            ;通过点取方式获得靠墙边
    (setq pnt (list (car pnt) (cadr pnt)))                              ;这步不可少,防止不在同个平面上
    (grdraw pnt (car pts) 3 1)                                          ;虚线显示布置靠墙边
    (setq pts (cons pnt pts))                                 
)

;;输入完成开始画图
(if (> (lengthpts) 1)                                             ;至少要两点
    (progn
      (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
      (vla-StartUndoMark doc)                                           ;设置Undo起始点
      (setq scr (GetRandFunction))
      ;;一些初始化工作--------------------------------------------------
      (setq pts (reverse pts))                                          ;点集反转
      ;(setq pts (mapcar (function (lambda (x) (trans x 1 0))) pts))   ;把点集转化到世界坐标系
      (if pIn
      (setq pIn (trans pIn 1 0)
            dlt (det (car pts) (cadr pts) pIn)                        ;右手法则
      )
      )                                                
      (if (> dlt 0)                                                   ;通过右手法则判断偏移方向
      (setq dist1 (* size 0.5)
            dist2 size
      )
      (setq dist1 (* size -0.5)
            dist2 (- size)
      )
      )

      ;;首先构建衣柜的外轮廓和中心线------------------------------------
      (setq lst1 (OffsetPts pts dist1 nil))                           ;衣柜的中心线点
      (setq lst2 (OffsetPts pts dist2 nil))
      (setq lst2 (append pts (reverse lst2)))                           ;衣柜的外轮廓点
      
      (setq Cur1 (make-Poly lst1 nil))                                  ;画衣柜的中心线
      (setq Cur2 (make-Poly lst2 T))                                    ;画衣柜的中心线
      (setq Obj1 (vlax-ename->vla-object Cur1))
      (setq Obj2 (vlax-ename->vla-object Cur2))

      (setq lst3 (OffsetPts lst2 (* (sign dist1) 50) T))
      (setq Cur3 (make-Poly lst3 T))
      (setq obj3 (vlax-ename->vla-object Cur3))

      (setq lst(list obj1 obj2 obj3))

      (setq Objs (Make-clothes-hanger))                                 ;画衣架
      (setq dist 0.0)
      (setq sLen (vla-get-length Obj1))                                 ;中心线长度
      (setq ang1 (/ pi 0.1 180))                                        ;摆动幅度在10度左右
      (setq ang2 (- ang1))
      (while (< dist sLen)
      (setq pnt (vlax-curve-getPointAtDist Obj1 dist))                ;衣架的定位点
      (setq par (vlax-curve-getParamAtDist Obj1 dist))
      (setq Vec (vlax-curve-getFirstDeriv Obj1 par))                  ;衣架的水平方向
      (setq ang (angle '(0 0 0) Vec))
      (setq ang (+ ang (Rand scr ang1 ang2)))                         ;衣架的旋转角度
      (setq pIn (vlax-curve-getPointAtParam obj1 (fix (+ 0.5 par))));转点
      (if (>= (distance pnt pIn) 300)                                 ;如果与转点距离大于300
          (Copy-and-tranformby Objs pnt ang)                            ;拷贝原点处衣架并变换
      )      
      (setq dist (+ dist (Rand scr 80 300)))                        ;步进到下一点(100,300)这两个数值可自调
      )
      (mapcar 'vla-erase Objs)                                          ;把原点处衣架删除
      (makeGroup Doc Lst)
      (and scr (vlax-release-object scr))                               ;释放脚本实例
      (vla-EndUndoMark doc)                                             ;设置Undo终止点
      (vlax-release-object doc)
    )
)
(redraw)                                                            ;重画一下,消除Grdraw的痕迹
(command "color" oldcolor)   ;设置为原有颜色
;; (setvar "cecolor" "bylayer");设置颜色随层
(setvar "clayer" mylayer)
(princ)                                                               ;静默退出
)
(defun sign (x)
(if (< x 0) -1 1)
)

;;;画线段
(defun Make-Line (p q)
(entmakeX (list (cons 0 "LINE") (cons 10 p) (cons 11 q)))
)

;;;绘制多段线
(defun Make-Poly (pp isClosed / C)
;;;;;;;;;;;;设置画线层
(if (= (tblsearch "layer" "0-PM-固定家具") nil)
    (Command "-layer" "m" "0-PM-固定家具" "c" 251 "" "")
    (Command "-layer" "t" "0-PM-固定家具" "")
)
(setvar "clayer" "0-PM-固定家具")
(if isClosed
    (setq C 1)
    (setq C 0)
)
(entmakeX                                                             ;画凸包
    (append
      (list
      (cons 0 "LWPOLYLINE")
      (cons 100 "AcDbEntity")
      (cons 100 "AcDbPolyline")
      (cons 90 (length pp))                                           ;顶点个数
      (cons 70 C)                                                   ;闭合的
      )
      (mapcar
        (function
          (lambda (x)
          (cons 10 (reverse (cdr (reverse (trans x 1 0)))))
          )
        )
        pp
      )                                                                   ;多段线顶点
    )
)
)

;;;画衣架
(defun Make-clothes-hanger (/)
(mapcar
    (function (lambda (p q /) (VLAX-ENAME->VLA-OBJECT (make-line p q))))
    '((-17.5 -225.) (+17.5 -225.) (-35.0 -210.) (-35.0 +210.))
    '((-17.5 +225.) (+17.5 +225.) (+35.0 -210.) (+35.0 +210.))
)
)

;;;拷贝原点处的物体并变换
(defun Copy-and-tranformby (Objs pnt Ang / newObj)
(foreach obj Objs
    (setq NewObj (vla-copy obj))
    (vla-move NewObj (vlax-3d-point '(0 0 0)) (vlax-3d-point pnt))
    (vla-rotate NewObj (vlax-3d-point pnt) Ang)
    (setq lst (cons NewObj lst))
)
)

;;;最后做成组
(defun MakeGroup (Doc objLst / Groups sGroup oGroup aBound eArray)
(setq Groups (vla-get-groups doc))
(setq sGroup (getvar "cdate"))
(setq sGroup (rtos (* 1e9 (- sGroup (fix sGroup))) 2 0))
(setq oGroup (vla-add Groups (strcat "YG" sGroup)))
(setq aBound (cons 0(1- (length objLst))))
(setq eArray (vlax-make-safearray vlax-vbObject aBound))
(vlax-safearray-fill eArray objLst)
(vla-AppendItems oGroup eArray)
)

;;;偏移点集(没用vla-offset)
;;;此函数可以扩展,为以后的编程准备
(defun OffsetPts (pts d isClosed / AN1 AN2 CNT HPI LST PN1 PN2 PN3 PN4 PNT PPP PT1 PT2 PT3 P12)
(setq ppp pts)
(setq cnt (length ppp))
(cond
    ( (>= cnt 2)
      (setq hPi (/ Pi 2))
   
      (setq pt1 (car ppp))
      (setq pt2 (cadr ppp))
   
      (setq an1 (angle pt1 pt2))
      (setq pn1 (polar pt1 (+ an1 hPi) d))
      (setq pn2 (polar pt2 (+ an1 hPi) d))
   
      (setq pn4 pn2)

      (setq lst (list pn1))
      (if isClosed
      (setq ppp (append pts (list (car pts)))
            p12 (list pn1 pn2)
      )
      )
      (while (caddr ppp)
      (setq pt1 (car ppp))
      (setq pt2 (cadr ppp))
      (setq pt3 (caddr ppp))
   
      (setq an1 (angle pt1 pt2))
      (setq pn1 (polar pt1 (+ an1 hPi) d))
      (setq pn2 (polar pt2 (+ an1 hPi) d))

      (setq an2 (angle pt2 pt3))
      (setq pn3 (polar pt2 (+ an2 hPi) d))
      (setq pn4 (polar pt3 (+ an2 hPi) d))

      (setq pnt (inters pn1 pn2 pn3 pn4 nil))
      (andpnt (setq lst (cons pnt lst)))
      (setq ppp (cdr ppp))
      )
      (if isClosed
      (setq lst (cdr (reverse lst))
            pnt (inters pn3 pn4 (car p12) (cadr p12) nil)
            lst (cons pnt lst)
      )
      (setq lst (cons pn4 lst)
            lst (reverse lst)
      )
      )
      (vl-remove nil lst)
    )
)
)
;;;===============
;;;行列式,判别法则
;;;===============
(defun det (p1 p2 p3 / x1 y1)
(setq x1 (car p1)
      y1 (cadr p1)
)
(- (* (- (car p2) x1) (- (cadr p3) y1))
   (* (- (car p3) x1) (- (cadr p2) y1))
)
)

;;;---------------------------------------------------------------------
;;;Definine Rand()--which one is better? I don't know.               
;;;---------------------------------------------------------------------
(defun GetRandFunction(/ scr str)
(setq scr (vlax-create-object "ScriptControl"))                     ;Create a script
(if scr
    (progn
      (vlax-put scr 'Language "VBS")
      (setq str "Randomize\n
                Function Rand(x,y)\n
                Rand=x+Rnd*(y-x)\n
                End Function"
      )                                                               ;for randomize some features
      (vlax-invoke Scr 'ExecuteStatement str)                           ;Execute script
      (defun Rand (scr nMin nMax)                                       ;Rand function
      (vlax-invoke scr 'run "Rand" nMin nMax)
      )
    )
    ;;;rand function-some code from Le,--thanks.
    (defun Rand (Option nMin nMax / seed)
      (setq seed (getvar "USERR4"))
      (if (= seed 0.)
      (setq seed (getvar "TDUSRTIMER")
            seed (- seed (fix seed))
            seed (rem (* seed 86400) 1)
      )
      )
      (setq seed (rem (+ (* seed 15625.7) 0.21137152) 1))
      (setvar "USERR4" seed)
      (+ nMin (* seed (- nMax nMin)))
    )
)
scr
)


;;;;;;;;;;;柜子平面
;坛子里找个简单代码,类似达到效果
(defun c:SG ( / _line )
(defun *error* (msg)
(setvar "cecolor""bylayer") ;_ 恢复颜色随层;
(setvar "clayer" mylayer)   ;恢复原有图层
(princ "错误信息: ")
(princ msg)      ;_ 打印错误信息
(princ)         
)
(setvar "measurement" 0)   ; 设置公制单位
(setvar "cmdecho" 0)         ; 关闭命令响应
(setvar "hpassoc" 0)          ;设置填充时不关联
(setq mylayer (getvar "clayer"))    ;保存当前层
(setq oldcolor (getvar "cecolor"))   ;保存原有颜色

(defun _line (lst)
(if (= (tblsearch "layer" "0-PM-固定家具") nil)
    (Command "-layer" "m" "0-PM-固定家具" "c" 251 "" "")
    (Command "-layer" "t" "0-PM-固定家具" "")
)
(setvar "clayer" "0-PM-固定家具")
    (mapcar '(lambda (a b)(entmakex (list '(0 . "LINE") (cons 10 a) (cons 11 b)))) lst (cdr lst))
)
(while (and (setq n (Cond ((getint(strcat "\n等分数["(itoa(setq n(Cond ( n )( 5 ))))"] ")))( n )))
            (setq p1 (getpoint "\n第一角点 :"))
            (setq p2 (getcorner p1 "\n另一角点 :"))
         )
    (setq dx (abs (- (car p2) (car p1)))
          dy (abs (- (cadr p2) (cadr p1)))
    )
    (setq ptm (list (min (car p1) (car p2)) (min (cadr p1) (cadr p2)))
          p2(list (max (car p1) (car p2)) (max (cadr p1) (cadr p2)))
          p1ptm
    )
    (if      (> dx dy)
      (progn
      (setq dd (/ dx n))
      (repeat      n
          (setq      p3 (polar p1 0 dd)
                p4 (polar p1 (/ pi 2) dy)
                p5 (polar p4 0 dd)
          )
          (_LINE (list p1 p3 p4 p5 p1 p4))
          (setq p1 p3)
      )
      )
      (progn
      (setq dd (/ dy n))
      (repeat      n
          (setq      p3 (polar p1 (/ pi 2) dd)
                p4 (polar p1 0 dx)
                p5 (polar p3 0 dx)
          )
          (_LINE (list p1 p3 p4 p5 p1 p4))
          (setq p1 p3)
      )
      )
    )
    (_LINE (list p3 p5))
)

(command "color" oldcolor)   ;设置为原有颜色
;;(setvar "cecolor" "bylayer");设置颜色随层

;;(setvar "color" "251");设置颜色随层
(setvar "clayer" mylayer)
(princ)
)

stonedesign 发表于 2022-6-22 18:52:56

感谢:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P:P

lxl217114 发表于 2022-6-23 12:33:09

这个必须点赞了

注册 发表于 2022-6-23 13:11:58

这个必须点赞了--

czb203 发表于 2022-6-23 17:07:34


这个必须点赞了

999999 发表于 2022-6-23 21:23:09

这个必须点赞了

趣意人生 发表于 2022-6-23 22:38:34


这个必须点赞了

stonedesign 发表于 2022-6-24 12:22:43

小毛草 发表于 2022-6-24 11:11
我这也是YG的修改版,不过设置了出入了默认图层

呵呵,厉害就是需要这个,衣柜没啥问题了,但是那个个柜子平面不这么好用 不能设置一侧的距离,随意2点画的,不是很好用,大佬能改下?改成图片的效果

stonedesign 发表于 2022-6-24 12:31:52

小毛草 发表于 2022-6-24 11:11
我这也是YG的修改版,不过设置了出入了默认图层

最高柜子平面也能和衣柜一样设置一侧尺寸
页: [1] 2
查看完整版本: 修改 原【高飞鸟】] 【飞鸟集】画衣柜的LISP程序的画平面衣柜