advksf 发表于 2024-4-22 17:14:49

感谢大佬分享,我也是初学者,正在慢慢摸索

Gaudi 发表于 2024-4-22 17:44:47

本帖最后由 Gaudi 于 2024-4-23 16:54 编辑

第二篇第一部分桩号数值转标注文字



这个功能开始是很简单的。
直接用设计软件进行标注就行。

但是后来大量有实际里程和标注里程不一致的情况出现。
并且还不能使用长短链。
不得不去再去寻找新的办法。

1 功能拆分

选择主线。

起始点桩号标注:
获得起始点坐标。
将起点数值转为桩号形式,即公里和米。
标注内容四连判断——如果起点数值是0,0+000;如果是百位数,0+数值;如果是十位数,0+0数值;如果是个位数,0+00数值。
标注桩号线和文字,计算确定起终点位置和标注角度,调用直线命令和文字命令。

中间点桩号标注:
用总长除间距,得到需要重复标注多少次。
每一次就再上次的标注点上加桩号间距。
这里有个坑,就是起始数值可能不是桩号间距的整数倍,所以要经过一次计算,判定第一次中间点桩号标注时候的准确间距。
然后是标注内容四连判断、标注桩号线和文字。

终点桩号标注:
一样。

还得有个函数,找到每个点的切点角度。

2 基础参数输入


罗里吧嗦几千字,终于开始实战了。
面临的第一个问题就是——如何用autolisp实现将用户输入的数值给到某个特定参数,并给参数一个默认值?

查询的过程就不赘言,给出结果:使用GETXXX系列函数。
七里八里的不用看,重点就两个:数字用getreal,文字用getstring。

模板函数如下:
(if(= nil (setq 参数名 (getreal "\n参数描述{参数列表}<默认值>:")))
    (PROGN
      (setq 参数名 默认值)
    )
)

样例如下:
(if(= nil (setq normalAngle (getreal "\n选择垂直法线方向{0.两侧 1.左侧 2.右侧}<0>:")))
    (PROGN
      (setq normalAngle 0)
    )
)

逐行注释下:
把“”引号里的内容发到命令行,读取输入数值。如果输入的数值为空(操作就是空格过去),那就把默认值赋给这个参数。

看看,朋友,多简单,就是前面的IF和SETQ组合。

分门类别把所有需要的参数全部定义好了 ,都是这一个模板,没有任何变化。

3 桩号文字的转换

获取到桩号数值以后,要写一个函数将数值转为K0+000字符串,这里就命名为stringZH吧,代表把桩号数值转为桩号文字。

首先要取得公里数和米数。
其实大家如果不用autolisp写,而是用自然语言描述,都知道怎么弄。
前面有说过,电脑是个傻子,他不懂自然语言,你必须得讲自然语言分解成最基本的操作单元。

A 将桩号数值除以1000。
B 取得其整数部分。
C 将整数部分保存到千米参数。
D 将千米参数乘以1000.
E 用桩号数值减去乘以1000以后的千米参数。
F 结果保存到米参数。

大家看是不是?

转化成autolisp后如下:
(setq ZHK (FIX (/ ZH 1000.0)))
(setq ZHM (- ZH (* ZHK 1000.0)))

这里面有个FIX函数,实现的是B功能取整。还有个REM函数,实现的是取余功能。都是最基本的数学运算板块函数。
其他就没什么新知识了。

然后就是根据米部分的四连判断,我将上文的内容再复制一次:
标注内容四连判断——如果起点数值是0,0+000;如果是百位数,0+数值;如果是十位数,0+0数值;如果是个位数,0+00数值。

以一个判定为示例:
(if(> 100.0 ZHM 10.0)
(PROGN
    (setq ZHK+M (strcat (ZHK "+0" ZHM)))
)
)

把这个判定复制四次,心满意足的去调试。

错误,函数错误。

4 错误修复

明明语句是对的,为什么错误?
因为软件真得很傻,ZHK和ZHM明明是数字,strcat要求字符串也就是文字。
所以得去搜一个新函数,RTOS。
还记得刚刚两个getreal和getstring吗?
RTOS=Real TO String。

OK,更改如下:
(defun C:ZH(ZHK ZHM)
(if   (> 100.0 ZHM 10.0)
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+0" (RTOS ZHM 2 0)))
    )
)
)

