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
坐等大佬更新