☰
AutoLISP函数大全分类手册:从数学运算到选择集操作的核心函数速查指南
2026/10/24 17:53:45 网站建设 项目流程

简介:《LISP函数大全分类手册》是一份面向AutoLISP初学者与CAD二次开发者的函数速查资料,以PDF形式系统梳理了AutoLISP常用函数,帮助读者在编写和调试LISP程序时快速定位语法与用途。资源包共1个PDF文件,大小约47KB,轻量便携,适合随时查阅。手册按功能划分为数学运算、检验与逻辑运算、转换运算、列表处理等模块,逐条列出函数原型与返回值说明,例如数学运算中的加减乘除、取整、最大公约数,逻辑运算中的比较与位运算,转换运算中的角度、字符串与实数互转,以及列表处理中的car、cdr、cons、mapcar等核心操作,并延伸至字符串、文件、等待输入与几何运算等常用函数。目前已有765人学习下载,内容覆盖AutoLISP编程基础,可作为案头工具书,帮助读者理解函数语义、积累调用经验,进而提升CAD环境下的程序编写效率与灵活性。

1. 搞懂 LISP 函数:为什么一串括号能指挥整个绘图流程

很多人第一次看到 LISP 代码,脑子里冒出的第一个念头是:这一堆括号到底在干什么?比如(+ 1 2 3),看起来像某种加密过的算式,实际上它就是 1 加 2 加 3 的意思。LISP 的全称是 List Processing,翻译过来叫“列表处理”,它的核心思想非常朴素——代码本身就是数据,数据也是代码,所有东西都用括号包成一个列表来表达。

打个比方,LISP 的括号就像厨房里的备菜盘。每个盘子里放着食材和调料,厨师按盘子上的顺序依次处理。(+ 1 2)这个盘子里装的是“加法操作、数字 1、数字 2”,LISP 引擎看到盘子就知道该做加法。这种“操作符放最前面”的写法叫前缀表达式,和数学课上写的1 + 2顺序不同,但逻辑一样。

AutoLISP 是嵌入在 CAD 软件里的 LISP 方言,专门用来做绘图自动化和批量处理。这份《LISP函数大全分类手册》把 AutoLISP 的函数按功能分成十九个大类,从数学运算到对象处理、从选择集操作到内存管理,基本覆盖了日常写脚本会用到的全部工具。搞懂这些函数的分类逻辑,比死记硬背每个函数的参数有用得多——因为你知道遇到什么问题该去哪个抽屉里找工具。

2. 数学与逻辑函数:LISP 的算盘和判官

2.1 数学运算函数到底在算什么

数学函数是 LISP 里最没有理解门槛的一类,因为它们的名字和功能几乎一一对应。(+ 数值 数值...)做累加,(- 数值 数值...)做减法,(* 数值 数值...)做乘法,(/ 数值 数值...)做除法。注意一个细节:减法和除法都是“第一个数减/除以后面所有的数”,不是两两配对。比如(- 10 3 2)的结果是 5,先算 10 减 3 得 7,再减 2 得 5。

除了四则运算,手册里还列了一批“单数值操作”函数。(abs 数值)取绝对值,(fix 数值)把实数截断成整数,(sqrt 数值)求平方根,(exp 数值)算自然指数,(log 数值)算自然对数。这些函数在写几何计算脚本时出场率极高,比如算两点距离、判断坐标是否在某个范围内。

三角函数值得单独提一句。(sin 角度)和(cos 角度)的参数单位是弧度,不是角度。很多人第一次用的时候传了 90 进去,以为能算出 1,结果得到一个约等于 0.894 的数——因为 90 弧度早就绕了好几圈了。正确做法是用pi常数来换算,比如 90 度要写成(/ pi 2)。

;; 计算 60 度角的正弦值 ;; 先把角度转成弧度:60 * pi / 180 (sin (* 60 (/ pi 180))) ;; 返回约 0.866

这段代码里pi是 AutoLISP 内置的常数,约等于 3.1415926。(/ pi 180)算出每度对应的弧度值,再乘以 60 就得到 60 度的弧度表示。这种写法在需要精确控制角度的绘图脚本里非常常见。

