明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: alpha223334

[提问] 为什么最近用的文字居中lisp在cad2014中不能用了

[复制链接]
发表于 2019-11-13 16:24:32 | 显示全部楼层
注册 发表于 2019-9-29 08:03
处理好了之后的代码还是不能识别pline

我修改正了,见修改后的代码。
发表于 2019-11-16 19:10:22 | 显示全部楼层
本帖最后由 wudechao 于 2019-11-16 23:01 编辑

;再次修改,缩小scsz搜索范围,加快速度。排除斜线,vla-move比move快10倍
(defun c:wzjz (/ *error* oos en ss n ptm disn diss dise disw date1 xx yy pt-dis dis)
(defun ffg-snearlin (pt ang scsz / scsz ss3 m en3 ent3 ty ent2 ptj lst ang1);增加scsz参数,缩小选择范围
  (vl-load-com)
  (setq ss3 (ssget "f" (list pt (polar pt ang scsz)) '((0 . "LINE,LWPOLYLINE,POLYLINE")))
        lst nil
  )
  (if ss3
   (progn
    (setq m 0)
    (while (setq en3 (ssname ss3 m))
     (setq ent2 (entget en3)
           ty (assoc 0 ent2)
     )
     (if (or
          (= "LWPOLYLINE" (cdr ty))
          (= "POLYLINE" (cdr ty))
         )
      (progn
       (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 (polar pt ang scsz))))
       (setq ent3 (entlast))
       (setq ptj (vlax-invoke (vlax-ename->vla-object en3) 'intersectwith (vlax-ename->vla-object ent3) 0))
       (entdel ent3)
      )
      (progn
       (setq ptj (trans (vlax-curve-getclosestpointto en3 (trans pt 1 0) t) 0 1))
      )
     )
     (setq ang1 (angle pt ptj));以下代码是取线段角度,剔除斜线
     (if (equal ang1 (* 2 pi) 0.087266);355~360之间的角度设置为0,否则无法判断比如359.99度与0度是否相等
      (setq ang1 (* 2 pi))
     )
     (setq ang1 (rem ang1 (* 2 pi)))
     (if (equal ang1 ang 0.087266);误差5度
      (setq lst (cons (list (distance pt ptj) en3) lst))
     )
     (setq m (1+ m))
    )
    (apply
     'min
     (mapcar
      'car
      lst
     )
    )
   )
  )
)
(defun ffg-txtmpt (en2 / ent4 box ls pt4 ang4 pt-dis2)
  (setq ent4 (entget en2)
        box (textbox ent4)
        ang4 (cdr (assoc 50 ent4))
        ls (mapcar
            '(lambda (a b)
              (* 0.5 (+ a b))
             )
            (car box)
            (cadr box)
           )
        pt4 (cdr (assoc 10 ent4))
  )
  (setq pt-dis2 (list (polar pt4 (+ ang4 (angle '(0 0) ls)) (distance '(0 0) ls)) (abs (distance (car box) (cadr box)))));增加字宽度,为缩小搜索范围做准备
)
(vl-load-com)
(setvar "cmdecho" 0)
(defun *error* (msg)
  (if oos
   (setvar "osmode" oos)
  )
  (setvar "cmdecho" 1)
)
(command "undo" "begin")
(setq oos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "TEXT,TCH_TEXT,ATTRIB")))
       n 0
       date1 (getvar "millisecs")
)
(while (setq en (ssname ss n))
  (setq pt-dis (ffg-txtmpt en))
  (setq ptm (trans (car pt-dis) 0 1)
        dis (cadr pt-dis)
        dise (ffg-snearlin ptm 0.0 (* 2 dis))
        disn (ffg-snearlin ptm (* 0.5 pi) (* 1 dis))
        disw (ffg-snearlin ptm (* 1.0 pi) (* 2 dis))
        diss (ffg-snearlin ptm (* 1.5 pi) (* 1 dis))
  )
  (if (and
       disn
       diss
      )
   (setq yy (* 0.5 (- disn diss)))
   (setq yy 0)
  )
  (if (and
       dise
       disw
      )
   (setq xx (* 0.5 (- dise disw)))
   (setq xx 0)
  )
  (or
   (= 0 xx yy)
  (vla-move (vlax-ename->vla-object en) (vlax-3D-point ptm) (vlax-3D-point (list (+ (car ptm) xx) (+ (cadr ptm) yy))))
  );vla-move比move快10倍
  (setq n (1+ n))
)
(princ (strcat "\n耗时\"" (rtos (/ (- (getvar "millisecs") date1) 1000.000) 2 3) "\"秒"))
(command "undo" "end")
(setvar "osmode" oos)
(setvar "cmdecho" 1)
(princ)
)
发表于 2019-11-16 20:14:36 | 显示全部楼层
你这个会出现参数类型错误:二维/三维点
发表于 2019-11-16 20:23:07 | 显示全部楼层
本帖最后由 wudechao 于 2019-11-16 20:28 编辑
烟盒迷唇 发表于 2019-11-16 20:14
你这个会出现参数类型错误:二维/三维点