可行!

5 需求增加

用着用着我发现,只能对付不带小数的桩号。
如果要增加小数桩号的标注,那得增加一个判定:
(= ZHM (FIX ZHM))
FIX取整,取整以后和原数字一样,那就说明ZHM不带小数。

这个判定要跟米参数的范围联合起来,所以要用AND。
(AND (> 100.0 ZHM 10.0) (= ZHM (FIX ZHM)))

同时增加一个带小数桩号的判定:
(if(/= ZHM (FIX ZHM))
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 3)))
    )
)
</=>就是不等于的意思。
RTOS后面的2代表十进制,其他参数我看一般也用不到;3代表小数部分的位数。

5 最终函数
(defun stringZH (ZH)
(setq ZHK (FIX (/ ZH 1000.0)))
(setq ZHM (- ZH (* ZHK 1000.0)))
(if(= ZHM 0)
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+000"))
    )
)
(if(AND (>= ZHM 100.0) (= ZHM (FIX ZHM)))
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 0)))
    )
)
(if(AND (> 100.0 ZHM 10.0) (= ZHM (FIX ZHM)))
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+0" (RTOS ZHM 2 0)))
    )
)
(if(AND (> 10.0 ZHM 0.0) (= ZHM (FIX ZHM)))
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+00" (RTOS ZHM 2 0)))
    )
)
(if(/= ZHM (FIX ZHM))
    (PROGN
      (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 3)))
    )
)
ZHK+M
)

最后函数加个参数值返回。
如果没这个东西,默认返回最后一句赋值代码。
那也太不可控了不是吗。

写着写着发现太长了,分下段吧。


你有种再说一遍 发表于 2024-4-22 18:40:53

你可以用md格式写笔记.
只是这个论坛不支持这个格式.
并且再去学习一下git,它支持md格式

sky-x-x 发表于 2024-4-22 19:39:19

从零开始学习lisp。谢谢

lxl217114 发表于 2024-4-22 19:43:23

给想学lisp的坛友注入了一针强心剂,很好。

qazxswk 发表于 2024-4-22 19:46:56

今天注册的成员,竟然能写出这样的教程,肯定是一个默默无闻的成功者,今天开始要爆发了,不简单。:lol

Gaudi 发表于 2024-4-22 20:29:01

本帖最后由 Gaudi 于 2024-4-23 15:35 编辑

第二篇第一部分增补


1
一定一定要注意lisp中函数要求提供的数据格式。

输入的时候,带上“就是代表是字符串。


目前我最常见的数据格式有:数字(real)、文字(字符串string)、列表(list)。

最常用的转换就是数字转字符串,rtos。

而字符串转数字我目前还没用到,稍微查询了下
如果可以确定该字符串只有数字,可以有atoi和atof。
但是字符串绝大部分情况不是这样,所以需要自定义函数。
自定义函数基本上是通过一个一个字符和数字对比,然后再合并起来。

至于列表的概念,还有很具有工程实际的角度弧度互转,以及cad图元命和vla对象的互转。
碰到了再增补。

2
数学运算和逻辑对比

加减乘除、乘方开方,就不用说了。

FIX和REM,一个取整,一个取余。

大于小于、大于等于、小于等于、等于不等于,这些都很简单。
有一个点,可以连续判定,按顺序判定。
(> 100.0 ZHM 10.0)


这里有一个坑。
<=>只能用于比较数字,如果是字符串,需要用<equal>。
equal有一系列的子函数,其他不用管。

同时还有一个坑。
比较的时候需要注意数字是否带小数。
根据我查询资料,计算机里面应该有整数和小数的区分。
多注意。

飞雪神光 发表于 2024-4-22 20:51:21

Gaudi 发表于 2024-4-22 20:29
等什么时候会在论坛上传代码了再改

表情旁边有一个   <>在里面选择 LISP

PDCA2025 发表于 2024-4-22 21:36:02

赞一个
刚刚学就如此简单高效搞出一个工具,羡慕了。

XPG 发表于 2024-4-23 09:45:03

坐等大佬更新
页: 1 [2] 3 4 5 6
查看完整版本: 新手从零开始的第一份LISP程序全纪录