(gcd 数值1 数值2)求最大公约数,(rem 数值1 数值2)求余数,(max ...)和(min ...)在一堆数里挑最大最小。这些函数单独看都很简单,但组合起来能解决不少实际问题。比如判断一个数是不是偶数,可以用(= (rem n 2) 0);比如把任意角度规范到 0 到 360 度之间,可以用rem配合条件判断。

2.2 逻辑判断:LISP 怎么分辨真假

LISP 里的“真”和“假”跟很多语言不太一样。它用T表示真,用nil表示假,而且nil同时兼任“空列表”的角色。这意味着任何返回空列表的操作,在逻辑判断里都等同于“假”。这个设计初看有点怪,但用久了会发现它让代码变得很紧凑。

比较函数是逻辑判断的基础。(= 表达式1 表达式2)判断相等,(< ...)判断小于,(> ...)判断大于,(<= ...)和(>= ...)分别判断小于等于和大于等于。这些函数不仅能比较数字,还能比较字符串。比如(= "abc" "abc")返回T,(< "apple" "banana")也返回T,因为字符串比较走的是字典序。

(and 表达式1 表达式2...)做逻辑与运算,所有表达式都为真时才返回真。(eq 表达式1 表达式2)和(equal 表达式1 表达式2 [差量])是一对容易搞混的函数。eq比较的是“是不是同一个对象”,equal比较的是“内容是不是一样”。举个例子,两个分别创建的列表(list 1 2)和(list 1 2),用eq比较返回nil,用equal比较返回T。equal还支持一个可选的差量参数,用于实数比较时容忍微小误差——这在浮点运算里非常实用,因为计算机算出来的 0.1 加 0.2 不一定精确等于 0.3。

(boole 函数 整数 整数...)做位运算,(~ 数值)做按位取反。这两个函数在写底层工具或者处理二进制标志位时才会用到,日常绘图脚本里出现频率不高,但知道它们存在能让你在遇到位操作需求时不至于抓瞎。

3. 列表处理函数:LISP 的看家本领

3.1 列表的拆与装

列表是 LISP 的命根子,几乎所有数据都用列表来表示。一个三维坐标点是列表(x y z),一条线的信息是列表((起点) (终点)),图元的数据更是嵌套了好几层的列表。所以列表处理函数是这份手册里最值得花时间理解的部分。

(car 列表)取列表的第一个元素,(cadr 列表)取第二个,(caddr 列表)取第三个。这三个函数在 CAD 脚本里几乎无处不在,因为坐标点就是三元素列表,car拿 X 坐标,cadr拿 Y 坐标,caddr拿 Z 坐标。(cdr 列表)返回去掉第一个元素之后的剩余部分,常用来遍历列表。

(cons 新元素 列表)把新元素塞到列表头部,(append 列表1 列表2...)把多个列表首尾拼接成一个。这两个函数的区别在于:cons的第二个参数必须是列表,结果是新元素成为列表的第一个;append的所有参数都必须是列表,结果是所有元素合并。比如(cons 1 (list 2 3))得到(1 2 3),(append (list 1) (list 2 3))也得到(1 2 3),但(cons 1 2)会报错,因为 2 不是列表。

(list 元素1 元素2...)把散落的元素打包成一个列表,(length 列表)数一数列表里有几个元素,(reverse 列表)把列表顺序颠倒过来,(nth n 列表)取出第 n 个元素(从 0 开始数)。这些函数组合起来能完成大部分列表操作需求。

