lzspain 发表于 2024-9-26 19:16:39

新建单行文字lisp代码报错

本人是LISP小白,为了解决工作中的小问题,让AI写了一个lisp程序。主要功能如下:选择一个单行文本(可理解为初始高程),指定计算基点和目标点,在世界坐标系下计算两点Y坐标之差,生成一个新文本,即新文本=旧文本+目标点Y坐标-基点Y坐标。但效果不理想,最终生成的文本并没有在目标点位置,而是在原点处,我想要的结果是新文本左下角和目标点对齐,AI调试了一个多小时也不能实现。以下是代码和运行后的提示:


(defun c:gwz ()
(setq numText nil)

;; 提示用户选择纯数字文本
(prompt "\n请选择一个纯数字单行文字:")
(setq sel (ssget '((0 . "TEXT")))) ; 仅选择单行文字对象

(if sel
    (progn
      ;; 获取所选文本对象
      (setq ent (ssname sel 0))
      (setq numText (cdr (assoc 1 (entget ent)))) ; 获取文本内容
      (prompt (strcat "\n选中的文本内容是: " numText)) ; 调试信息

      ;; 检查文本是否为纯数字(支持负号和小数点)
      (if (and numText (not (vl-string-search "[^0-9.-]" numText)))
      (progn
          ;; 提示选择计算基点
          (prompt "\n请选择计算基点:")
          (setq basePoint (getpoint))

          ;; 输出基点的值
          (prompt (strcat "\n基点的坐标是: " (rtos (car basePoint) 2 4) ", " (rtos (cadr basePoint) 2 4)))

          ;; 提示选择目标点
          (prompt "\n请选择目标点:")
          (setq targetPoint (getpoint))

          ;; 输出目标点的值
          (prompt (strcat "\n目标点的坐标是: " (rtos (car targetPoint) 2 4) ", " (rtos (cadr targetPoint) 2 4)))

          ;; 计算 Y 值的差值
          (setq baseY (cadr basePoint)
                targetY (cadr targetPoint)
                diffY (- targetY baseY))

          ;; 确保将文本内容转换为浮点数
          (setq originalNumber (atof numText)) ; 使用 atof 转换为浮点数
          (prompt (strcat "\n原始数字是: " (rtos originalNumber 2 4))) ; 调试信息
         
          ;; 计算新的数字
          (setq newNumber (+ originalNumber diffY))
          (prompt (strcat "\n计算后的新数字是: " (rtos newNumber 2 4))) ; 调试信息

          ;; 用户输入小数位数
          (setq decimal-places (getint "\n请输入小数位数(0表示无小数位):"))

          ;; 根据用户输入的小数位数生成新的文本内容
          (setq formattedNewText (rtos newNumber 2 decimal-places))

          ;; 输出新的文本内容
          (prompt (strcat "\n格式化后的新文本内容是: " formattedNewText)) ; 调试信息

          ;; 获取原文本的属性
          (setq textStyle (cdr (assoc 7 (entget ent))) ; 字体样式
                height (cdr (assoc 40 (entget ent))) ; 字高
                width (cdr (assoc 41 (entget ent))); 字宽
                align (cdr (assoc 72 (entget ent))); 对齐样式
                newPoint (list (car targetPoint) (cadr targetPoint))) ; 新文本位置

          ;; 输出文本属性和位置调试信息
          (prompt (strcat "\n新文本位置: " (rtos (car newPoint) 2 4) ", " (rtos (cadr newPoint) 2 4)))
          (prompt (strcat "\n文本样式: " textStyle ", 字高: " (rtos height 2 4) ", 字宽: " (rtos width 2 4)))

          ;; 创建新的文本对象
          (setq newTextEnt (entmake
            (list
            (cons 0 "TEXT")
            (cons 1 formattedNewText)       ; 新文本内容
            (cons 10 newPoint)            ; 文本位置
            (cons 40 height)                ; 字高
            (cons 41 width)               ; 字宽
            (cons 7 textStyle)            ; 字体样式
            (cons 72 align)               ; 对齐样式
            (cons 210 '(0 0 1))             ; 文本的法向量
            )))

          ;; 调整文本位置以确保左下角在目标点
          (if newTextEnt
            (progn
            ;; 计算文本的偏移量
            (setq textHeight (cdr (assoc 40 (entget newTextEnt)))
                  offsetY (* 0.5 textHeight)) ; 偏移为高度的一半

            ;; 移动文本到目标点
            (command "MOVE" newTextEnt "" newPoint (list (car targetPoint) (+ (cadr targetPoint) offsetY)))

            (prompt "\n新文本已创建,内容为:")
            )
            (prompt "\n文本创建失败!"))
          (princ formattedNewText)
      )
      (prompt "\n非纯数字文本对象!")
      )
    )
    (prompt "\n未选择任何对象!")
)
(princ)
)

(princ "\n命令 gwz 已加载,请使用 gwz 命令。")


运行后提示如下:

命令: GWZ

请选择一个纯数字单行文字:
选择对象: 找到 1 个

选择对象:
选中的文本内容是: 3564.12
请选择计算基点:
基点的坐标是: 1983.5526, 1754.0645
请选择目标点:
目标点的坐标是: 1983.5526, 1751.4645
原始数字是: 3564.12
计算后的新数字是: 3561.52
请输入小数位数(0表示无小数位):2

格式化后的新文本内容是: 3561.52
新文本位置: 1983.5526, 1751.4645
文本样式: 横断面, 字高: 1, 字宽: 0.7; 错误: 参数类型错误: lentityp ((0 . "TEXT") (1 . "3561.52") (10 1983.55 1751.46) (40 . 1.0) (41 . 0.7) (7 . "横断面") (72 . 1) (210 0 0 1))


本想让程序自行判断小数位数,奈何一直报参数类型错误,无法解决,故采用手动输入小数位数的方式。恳请大佬出手调整一下代码,让最终生成的文本在目标点位置,且左下角与目标点对齐,能自动计算、匹配小数位数更好。
页: [1]
查看完整版本: 新建单行文字lisp代码报错