林霄云 发表于 2014-2-13 00:15:20

拉筋箍筋符号源码解析与测试(支持UCS、形式切换、智能比例、统一命令)

本帖最后由 林霄云 于 2014-2-19 15:37 编辑

拉筋箍筋(支持UCS、形式切换、智能比例、统一命令)
原版本详见,拉筋符号源码解析与测试(详解算法,支持UCS、形式切换)
http://bbs.mjtd.com/forum.php?mo ... 170&fromuid=7303580
主函数调用
主要修改,增加点筋点数判断,当大于2时,采用箍筋命令(if ( >total_pt 2)
(progn
(setq num-pt 0)
(setq ss (ReinforceBar_G pt_list num-pt))

(prompt "\n左击切换箍筋形式")

      (while (and (setq ptr (grread t 15 2))
            (not (and (= 2 (car ptr)); 键盘事件
                  (or (= 13 (cadr ptr)) (= 32 (cadr ptr))) ;_Enter Space
            ))
             (not (or (= (car ptr) 11) (= (car ptr) 25)));_Mouse Right button
                        )   
               ; (redraw)
      (cond ((= (car ptr) 3);_Mouse Left button
      (setq num-pt (1+ num-pt)) ;切换标志,删除,生成
      (ss_delete ss)
      (setq ss (ReinforceBar_G pt_list num-pt))
         ))

)

);progn
);if其中子函数ReinforceBar_G,为绘制箍筋。(defun ReinforceBar_G(ptlistnum-pt / in-anglist ss pt_list h d en self-ang pt0 pt1 pt2 pt1a pt2a)
;函数ReinforceBar 生成箍筋,参数ptlist 点表,flag-num 箍筋弯钩位置。生成箍筋
;Desiged by 林霄云 2014年2月12日本箍筋符号绘制的核心代码为,一,给定点表ptlist,形成封闭的多段线;二,求得多段线各个内角,以便箍筋弯钩的插入。(defun con_ptlist (ptlist / x-list x y)
……
(defun con_anglist(ptlist / in-anglist total i x y )
……函数列表;;MAKE_LAYER
;;MAKE_STYLE
;;EN_OFFSET
;;SS2ENLIST
;;GET_PLINE_VERTEX
;;GET_MIDPOINT
;;GET_BAR_PTLIST
;;CON_PTLIST
;;MOD_I
;;CON_ANGLIST
;;MAKE_PLINE
;;MAKE_TEXT
;;SS_DELETE
;;REINFORCEBAR
;;REINFORCEBAR_G
;;C:RB 结果:详见附图
实现了拉筋箍筋的大一统,其满足结构专业应用需求。
异性箍筋的绘制;箍筋弯钩的正确性与可切换。拉筋的正确性与可切换。支持UCS。支持比例切换。

补充代码解析
con_ptlist函数,并非用凸包算法,但是取一种可被理解的一般使用可以接受的便捷方式。凸包算法。(defun con_ptlist (ptlist / x-list pt-first ang-list index-list out-list out-list1 i x y)
;函数con_ptlist,参数ptlist 点表。返回值,按逆时针排序好的,可生成pline的点表;但不保证是凸边形。
;Desiged by 林霄云 2014年2月12日

;取最右端点,当多个时,取右上端点,使用两次vl-sort就行。g版,在凸包算法中,定了复杂的lambda。
(setq x-list (vl-sort
                   (vl-sort ptlist '(lambda (x y) (< (cadr x) (cadr y)))) ; y坐标较小者在前面
                   '(lambda (x y) (< (car x) (car y)))                ; x坐标较小者在前面
               ))
(setqpt-first (last x-list));最后一个,为x的较大者,且y的较大者。   

;取角度list,然后进行极角排序,如果是凸包,极角相同时,得去掉距离近的点。此处并不处理。
(setq x-list (vl-remove pt-first x-list) ) ;去掉最后一个元素,因为其为起始点。
; (princ (vl-princ-to-string x-list))
(setq ang-list (mapcar '(lambda (x) (anglept-first x)) x-list));ang-list 与 x-list 有一一对应关系。(angle (setq pt1 (getpoint))(getpoint pt1))
; (princ (vl-princ-to-string ang-list))
(setq index-list (vl-sort-i ang-list '< ));最好不要有三点共线
; (princ (vl-princ-to-string index-list))
;生成点表
(setq i 0)
(setq out-list nil)
(repeat (setq total (length x-list))
(setq out-list (cons (nth (nth i index-list ) x-list) out-list))
(setq i (1+ i))
);repeat
;(princ (vl-princ-to-string (reverse out-list)))

;对于结束边要逆序。处理共线问题。
(setq i 1)
(setq ang-last (angle pt-first (car out-list)))
(while (= ang-last (angle pt-first (nth i out-list)))
(setq i (1+ i))
);while
;退出循环,i 保存了结束边点数(除了pt-first)。大于1时,需手工逆序;否则用reverse逆序。
(if (> i 1)
(progn
(setq out-list1 nil)
(setq ii 1)
(repeat total
(if (<= ii i)
(setq out-list1 (cons (nth (- i ii) out-list) out-list1))
(setq out-list1 (cons (nth(- ii 1 ) out-list) out-list1))
);if
(setq ii (1+ ii))
)

(cons pt-first out-list1); 人工逆序。
);progn
(cons pt-first (reverse out-list));
   );if
);defun为了定位箍筋弯钩直段,内角平分线作为基准线。对于内角列表,巧妙的使用rem函数,去掉正负性。欢迎指点。(defun con_anglist(ptlist / in-anglist total i x y )
;函数con_anglist,参数ptlist 点表。返回值,点表形成的多边形内角。
;Desiged by 林霄云 2014年2月12日
    (setq i 0)
(setq in-anglist '())
(setq total (length ptlist))
    (repeat total
(setq in-anglist (cons (rem (+   (setq test1 (angle (nth i ptlist) (nth (mod_i (1- i) total) ptlist)))
                (-(setq test2 (angle (nth i ptlist) (nth (mod_i (1+ i) total) ptlist))))
                (* 2 pi))
                (* 2 pi))
            in-anglist))
       (setq i (1+ i))
    )
   
(reverse in-anglist)
)由于需要循环性,所以定义了mod_i函数,对角标值进行修正(defun mod_i (i num)
;函数mod_i,返回值,对i进行调整,使其形成在0 num-1内循环。要求-num-1 <i< 2*num
;Desiged by 林霄云 2014年2月12日
(if (< i 0) (setq i (+ i num) ) (if (>= i num) (setq i (- i num)) i ))
)定义了一个简单的多段线偏移en_offset(defun en_offset(en d d-flag / en-obj)
(setq en-obj (vlax-ename->vla-object en))
(vla-offset en-obj d)
(if d-flag (entdel en));d-flag :delete source flag
)定义了一个简单的多段线生成函数make_pline,设置了测试代码。(defun make_pline(ptlist layername c-flag / ucszdirtemp-list i in-anglist)
;函数make_pline,参数ptlist 点表,layername 图层名,c-flag闭合标识 t为闭合。返回值,点表形成的多边形。为简单的pline,不支持圆弧。
;Desiged by 林霄云 2014年2月12日

(if c-flag (setq c-flag 1) (setq c-flag 0))
(setq ucszdir (trans '(0 0 1) 1 0 T ));生成OCS法向量

(setq temp-list(mapcar '(lambda(x)(cons 10 x)) ptlist ) )

(setq temp-list (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline")
                (cons 210 ucszdir)(cons 8 layername)(cons 90 (length ptlist)) (cons 70 c-flag)(cons 43 0))
      temp-list ) )
;多线
(EntMakex temp-list) ;返回ename
);defun 定义了简单的图层生成函数make_layer(defun make_layer(layername code-6 code-62 code-370)
(if (null (tblobjname "LAYER" layername) )
(entmake (list '(0 . "LAYER")
      '(100 . "AcDbSymbolTableRecord")
      '(100 . "AcDbLayerTableRecord")
      '(70 . 0)
    (cons 2 layername)
      (cons 6 code-6)   ;线型Continuous
       (cons 62 code-62);颜色
    (cons 370 code-370);线宽,整数,50表示0.50 9表示0.09
      )
    )
);if
);defun等等,

广易精通 发表于 2021-12-14 16:22:06

好程序,再加上设置线宽更完美了,code-370我还不会

阿猪蛋 发表于 2024-6-11 09:17:08

支持一下,为结构设计减少点工作量。

429014673 发表于 2014-2-13 09:18:13

牛,可惜用不起

林霄云 发表于 2014-2-13 09:43:00

429014673 发表于 2014-2-13 09:18 static/image/common/back.gif
牛,可惜用不起

源代码还在整理,由于定义了多个子函数,为了其具有通用性,需要点时间调试。
回头这个,都免费。

yfs719 发表于 2014-2-13 09:58:22

支持一下,为结构设计减少点工作量。

chleiwu 发表于 2014-2-13 10:40:34

异性箍筋的绘制,太实用了

myjping 发表于 2014-2-13 11:38:01

不错,用心了

zhl0123321 发表于 2014-2-13 11:38:25

能不能修改下钢筋图层可以自定义,钢筋宽度可以自定义

xyp1964 发表于 2014-2-13 12:59:18

这样的有木有?

林霄云 发表于 2014-2-13 14:41:35

zhl0123321 发表于 2014-2-13 11:38 static/image/common/back.gif
能不能修改下钢筋图层可以自定义,钢筋宽度可以自定义

可以考虑,提供一个接口函数,让用户设置,并保存。

林霄云 发表于 2014-2-13 14:46:23

xyp1964 发表于 2014-2-13 12:59 static/image/common/back.gif
这样的有木有?

可以分次实现。
在选择点筋后,生成的点筋点表,过滤掉,使内角大于或等于pi的点。
但是,得多次选择。
页: [1] 2 3 4
查看完整版本: 拉筋箍筋符号源码解析与测试(支持UCS、形式切换、智能比例、统一命令)