【飞鸟集】画衣柜的LISP程序(更新至2014.11.27)
原来的帖子地址:【飞鸟集】画衣柜的LISP程序(更新至2014.11.27)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=86629&fromuid=7328064
(出处: 明经CAD社区)
改了一点点看上去好看点,能力有限。希望有大佬在改下。
网友答: 我这也是YG的修改版,不过设置了出入了默认图层
网友答:
呵呵,厉害就是需要这个,衣柜没啥问题了,但是那个个柜子平面不这么好用 不能设置一侧的距离,随意2点画的,不是很好用,大佬能改下?改成图片的效果网友答: 感谢: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网友答: 这个必须点赞了网友答: 这个必须点赞了--网友答:
这个必须点赞了网友答: 这个必须点赞了
网友答:
这个必须点赞了网友答:
最高柜子平面也能和衣柜一样设置一侧尺寸
原来的帖子地址:【飞鸟集】画衣柜的LISP程序(更新至2014.11.27)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=86629&fromuid=7328064
(出处: 明经CAD社区)
改了一点点看上去好看点,能力有限。希望有大佬在改下。
网友答: 我这也是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 (> (length pts) 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))
- (and pnt (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)))
- p1 ptm
- )
- (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)
- )
小毛草 发表于 2022-6-24 11:11
我这也是YG的修改版,不过设置了出入了默认图层
呵呵,厉害就是需要这个,衣柜没啥问题了,但是那个个柜子平面不这么好用 不能设置一侧的距离,随意2点画的,不是很好用,大佬能改下?改成图片的效果网友答: 感谢: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网友答: 这个必须点赞了网友答: 这个必须点赞了--网友答:
这个必须点赞了网友答: 这个必须点赞了

网友答:
这个必须点赞了网友答:
小毛草 发表于 2022-6-24 11:11
我这也是YG的修改版,不过设置了出入了默认图层
最高柜子平面也能和衣柜一样设置一侧尺寸