你根据实际表格,适当修改一下这个dis的倍数,这个距离如果太大,速度慢,距离太小,可能会找不到表格的边。
        dise (ffg-snearlin ptm 0.0 (* 1 dis))
        disn (ffg-snearlin ptm (* 0.5 pi) (* 3 dis))
        disw (ffg-snearlin ptm (* 1.0 pi) (* 1 dis))
        diss (ffg-snearlin ptm (* 1.5 pi) (* 3 dis))
发表于 2019-11-16 20:33:22 | 显示全部楼层
wudechao 发表于 2019-11-16 20:23
你根据实际表格,适当修改一下这个dis的倍数,这个距离如果太大,速度慢,距离太小,可能会找不到表格的 ...

不是这个DIS的问题吧,是提示这句话有问题:(setq ang1 (angle pt ptj)),二维/三维点
发表于 2019-11-16 22:20:55 | 显示全部楼层
本帖最后由 wudechao 于 2019-11-16 23:30 编辑
烟盒迷唇 发表于 2019-11-16 20:33
不是这个DIS的问题吧,是提示这句话有问题:(setq ang1 (angle pt ptj)),二维/三维点

我的cad2014 win7 x64系统。我的没有问题。你的图可能是天正的格式吧?或者你的CAD不是完整版本,精简版本。
发表于 2019-11-16 23:21:44 | 显示全部楼层
本帖最后由 wudechao 于 2025-12-10 13:06 编辑