;; 从坐标点列表中提取所有 X 坐标 ;; 假设 points 是 ((1 2 0) (3 4 0) (5 6 0)) (mapcar 'car points) ;; 返回 (1 3 5)

mapcar是列表处理里的“批量处理器”。它把函数依次应用到每个列表的对应元素上,返回一个新列表。上面这段代码用car函数批量提取每个点的第一个元素,一行就完成了遍历。mapcar后面可以跟多个列表,函数会按位置依次取参。比如(mapcar '+ '(1 2) '(10 20))返回(11 22),相当于把两个列表对应位置的元素相加。

3.2 查找、替换与遍历

(assoc 关键元素 联合列表)在“关联列表”里查找匹配项。关联列表是一种特殊的嵌套列表结构,每个子列表的第一个元素是键,后面跟着值。比如((name "A") (age 20))就是一个关联列表,(assoc 'name ...)会返回(name "A")。这种结构在存储配置信息、图元属性时非常常用。

(member 关键元素 列表)从列表里找到关键元素第一次出现的位置,返回从该位置到末尾的子列表。如果没找到就返回nil。(subst 新项 旧项 列表)把列表中所有等于旧项的元素替换成新项,返回替换后的新列表。注意subst是“全量替换”,列表里所有匹配的旧项都会被换掉。

(foreach 名称 列表 表达式)是遍历列表的专用工具。它把列表里的每个元素依次赋值给名称,然后执行表达式。和mapcar的区别在于:mapcar收集每次执行的结果组成新列表返回,foreach不收集结果,纯粹为了执行副作用(比如打印信息、修改外部变量)。选择哪个取决于你是要“得到一个新列表”还是“对每个元素做一件事”。

(listp 元素)判断一个东西是不是列表,返回T或nil。这个函数在写递归处理嵌套列表的代码时是必备的守卫条件——先判断是不是列表,再决定要不要继续往里拆。

4. 转换、字符串与输入函数:数据在 LISP 里怎么变形

4.1 类型转换:数字和文字之间的翻译官

LISP 是弱类型语言,但这不意味着类型不重要。很多时候你需要把用户输入的字符串变成数字才能计算,或者把计算结果变成字符串才能显示。转换函数就是干这个的。

(atof 字符串)把字符串转成实数,(atoi 字符串)把字符串转成整数,(itoa 整数)把整数转成字符串,(rtos 数值 模式 [精度])把实数转成字符串并控制格式。rtos的模式参数决定输出格式:模式 1 是科学计数法,模式 2 是十进制,模式 3 是工程格式,模式 4 是建筑格式,模式 5 是分数格式。精度参数控制小数点后保留几位。

角度转换有一对专用函数。(angtof 字符串 [模式])把角度字符串转成实数(弧度),(angtos 角度 [模式 [精度]])把弧度值转成角度字符串。这两个函数在处理用户输入的角度值时非常方便,因为用户习惯用“度”来思考,而 LISP 内部用弧度计算。

(cvunit 数值 原始单位 转换单位)做单位换算,换算规则来自acad.nut文件。比如把英寸转成毫米、把度转成弧度。(trans 点 原位置 新位置 [位移])做坐标系统转换,把点从一个坐标系转到另一个坐标系。这个函数在写涉及多个坐标系的脚本时是刚需,比如把用户坐标系里的点转到世界坐标系。

;; 把用户输入的字符串 "3.14" 转成实数并计算平方 ;; 假设用户输入存在变量 input-str 中 (setq input-str "3.14") (setq num (atof input-str)) (setq result (* num num)) ;; result 约等于 9.8596

这段代码展示了典型的“输入-转换-计算”流程。atof把字符串变成实数,然后才能参与乘法运算。如果跳过转换直接对字符串做乘法,LISP 会报错。

4.2 字符串处理与文件读写

字符串函数处理文本数据。(strlen 字符串)返回字符个数,(strcat 字符串1 字符串2...)把多个字符串拼接成一个,(substr 字符串 起始 长度)从指定位置截取指定长度的子串,(strcase 字符串 [字样])转换大小写。(ascii 字符串)返回第一个字符的 ASCII 码,(chr 整数)返回整数对应的 ASCII 字符。

(wcmatch 字符串 格式)做通配符匹配,支持*和?等通配符。比如(wcmatch "hello.lsp" "*.lsp")返回T,用来判断文件名是否符合某种模式。这个函数在批量处理文件时很有用。

文件操作函数包括(open 文件名 模式)打开文件、(close 文件名)关闭文件、(read-line [文件代码])读一行、(write-line 字符串 [文件代码])写一行。模式参数用"r"表示读取,"w"表示写入,"a"表示追加。文件代码是open返回的句柄,后续读写操作都靠它来指定目标文件。

(read 字符串)把字符串解析成 LISP 数据。比如(read "(1 2 3)")返回列表(1 2 3)。这个函数在解析配置文件或者处理序列化数据时很有用。

4.3 等待输入:让脚本和用户对话

输入函数让脚本暂停执行,等待用户提供数据。(getpoint [基点] [提示])请求用户点选一个点,(getdist [基点] [提示])请求输入距离,(getint [提示])请求整数,(getreal [提示])请求实数,(getstring [提示])请求字符串,(getangle [基点] [提示])请求角度,(getcorner 基点 [提示])请求矩形对角点。

这些函数的参数都是可选的。如果不提供提示信息,CAD 命令行会显示默认提示。如果提供了基点,用户点选时会显示一条从基点到当前光标的橡皮筋线,方便定位。

(initget [位] 字符串)用来限制下一次getxxx函数的有效输入。位参数控制是否允许空输入、零、负数等,字符串参数列出允许的关键词。比如(initget 1 "Yes No")表示下一次输入必须是非空值,且只能是 "Yes" 或 "No"。这个函数在写交互式脚本时能有效防止用户乱输入导致程序崩溃。

(getkword [提示])专门用来获取关键词输入,配合initget使用。用户输入的关键词会以字符串形式返回。

5. 几何、对象与选择集:LISP 怎么操作图形

5.1 几何计算函数

几何函数处理点、线、角度、距离这些图形基本元素。(angle 点1 点2)返回两点连线的角度(弧度),(distance 点1 点2)返回两点距离,(polar 基点 弧度 距离)按极坐标方式从基点出发走指定距离和角度得到新点,(inters 点1 点2 点3 点4 [模式])求两条线的交点。

(osnap 点 模式字符串)按照对象捕捉模式取得精确坐标。模式字符串可以是"end"(端点)、"mid"(中点)、"cen"(圆心)、"int"(交点)等。这个函数在写需要精确对齐的脚本时非常关键,因为用户鼠标点选的位置往往有偏差,osnap能自动吸附到精确位置。

(textbox 对象列表)返回文字对象的两个对角点坐标,用来计算文字占用的空间。这个函数在写自动排版或者检查文字是否重叠的脚本时会用到。

;; 计算两点之间的距离和角度 (setq p1 '(0 0 0)) (setq p2 '(3 4 0)) (setq dist (distance p1 p2)) ;; 返回 5.0 (setq ang (angle p1 p2)) ;; 返回约 0.9273 弧度 ;; 用 polar 从 p1 出发走 dist 距离、ang 角度,应该回到 p2 (polar p1 ang dist) ;; 返回 (3.0 4.0 0.0)

这段代码展示了distance、angle、polar三个函数的配合关系。polar本质上是angle和distance的逆运算——已知起点、方向和距离,求终点。

5.2 对象处理与选择集

对象处理函数直接操作图形数据库里的图元。(entget 对象名称)取出图元的信息列表,里面包含图元类型、图层、颜色、坐标等所有属性。(entmod 对象列表)把修改后的信息列表写回图元,实现修改图形。(entmake 对象列表)创建新图元,(entdel 对象名称)删除图元,(entnext [对象名称])找下一个图元,(entlast)找最后一个图元。

(entsel [提示])请求用户选取一个图元,返回包含图元名称和选点坐标的列表。(nentsel [提示])和(nentselp [提示] [点])用于选取块内部的子图元,返回的信息更详细。

选择集函数批量处理图元。(ssget [模式] [点1] [点2])创建选择集,模式参数可以是"W"(窗口包含)、"C"(交叉窗口)、"X"(过滤器)等。(ssadd [对象名称] [选择集])把图元加入选择集,(ssdel 对象名称 选择集)从选择集移除图元,(sslength 选择集)返回选择集中的图元数量,(ssname 选择集 索引值)按索引取出图元名称。

(ssget "X" [过滤列表])是使用频率最高的选择集函数之一。过滤列表用关联列表的形式指定筛选条件,比如((0 . "LINE"))表示只选直线,((8 . "WALLS"))表示只选 WALLS 图层上的图元。多个条件可以组合,实现精确筛选。

5.3 符号表与查询控制

符号表函数访问图形数据库里的全局设置。(tblsearch 符号表名称 符号)在指定符号表中查找符号,(tblnext 符号表名称 [T])遍历符号表。有效的符号表名称包括"LAYER"(图层)、"LTYPE"(线型)、"STYLE"(文字样式)、"BLOCK"(块)等。

查询控制函数包括(getvar "系统变量")读取系统变量值,(setvar "系统变量" 值)设置系统变量值,(getenv "环境变量")读取环境变量,(findfile 文件名)查找文件路径,(getfiled 标题 内定档名 扩展名 旗号)弹出文件选择对话框。

(command "AutoCAD命令" ...)是重量级函数,直接在 LISP 里调用 CAD 原生命令。比如(command "LINE" '(0 0) '(10 10) "")相当于在命令行输入画线命令并指定两个端点。这个函数让 LISP 脚本能复用 CAD 的所有内置功能,是自动化绘图的万能钥匙。

6. 流程控制与函数定义:让 LISP 脚本活起来

6.1 判断与循环

(if 比较式 表达式1 [表达式2])是最基本的条件判断。比较式为真执行表达式1,否则执行表达式2(如果提供了的话)。(cond (比较式1 表达式1) (比较式2 表达式2) ...)是多分支判断,依次检查每个比较式,执行第一个为真的分支。(progn 表达式1 表达式2...)把多个表达式打包成一个,常配合if和cond使用,因为这两个函数的分支只能写一个表达式,用progn就能塞进去多个。

(repeat 次数 [表达式...])重复执行指定次数,(while 比较式 表达式...)在条件为真时反复执行。while是写不确定次数循环的标准工具,比如遍历一个列表直到取完为止。

;; 用 while 遍历列表并累加所有数字 (setq nums '(1 2 3 4 5)) (setq total 0) (while nums (setq total (+ total (car nums))) (setq nums (cdr nums)) ) ;; total 最终为 15

这段代码展示了 LISP 里最经典的列表遍历模式:用car取头部元素,用cdr去掉头部,循环直到列表为空(nil在条件判断里为假)。虽然foreach和mapcar更简洁,但理解这种底层遍历方式有助于看懂老代码。

6.2 自定义函数与错误处理

(defun 名称 自变量列表 表达式...)定义自定义函数。这是 LISP 编程的核心——把重复的逻辑封装成函数,需要时调用即可。(lambda 自变量 表达式)定义匿名函数,通常直接传给mapcar或apply使用,不需要单独命名。

(apply 功能函数 列表)把函数应用到列表上,相当于把列表展开成参数列表再调用函数。(eval 表达式)执行一个表达式并返回结果,用于动态执行代码。(quote 表达式)或简写'表达式阻止表达式被求值,直接返回表达式本身。

错误处理方面,(*error* 字符串)定义错误处理函数,当程序出错时自动调用。(alert 字符串)弹出警告对话框。(exit)和(quit)强制退出程序。(trace 函数...)和(untrace 函数...)设置和解除函数追踪标记,用于调试。

(setq 符号1 表达式1 [符号2 表达式2]...)是最常用的赋值函数,把表达式的值赋给符号。(set 符号 表达式)功能类似但符号需要带引号。(type 元素)返回元素的数据类型,(boundp 表达式)判断符号是否有值,(null 元素)判断元素是否为nil,(numberp 元素)判断是否为数字,(zerop 元素)判断是否为零,(minusp 元素)判断是否为负。

7. 常见误区:这些函数名字很像,用错了就翻车

7.1 eq 和 equal 到底差在哪

这是 LISP 初学者最容易踩的坑。eq比较的是“两个东西是不是同一个对象”,equal比较的是“两个东西的内容是不是一样”。对于数字和字符串,两者行为基本一致。但对于列表,差别就出来了:两个分别用list创建的相同列表,eq返回nil,equal返回T。

为什么会有这个区别?因为 LISP 里列表是引用类型,每次list调用都会在内存里新建一个对象。eq看的是内存地址,equal看的是内容。日常写脚本时,比较列表内容用equal几乎总是对的,用eq比较列表基本都会翻车。

7.2 car/cdr 和 first/rest 是一回事吗

AutoLISP 里car和cdr是标准函数,first和rest在某些 LISP 方言里是它们的别名。但在 AutoLISP 里,first和rest并不是内置函数,直接用会报错。所以看到别的 LISP 代码里用first和rest,搬到 AutoLISP 里要改成car和cdr。

另外cadr不是“cdr 的 car”,而是“car 的 cdr 的 car”——从右往左读:先cdr去掉第一个元素,再car取新列表的第一个元素,也就是原列表的第二个元素。同理caddr是取第三个元素。这种命名规则可以扩展到四层,比如cadadr,但超过三层可读性就很差了。

7.3 subst 和 entmod 都能改数据,什么时候用哪个

subst是纯列表操作函数,它返回一个新列表,不修改原列表,也不涉及图形数据库。entmod是图形数据库操作函数,它把修改后的图元信息列表写回数据库,直接改变屏幕上的图形。

如果你只是想处理一个普通列表数据,用subst。如果你想修改图形中某个图元的属性(比如改颜色、改图层),需要先用entget取出信息列表,用subst替换要改的字段,再用entmod写回。两者是配合关系,不是替代关系。

7.4 getpoint 和 osnap 都能取点,区别在哪

getpoint是交互函数,暂停程序等待用户用鼠标点选或键盘输入坐标。它返回的是用户实际点选的位置,可能有偏差。osnap是计算函数,它不暂停程序,而是根据给定的参考点和捕捉模式,计算出一个精确的捕捉点。

典型用法是先用getpoint让用户大致点一下,再用osnap把那个点吸附到最近的端点或中点上。如果直接用getpoint的返回值作为绘图坐标,画出来的线可能没有精确对齐。

7.5 setq 和 set 看起来一样,为什么有两个

(setq 符号 表达式)的第一个参数不需要引号,LISP 自动把它当作符号名处理。(set 符号 表达式)的第一个参数需要求值,所以通常要写成(set '符号 表达式)。功能上两者都能赋值,但setq更简洁,是日常首选。set存在的意义在于它的第一个参数可以是变量——比如(set var-name value)可以根据var-name里存的符号名来动态赋值。这种动态赋值场景很少见,但需要时只有set能做到。

8. 什么时候该翻这本手册,什么时候别硬套

这份《LISP函数大全分类手册》最直接的用法是当字典查。写脚本时突然想不起来某个功能的函数名,按分类翻到对应章节扫一眼,比在搜索引擎里大海捞针快得多。比如你需要做字符串大小写转换,翻到“字符串处理”章节,一眼就能看到strcase。

但手册不是教程,它不会告诉你“写一个自动标注脚本需要哪几步”。如果你完全没写过 LISP,光看函数列表会一头雾水——你知道每个函数干什么,但不知道怎么把它们串起来解决实际问题。这种情况下,更好的路径是先找一个简单的完整脚本例子,跑通一遍,理解基本结构,再回头翻手册查漏补缺。

另一个需要注意的是版本差异。AutoLISP 在不同版本的 CAD 软件里功能有增减,手册里列的函数大部分是长期稳定的核心函数,但涉及 3D 渲染、数据库连接的那些外部定义函数,可能因版本和安装配置不同而表现不一致。遇到这类函数报错,先确认当前环境是否支持,别急着怀疑自己代码写错了。

我自己的习惯是:写新脚本之前先翻一遍相关分类,把可能用到的函数在纸上列出来,标上参数和返回值,然后再动手写。这个习惯帮我省了很多来回查文档的时间。有一次写批量改图层的脚本,我本来打算用while循环遍历选择集,翻手册时发现ssname配合sslength用repeat更直接,少写了好几行代码。

希望这份手册也能帮你少走一些弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询