明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: Gaudi

[讨论] 新手从零开始的第一份LISP程序全纪录

    [复制链接]
发表于 2024-4-22 17:14 | 显示全部楼层
感谢大佬分享,我也是初学者,正在慢慢摸索
 楼主| 发表于 2024-4-22 17:44 | 显示全部楼层
本帖最后由 Gaudi 于 2024-4-23 16:54 编辑

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




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

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

1 功能拆分

选择主线。

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

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

终点桩号标注:
一样。

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

2 基础参数输入


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

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

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


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


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

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

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

3 桩号文字的转换

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

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

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

大家看是不是?

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


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

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

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


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

错误,函数错误。

4 错误修复

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

OK,更改如下:
  1. (defun C:ZH(ZHK ZHM)
  2.   (if   (> 100.0 ZHM 10.0)
  3.     (PROGN
  4.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+0" (RTOS ZHM 2 0)))
  5.     )
  6.   )
  7. )


可行!

5 需求增加

用着用着我发现,只能对付不带小数的桩号。
如果要增加小数桩号的标注,那得增加一个判定:
  1. (= ZHM (FIX ZHM))

FIX取整,取整以后和原数字一样,那就说明ZHM不带小数。

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


同时增加一个带小数桩号的判定:
  1.   (if  (/= ZHM (FIX ZHM))
  2.     (PROGN
  3.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 3)))
  4.     )
  5.   )

</=>就是不等于的意思。
RTOS后面的2代表十进制,其他参数我看一般也用不到;3代表小数部分的位数。

5 最终函数
  1. (defun stringZH (ZH)
  2.   (setq ZHK (FIX (/ ZH 1000.0)))
  3.   (setq ZHM (- ZH (* ZHK 1000.0)))
  4.   (if  (= ZHM 0)
  5.     (PROGN
  6.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+000"))
  7.     )
  8.   )
  9.   (if  (AND (>= ZHM 100.0) (= ZHM (FIX ZHM)))
  10.     (PROGN
  11.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 0)))
  12.     )
  13.   )
  14.   (if  (AND (> 100.0 ZHM 10.0) (= ZHM (FIX ZHM)))
  15.     (PROGN
  16.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+0" (RTOS ZHM 2 0)))
  17.     )
  18.   )
  19.   (if  (AND (> 10.0 ZHM 0.0) (= ZHM (FIX ZHM)))
  20.     (PROGN
  21.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+00" (RTOS ZHM 2 0)))
  22.     )
  23.   )
  24.   (if  (/= ZHM (FIX ZHM))
  25.     (PROGN
  26.       (setq ZHK+M (STRCAT (RTOS ZHK 2 0) "+" (RTOS ZHM 2 3)))
  27.     )
  28.   )
  29.   ZHK+M
  30. )


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

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


点评

感谢楼主热心分享,很适用一些初学者  发表于 2024-4-23 10:37
[code=lisp] ... [/code]  发表于 2024-4-22 17:55
发表于 2024-4-22 18:40 | 显示全部楼层
你可以用md格式写笔记.
只是这个论坛不支持这个格式.
并且再去学习一下git,它支持md格式
发表于 2024-4-22 19:39 | 显示全部楼层
从零开始学习lisp。谢谢
发表于 2024-4-22 19:43 | 显示全部楼层
给想学lisp的坛友注入了一针强心剂,很好。
回复 支持 1 反对 0

使用道具 举报

发表于 2024-4-22 19:46 | 显示全部楼层
今天注册的成员,竟然能写出这样的教程,肯定是一个默默无闻的成功者,今天开始要爆发了,不简单。
 楼主| 发表于 2024-4-22 20:29 | 显示全部楼层
本帖最后由 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 | 显示全部楼层
Gaudi 发表于 2024-4-22 20:29
等什么时候会在论坛上传代码了再改

表情旁边有一个   <>  在里面选择 LISP
发表于 2024-4-22 21:36 | 显示全部楼层
赞一个
刚刚学就如此简单高效搞出一个工具,羡慕了。
发表于 2024-4-23 09:45 来自手机 | 显示全部楼层
坐等大佬更新
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-6 20:40 , Processed in 0.227731 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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