;文字表格秒居中(交叉线判断版),终结版本(经多次测试,比填充方式找中点约快215倍,2020.2.18修改 ffg-txtmpt函数,支持mtext和TCH_mtext,引进变量k目的是加快处理表格速度,根据实际表格,适当修改一下这个K的初始值1和增大倍数1.5,K*dis的多少倍能碰到表格边框,k*dis逐渐增大搜索)
(defun c:wzjz (/ *error* oos en ss n ptm disn diss dise disw date1 xx yy pt-dis dis zg time)
  (defun ffg-near-point-line (pt ang scsz / ss3 m en3 ent3 ty ent2 ptj lst ang1 dis-min);;求一个点沿某个方向最近的直线和距离(scsz为距离,为加快判断速度而设置)
    (vl-load-com)
    (setq ss3 (ssget "f" (list pt (polar pt ang scsz)) (list '(-4 . "<AND") '(0 . "LINE,LWPOLYLINE,POLYLINE") '(8 . "~DEFPOINTS")
                                 '(8 . "~校对") '(-4 . "AND>")
                               )
          )
      lst '()
    )
    (if ss3
      (progn
    (setq m 0)
    (while (setq en3 (ssname ss3 m))
      (setq ent2 (entget en3)
        ty (assoc 0 ent2)
      )
      (if (or
        (= "LWPOLYLINE" (cdr ty))
        (= "POLYLINE" (cdr ty))
          )
        (progn
          (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 (polar pt ang scsz))))
          (setq ent3 (entlast))
          (setq ptj (vlax-invoke (vlax-ename->vla-object en3) 'intersectwith (vlax-ename->vla-object ent3) 0));返回曲线上与直线相交点
          (entdel ent3)
          (if (> (length ptj) 3);多于两个相交点
        (setq ptj (list (car ptj) (cadr ptj) (caddr ptj)))
          )
        )
        (progn
          (setq ptj (trans (vlax-curve-getclosestpointto en3 (trans pt 1 0) t) 0 1));返回曲线上离指定点最近的点(在 ucs 上)
        );_结束progn
      );_结束if
      (if ptj
        (progn
          (setq ang1 (angle pt ptj));以下代码是取线段角度,剔除斜线
          (if (equal ang1 (* 2 pi) 0.087266);355~360之间的角度设置为0,否则无法判断比如359.99度与0度是否相等
        (setq ang1 (* 2 pi))
          )
          (setq ang1 (rem ang1 (* 2 pi)));对360度取余
          (if (equal ang1 ang 0.087266);误差5度
        (setq lst (cons (list (distance pt ptj) en3) lst));距离和线组合的表
          )
        )
        nil;没有相交点
      )
      (setq m (1+ m))
    );_结束while
    (setq dis-min (apply
            'min
            (mapcar
              'car
              lst
            )
              )
    )
    (assoc dis-min lst)
      );_结束progn
      nil;没有相交点
    )
  );_结束defun
  (defun ffg-txt-mid-ptlong (en2 / ent4 box ls pt4 ang4 pt-dis2 ty p1 p2 kuandu gaodu pt0 bbox);;;求文字的中心点和字对角线距离
    (setq ent4 (entget en2))
    (setq ty (cdr (assoc 0 (entget en2))))
    (cond
      ((or
     (= ty "TCH_MTEXT")
     (= ty "TCH_TEXT")
       )
    (setq bbox (vla-getboundingbox (vlax-ename->vla-object en2) 'p1 'p2))
    (setq p1 (vlax-safearray->list p1)
          p2 (vlax-safearray->list p2)
    )
    (setq midpt (mapcar
              '(lambda (a b)
             (* 0.5 (+ a b))
               )
              p1
              p2
            )
    )
    (setq pt-dis2 (list (trans midpt 0 1) (abs (distance p1 p2))))
      );_结束
      ((= ty "MTEXT")
    (setq kuandu (cdr (assoc 42 (entget en2))))
    (setq gaodu (cdr (assoc 43 (entget en2))))
    (setq pt0 (cdr (assoc 10 (entget en2))))
    (setq bbox (vla-getboundingbox (vlax-ename->vla-object en2) 'p1 'p2))
    (setq p1 (vlax-safearray->list p1)
          p2 (vlax-safearray->list p2)
    )
    (if (< (- (car pt0) (car p2)) 0)
      (setq p2 (list (+ (car p1) kuandu) (cadr p2)))
      (setq p2 (list (- (car p1) kuandu) (cadr p2)))
    )
    (if (> (- (cadr pt0) (cadr p1)) 0)
      (setq p1 (list (car p1) (- (cadr p2) gaodu)))
      (setq p1 (list (car p1) (+ (cadr p2) gaodu)))
    )
    (setq midpt (mapcar
              '(lambda (a b)
             (* 0.5 (+ a b))
               )
              p1
              p2
            )
    )
    (setq pt-dis2 (list (trans midpt 0 1) (abs (distance p1 p2))))
      );_结束
      ((or
     (= ty "TEXT")
     (= ty "ATTRIB")
       )
    (setq box (textbox ent4)
          ang4 (cdr (assoc 50 ent4))
          ls (mapcar
           '(lambda (a b)
              (* 0.5 (+ a b))
            )
           (car box)
           (cadr box)
         )
          pt4 (cdr (assoc 10 ent4))
    );_结束setq
    (setq pt-dis2 (list (trans (polar pt4 (+ ang4 (angle '(0 0) ls)) (distance '(0 0) ls)) 0 1) (abs (distance
                                                           (car box)
                                                           (cadr box)
                                                     )
                                                    )
              )
    )
      );_结束
    );_结束cond
    pt-dis2
  );_结束defun_ffg-txt-mid-ptlong

