天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 78|回复: 0

画衣柜的LISP程序的画平面衣柜

[复制链接]
  • TA的每日心情
    开心
    2024-8-31 15:58
  • 签到天数: 89 天

    [LV.6]常住居民II

    488

    主题

    207

    回帖

    3366

    积分

    管理员

    积分
    3366
    发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
    [code](vl-load-com)
    (prompt "命令是YG")
    ;;;画衣柜的LISP程序-----------------------------------------------------
    ;;;Copyright Highflybird------------------------------------------------
    ;;;2011.04.30 ----------------------------------------------------------
    (defun c:xr_YG1(/ 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
               )
      (if (< (setq size (getvar "USERR5")) 200.)                            ;初始化衣柜深
        (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 200)
          (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) 18) 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 160))                                        ;摆动幅度在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 60 200)))                          ;步进到下一点(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的痕迹
      (princ)                                                               ;静默退出
    )
    (defun sign (x)
      (if (< x 0) -1 1)
    )
    ;;;出错处理
    (defun *error_msg* (msg)
      (redraw)
      (princ msg)
    )

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

    ;;;绘制多段线
    (defun Make-Poly (pp isClosed / C)
      (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.) (-17.5 -225.) (-17.5 +225.))
        '((-17.5 +225.) (+17.5 +225.) (+17.5 -225.) (+17.5 +225.))
      )
    )

    ;;;拷贝原点处的物体并变换
    (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
    )
    [/code]

     

     

     

     

    画衣柜的LISP程序的画平面衣柜
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池| |网站地图

    GMT+8, 2024-9-8 10:53 , Processed in 0.070977 second(s), 26 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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