明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2866|回复: 5

[源码] 基于中点的文字反转v2源代码解析及测试 (支持块内文字 UCS)

[复制链接]
发表于 2014-1-5 23:43 | 显示全部楼层 |阅读模式
本帖最后由 林霄云 于 2014-1-6 19:08 编辑

文字基于自身中点反转——扩展对块内文字的操作
原版本文详见文字绕自身中点反转 支持UCShttp://bbs.mjtd.com/forum.php?mo ... 909&fromuid=7303580
强调更为广泛的应用,本文对文字反转进行扩展,使之对块内文字亦有效
思路:主要涉及到块内文字的操作
1,entsel选择对象,取ent和pt ,判断类型为text,直接调用反转。为insert时,取其所有text类型的子对象
2,对所有子对象,执行get-textbox,即取子对象四个角点,判断pt是否在四个角点形成的多边形内(此处比较都用默认的wcs (ocs)——即受限的UCS)。如果是,则对该对象执行反转。(默认点选文字重叠区时,重叠的文字都会反转)

流程:
1,主函数ART (Advanced Rotate Text) 进行选择对象,判断对象,当对象类型为TEXT时,调用反转函数rotate-text(en),否则继续判断,当为INSERT时,取块内类型为TEXT的ename列表。然后对每个进行判断是否单击点在其textbox中,如果是则,反转。
2,辅助函数有Rotate-text,get-textbox,inorout(判断点是否在多边形内,在代码里有感谢作者),AllEntityInBlk(取块内所有TEXT对象,在代码里有感谢原作者,我加入过滤条件)
源代码解析及测试如下
  1. ;1,entsel选择对象,取ent和pt ,判断类型为text,直接调用反转。为insert时,取其所有text类型的子对象
  2. ;2,对所有子对象,执行get-textbox,取子对象四个角点,判断pt是否在四个角点形成的多边形内(此处比较都用默认的wcs (ocs))。如果是,则对该对象执行反转,退出循环。
  3. (defun C:ART () ;Advanced Rotate Text
  4. ;函数ART Advanced Rotate Text 文字绕自身中点反转,version 2.0 支持块内文字 。
  5. ;Desiged by 林霄云 2014年1月5日
  6. (princ "\n选择需要反转的文字:");提示不需要进入循环

  7. (while (setq enl  (entsel)) ;循环操作,方便测试
  8.   (setq en (car enl)
  9.     en-pt (trans (cadr enl) 1 0) ;取单选的对象及其点,需要从UCS转WCS。
  10.     ent (entget en)
  11.     flag nil)
  12.   (setq typ (cdr (assoc 0 ent)))
  13.    (if (= typ "TEXT") ;如果判断是TEXT,则直接Rotate it。否则如果是块,则找到块内的文字对象列表 tn-list:text name list,对每一个text ename 进行判断。如果满足点在textbox里,则旋转之。
  14.    (rotate-text en)
  15.    (if (= typ "INSERT")
  16.    (progn
  17.    (setq tn-list (ALLENTITYINBLK en)) ;成功返回
  18.    (foreach entn  tn-list
  19.    (setq pt-list (get-textbox entn ))
  20.     (setq flag (inorout pt-list en-pt))
  21.    
  22.    (if flag
  23.     (progn
  24.   (rotate-text entn)

  25.   ;更新所有块,感谢llsheng_73的思路
  26.   ;(entupd entn)
  27.   
  28.   (setq i -1)
  29.   (setq ss (ssget "X" (list (cons 2  (cdr (assoc 2 ent)) ) ) ));(entupd en) ;(entmod ent);需要更新块。但不会更新所有块。唉。
  30.   (while (setq s1 (ssname ss (setq i (1+ i))))
  31.   (entupd s1))
  32.   );progn
  33.   )
  34.    );foreach
  35.    
  36.   
  37.    );progn
  38.    );if
  39.   );if
  40.       
  41. );while 加入循环
  42. (princ)
  43. );defun
  44. (princ "\nRTT 文字反转命令加载成功\nDesigned by 林霄云 2014年1月4日")
  45. (princ)
  1. ; 函数AllEntityInBlk  (blk)
  2. (defun AllEntityInBlk (blk / bn blkdef e typ el ) ;感谢 mjtd之 jxphklibin
  3. (setq bn     (cdr (assoc 2 (entget blk)));先找块名,bn,然后更具块找出其ename。定义的块。必然是全改的。如果不想全改,就是炸开咯。
  4.     blkdef (tblobjname "block" bn)
  5.   )   
  6.   (while (setq e (entnext blkdef))
  7.     (setq typ (cdr (assoc 0 (entget e))))
  8.   
  9.     (if (= typ "TEXT")
  10.   (setq el (cons e el)) ;过滤条件:只取 TEXT ,顺序不重要。
  11.   (if (= typ "INSERT")
  12.       (setq el (append (AllEntityInBlk e) el));list 级别的操作 el: entity list
  13.       ;(setq el (cons e el)) ;顺序不重要。
  14.     );if INSERT

  15.   );if TEXT
  16.     (setq blkdef e) ;entnext 条件
  17.   )
  18.   el
  19. )
  1. ;函数get-textbox(en)
  2. (defun get-textbox (en /  ang-self ang en ent pt0-ll pt0-tr pt-ins pt-2 pt-3 pt-4 pt-list x y ) ;获取文本四角点 Get Text Box
  3. ;函数get-textbox(en),参数en:entity name 即ename。
  4. ;Desiged by 林霄云 2014年1月4日
  5. (setq ent (entget en))
  6. (setq pt-ins (cdr (assoc 10 ent)))  ;第一对齐点(在 OCS 中)插入点(非UCS下坐标点);支持受限的UCS。
  7. (setq ang (cdr (assoc 50 ent)))    ;a 文字旋转角度 弧度
  8.         
  9. (setq pt-list (textbox ent))    ;取虚拟框
  10. (setq pt0-ll (car pt-list))      ;取左下点
  11. (setq pt0-tr (cadr pt-list))    ;取右上点

  12. (setq box-tr (mapcar '(lambda (x y) (+ x y)) pt0-ll pt0-tr)) ;取对应原点的右上点。

  13. (setq  box-length (car box-tr))
  14. (setq  box-height (cadr box-tr))

  15. (setq ang-self (atan (cadr box-tr) (car box-tr)));取转角,基点为原点。 self-ang花了作者一晚上的时间,因为polar中的角度是从坐标轴开始的。需要加自身转角。
  16.                          ;不用angle函数,angle会投影成UCS。
  17. (setq dis  (distance '(0.0 0.0 0.0) box-tr))
  18. (setq pt-3 (polar pt-ins (+ ang-self ang) dis));此句+ ang-self 表示逆时针(polar正方向)转角ang-self
  19. (setq pt-2 (polar pt-ins  ang box-length))
  20. (setq pt-4 (polar pt-ins (+ ang (*  0.5 pi) ) box-height)) ;此句+0.5pi 表示逆时针(polar正方向)转角90°
  21. ;(command "line" (trans pt-ins 0 1) (trans pt-2 0 1) (trans pt-3 0 1) (trans pt-4 0 1 ) "c") ;trans pt 0 1 wcs 转 ucs ,测试文本外框代码
  22. (list pt-ins pt-2 pt-3 pt-4) ;逆时针顺序,即polar函数规定的正方向

  23. );defun

  24. ;函数rotate-text(en)
  25. (defun rotate-text (en / ag ang-self ang en ent pt0-ll pt0-m pt0-tr pt-ins pt-list x y ) ;文字绕自身中点反转RotaTe Text
  26. ;函数rotate-text(en),参数en:entity name 即ename。
  27. ;Desiged by 林霄云 2014年1月4日

  28. (setq ent (entget en))
  29. (setq pt-ins (cdr (assoc 10 ent)))  ;第一对齐点(在 OCS 中)插入点(非UCS)

  30. (setq ang (cdr (assoc 50 ent)))    ;a 文字旋转角度 弧度(WCS)
  31.         
  32. (setq pt-list (textbox ent))    ;取文本虚拟框
  33. (setq pt0-ll (car pt-list))      ;取左下点
  34. (setq pt0-tr (cadr pt-list))    ;取右上点


  35. (setq te-tr (mapcar '(lambda (x y) (+ x y)) pt0-ll pt0-tr)) ;取对应原点的右上点。

  36. (setq ang-self (atan (cadr te-tr) (car te-tr)));取转角,基点为原点。 self-ang花了作者一晚上的时间,因为polar中的角度是从坐标轴开始的。需要加自身转角。
  37.          
  38. (setq pt-tr (mapcar '(lambda (x y) (+ x y)) te-tr pt-ins));取对应插入点的右上点

  39. ;相对pt-ins,将中点旋转角度ang

  40. (setq dis (* 0.5 (distance pt-ins pt-tr)))           ;取长度
  41. (setq pt0-m (polar pt-ins (+ ang-self ang) dis))
  42. ;;;(command "point" pt0-m)

  43. (setq ag "180")
  44. (vla-rotate
  45.   (vlax-ename->vla-object en)
  46.   (vlax-3d-point pt0-m)
  47.   (angtof ag)
  48. )
  49. );defun
  1. ; 函数 inorout
  2. ;;By Xiao_longxin 明经通道
  3. (defun inorout (pt_list pt / e1 n i j va va_count)
  4.   (setq i  0
  5. va_count 0
  6. n  (length pt_list)
  7. pt_list  (append pt_list (list (car pt_list)))
  8.   )
  9.   (repeat n
  10.     (setq va (- (angle pt (nth i pt_list))
  11.   (angle pt (nth (1+ i) pt_list))
  12.       )
  13.     )
  14.     (cond ((> va pi) (setq va (- va pi)))
  15.    ((< va (* -1 pi)) (setq va (+ va pi)))
  16.     )
  17.     (setq va_count (+ va_count va)
  18.    i    (1+ i)
  19.     )
  20.   )
  21.   (if (< (abs (- (abs va_count) pi)) 0.000001)
  22.     't
  23.     'nil
  24.   )
  25. )
函数inorout作者解析:
  1. ; 函数(inorout pt_list pt)
  2. ; 参数:
  3. ; pt_list:点表
  4. ; pt:所要判断的点
  5. ; 返回值:
  6. ; 如果在点表构成的多边形内,则返回T,否则返回nil。
  7. ; 说明:
  8. ; 有一不规则多边形由点a1(x1,y1)、a2(x2,y2).....an(xn,yn)依次连接而成,如何求证点p(x,y)是在多边形内还是多边形外?
  9. ; 将直线PAi记作ki.将ki旋转到ki+1(令kn+1=k1)的角记为βi(规定逆时针为正,顺时针为负,如果βi大于180就变成βi-360)。
  10. ; 从直观上看有下面的结论
  11. ; 若P在形内,诸β的代数和为360度;
  12. ; 若P在形外,诸β的代数和为0。
复制代码
结论
本代码成功反转文本进行了扩展。阐述了对块内文本进行定位的思路与实践,是对块内对象操作的一次很有益的尝试与应用。(TMA刷块内文字亦可以实现)
稍微修改,可以修正对于块镜像出现的文字问题;选择有问题的块,然后炸开实现文字反转。

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2014-1-7 07:57 | 显示全部楼层
反转的目的何在?
发表于 2014-1-7 10:36 | 显示全部楼层
能不能不能批量更改
 楼主| 发表于 2014-1-7 14:00 | 显示全部楼层
xyp1964 发表于 2014-1-7 07:57
反转的目的何在?

镜像文字,可能位置正确,方向不对,需要反转。有需求。
发表于 2016-3-24 09:53 | 显示全部楼层
林霄云 发表于 2014-1-7 14:00
镜像文字,可能位置正确,方向不对,需要反转。有需求。

顶, 同求,经常遇到。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-2-28 13:27 , Processed in 0.173667 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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