本帖最后由 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
- )
最后函数加个参数值返回。
如果没这个东西,默认返回最后一句赋值代码。
那也太不可控了不是吗。
写着写着发现太长了,分下段吧。
|