;;;主程序开始
  (vl-load-com)
  (setvar "cmdecho" 0)
  (command ".undo" "be")
  (defun *error* (msg)
    (if oos
      (setvar "osmode" oos)
    );_结束if
    (setvar "cmdecho" 1)
  );_结束error
  (setq oos (getvar "osmode"))
  (setvar "osmode" 0)
  (setq ss (ssget '((0 . "TEXT,MTEXT,TCH_TEXT,TCH_MTEXT,ATTRIB")))
    n 0
    date1 (getvar "millisecs")
  )
  (while (setq en (ssname ss n))
    (setq ty (cdr (assoc 0 (entget en))))
    (setq pt-dis (ffg-txt-mid-ptlong en)
      dis (cadr pt-dis);文字对角线距离
    )
    (setq k 1)
    (setq ptm (trans (car pt-dis) 0 1))
    (while (and
         (null (setq disn (car (ffg-near-point-line ptm (* 0.5 pi) (* k dis)))))
         (< k 20);根据实际表格,适当修改一下这个k最大值20,这里是最大20倍文字宽度。
       )
      (setq k (* 1.5 k));逐渐增大k值,循环尝试文字长度的多少倍能碰到表格边框
    )
    (setq k 1)
    (while (and
         (null (setq diss (car (ffg-near-point-line ptm (* 1.5 pi) (* k dis)))))
         (< k 20);根据实际表格,适当修改一下这个k最大值20
       )
      (setq k (* 1.5 k))
    )
    (setq k 1)
    (while (and
         (null (setq dise (car (ffg-near-point-line ptm 0.0 (* k dis)))))
         (< k 20);根据实际表格,适当修改一下这个k最大值20
       )
      (setq k (* 1.5 k))
    )
    (setq k 1)
    (while (and
         (null (setq disw (car (ffg-near-point-line ptm pi (* k dis)))))
         (< k 20);根据实际表格,适当修改一下这个k最大值20
       )
      (setq k (* 1.5 k))
    )
    (if (and
      disn
      diss
    )
      (setq yy (* 0.5 (- disn diss)))
      (setq yy 0)
    );_结束if
    (if (and
      dise
      disw
    )
      (setq xx (* 0.5 (- dise disw)))
      (setq xx 0)
    );_结束if
    (if (not (= 0 xx yy))
      (vla-move (vlax-ename->vla-object en) (vlax-3d-point ptm) (vlax-3d-point (list (+ (car ptm) xx) (+ (cadr ptm) yy))));vla-move比move快10倍
    )
    (setq n (1+ n))
  );_结束while
  (setq time (- (getvar "millisecs") date1))
  (princ (strcat "\n耗时\"" (rtos (/ time 1000.000) 2 3) "\"秒,平均速度: " (rtos (/ (* (sslength ss) 1000.0) time) 2 0)
         " 个/秒."
     )
  )
  (setvar "osmode" oos)
  (command ".undo" "e")
  (setvar "cmdecho" 1)
  (princ)
);_结束defun

评分

参与人数 1明经币 +1 金钱 +10 收起 理由
tigcat + 1 + 10 很给力!

查看全部评分

发表于 2019-12-22 23:03:01 | 显示全部楼层
wudechao 发表于 2019-9-26 18:19
用填充的找中点,速度太慢。院长的代码简练,佩服,不过执行效率低。测试520个字,院长的用了27秒。我下面 ...

大佬不支持多行文字
发表于 2019-12-22 23:05:56 | 显示全部楼层
wudechao 发表于 2019-11-16 23:21
;文字表格秒居中,终结版本(经多次测试,比填充方式找中点约快215倍)
(defun c:wzjz (/ *error* oos en  ...

大佬能不能麻烦添加支持多行文字
发表于 2019-12-23 11:40:52 | 显示全部楼层
zj20190405 发表于 2019-12-22 23:05
大佬能不能麻烦添加支持多行文字

(setq ss (ssget '((0 . "TEXT,MTEXT,TCH_TEXT,ATTRIB")))
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-12 18:14 , Processed in 0.152133 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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