数字测图原理与应用——Lisp语言的学习和使用

数字测图原理与应用——Lisp语言的学习和使用
数字测图原理与应用——Lisp语言的学习和使用

数字测图原理与应用

——Lisp语言的学习和使用

主要内容

AutoLisp语言介绍

AutoLisp语言的基本知识

赋值与数值计算函数

自定义函数

程序分支与循环函数

逻辑运算函数

字符串与类型转换函数

表处理函数

交互数据输入函数及相关的计算函数

与文件有关的函数

实体和设备访问类函数

其它函数

一、AutoLisp语言介绍

LISP(List Processing)是一种计算机的表处理语言。LISP语言是人工智能领域中广泛应用的一种程序语言。

AutoLISP语言是一种运行在AutoCAD环境下的LISP编程语言,或称为AutoCAD的一种嵌入式语言。它采用了与CommandLISP(一种通用的LISP语言版本)相近的语法及习惯约定,并吸收了LISP语言的主要函数,同时增加了针对AutoCAD特点的许多功能,如:可以把AutoLISP和AutoCAD的绘图命令透明地结合起来,使设计和绘图完全融为一体。利用AutoLISP语言编程可以实现对AutoCAD当前图形数据库进行直接访问和修改。

在LISP语言中,最基本的数据类型是符号表达式。LISP语言的特点是程序和数据都采用符号表达式的形式,即一个LISP程序可以把另一个LISP程序作为它的数据进行处理。因此使用LISP语言编程十分灵活,看起来是一个一个的函数调用。支持递归定义也是Auto LISP语言的重要特性。

AutoLISP语言是提供给用户的主要二次开发工具之一。用AutoLISP语言编写应用程序,可以为AutoCAD增加新的命令或修改AutoCAD,以适应用户的特殊需要。AutoCAD软件的开发者——AutoDesk公司许诺,将保证今后AutoCAD 软件对AutoLISP语言的支持。掌握使用和编制AutoLISP应用程序的方法和技术将大大提高用户的工作效率和二次开发水平,增强AutoCAD的灵活性,并将得到长期、稳定的技术支持。

二、AutoLISP语言的基本知识

2.1 AutoLISP语言的特性

AutoLISP语言是一种解释型语言,它的特点如下:

1.解释型语言

编程语言有两种基本类型:解释型和编译型。AutoLISP属于解释型语言。在解释型语言中,用户编写的源程序直接由解释器解释并执行。而在编译型的语言中,源代码首先要编译为一种中间格式(目标文件),然后再与所需的库文件链接,生成机器码可执行文件。AutoCAD本身是用编译型语言写成的。

解释型语言的主要优点是在执行这种语言编写的程序之前不需要中间步骤,用户可以交互、独立于其它部分来试验或验证程序段或程序语句,而不需像编译型语言那样,每当试验程序时,要全部地编译和链接整个程序。

2.平台和操作系统独立

AutoLISP语言的另一个优点是可移植性。AutoLISP程序可以在运行于多种支持平台(如Windows、DOS、UNIX和Macintosh等)上的AutoCAD中执行而与CPU或操作系统无关。

3.AutoCAD的版本独立

AutoLISP程序除平台和操作系统独立外,AutoLISP的设计还考虑了向下的兼容。这样,任一版本AutoCAD编写的AutoLISP程序一般不加修改就可以在以后版本的AutoCAD中运行。

4.AutoLISP与主流编程语言的比较

AutoLISP与目前使用比较多的编程语言(如C/C++,BASIC等)之间有一些明显的差别。具体可体现在下述几个方面:

(1)AutoLISP与其它大多数语言之间最重要的差别是它用表(List)存放

数据。AutoLISP

........没有数组、联合、结构及记录,所有复杂的数据集均由表来表...........................

示和处理

....。

(2)AutoLISP的变量没有明确的类型。LISP变量的类型是在赋值时动态确定的。

(3)AutoLISP不需要预先声明变量或函数。

(4)与C/C++,BASIC等语言不一样,LISP没有语句、关键词及运算符。

它是函数定位的语言,其所有运算都是由函数调用完成。

2.2 AutoLISP语言中的数据类型

AutoLISP支持下述10种数据类型:

●整型数

●实型数

●字符串

●符号

●表

●文件描述符

●AutoCAD实体名

●AutoCAD选择集

●内部函数(AutoLISP子程序)

●外部函数(ADS、ARX函数)

整型数

整型数是一种不带小数点的数字,它可由0,1,2……,9,+,-共12个字符组成,例如:123,-76,+322等。

实型数

实型数是带有小数点的数,它可由0,1,2……,9,+,-,E,e共14个字符组成。实数有两种表示方法,即十进制表示法和科学计数表示法。例如:十进制表示法:12.3,-7.6,+3.22

科学计数表示法:6.1E5(610000),-0.12E2(-12),-0.45E-2(-0.0045)

字符串

字符串(字符串常数)由一对双引号(”)括起来的字符序列组成。这对双引号是字符串的定界符。

字符串常数最大长度为132个字符,但表示字符串的符号名所约束的值可以是任意长度,因而可以利用“STRCAT“(字符串拼接)函数无限制地增加其长度。

字符串中,同一字母的大小写认为是不同的字符,空格是一个有意义的字符。

字符串的长度是指字符串一对双引号之间的字符个数(不包括一对双引号)。如果字符串的定界符之间无任何字符(即””)称为空串,其长度为零。

字符串中可以包含ASCII码中任一字符,通用的表示形式为“\nnn“,nnn 为八进制形式的ASCII码。例如:“\101\102 \103”表示“ABC”,两者的作用完全相同。由于反斜杠“\”已作为字符串中的前导转义符,因而当字符串中要使用反斜杠时,必须加转义符,即用双反斜杠“\\”表示字符串中一个反斜杠“\”,也可以用反斜杠的ASCII码表示(即“\114”)。同样,由于双引号已作为字符串的定界符使用,因而字符串中的双引号可以用“\””或“\042”表示。对于一些常用的控制字符,其ASCII代码见下表。

字符代码表

例如:下面的表达式表示在显示提示内容前先进行换行,然后再显示字符串内容。

(prompt “\nEnter filename:”)

(prompt “\012Enter filename:”)

二者效果完全相同。

符号

AutoLISP中符号用于存储数据,因此“符号”和“变量”这两个词含义相同,可以互相交换使用。

符号名可以由除下列6个字符外的任何可以打印的长度不限的字符序列来组成:

“(”、“)“、“,”、“’”、“””、“;”,当这6个字符中的任一字符在符号名中出现时,将终止符号名。不允许使用数字符号作为第一个字符。

下列为合法的符号名:

ABC,!A,&AB,A3

下列为不合法的符号名:

(A),A.B,3A

在AutoLISP中符号名的大小写是等价的。LISP中“约束”是指对一对符号和值,当把一个值赋给一个符号时,也即把这个符号约束为那个值。

例如:

(setq a 6)

“!a”将显示6,表示a是一个整数,其值为6。

(setq a 6.0)

“!a”将显示6.0,表示a是一个实数,其值为6.0。

(setq a “6.0”)

“!a”将显示6,表示a是一个字符串,其值为“6.0”。

表是指在一对相匹配的左右圆括号之间的元素的有序集合。表中的每一项称为表的元素,表中的元素可以是整数、实数、字符串和符号,也可以是另一个表。

为了处理图形中点的坐标,AutoLISP对二维和三维点的坐标按如下规则表示:

二维点:以分别代表x,y坐标的两个实数所构成的表(x y)的形式表示,如:(3.21 7.58)

三维点:以分别代表x,y,z坐标的三个实数所构成的表(x y z)的形

式表示,如:(3.21 7.58 4.68)。

表的大小用其长度来度量。长度是表中顶层元素的个数。

例如:

(setq a 6) 表的长度为3

(setq a (+ c (/ d 2) ) ) 表的长度为3

表有两种基本类型:标准表和引用表。标准表是从左括号开始到配对的右括号结束。表中的第一个元素(0号元素)必须是一个合法的已存在的AutoLISP

函数。引用表是在左括号前加一撇号,表示不对此表作求值处理

.........................。

文件描述符

当AutoLISP打开一个文件时,系统将给该文件赋一个数字标号,在以后要访问该文件时(读或写文件),可利用该文件描述符对指定的文件进行操作。

例如:

打开一个名为:“myfile.dat”的文件,把打开文件时的文件描述符赋给符号f,再把“This is a sample under AutoLISP.”写入该文件。

(setq f (open “c:\\myfile.dat” “w”) )

(print “This is a sample under AutoLISP.” f)

实体名

实体名是AutoCAD系统在绘图过程中赋予所绘实体的一个数字标号。实际是指向一个AutoCAD系统内部的数据文件的一个指针。

例如:

(setq elast (entlast) )

注:entlast 是获取数据库中最新图元的名称。

选择集

选择集一个或多个实体的集合。它类似AutoCAD的实体选择过程。在AutoLISP程序中也可以构造一个选择集,并把它赋予一个符号供其它函数使用。

例如:

(setq ss (ssget “p”))

子程序和外部子程序

由AutoLISP提供的函数称为子程序(内部函数),外部子程序是由ADSRX或ARX应用程序定义的子程序。

2.3 程序结构

C,VC,VB等采用“中缀表示法”

例如:

X=3.4

AutoLISP采用的是“前缀表示法“

例如:

(setq x 3.4)

表达式X=(A+B)*C在AutoLISP中表示为:

(setq X (* ( + A B) C) )

(setq a 2.3 )(setq b 6.7)(+ a b )

(defun C:ff(/)

(setq a 2.3 )

(setq b 6.7)

(setq c (+ a b ) )

)

2.4 求值、表达式及变量

求值

每个LISP程序的核心是一个求值器。求值器读入用户的输入行(一个符号表达式),对其进行计算,然后返回计算结果。

AutoLISP的求值过程如下:

(1)整形数、实型数、字符串对、文件指针和子程序以它们本身的值作为结果。

(2)符号以它们当前的约束值作为计算结果。

(3)表根据其第一个元素的类型来进行求值。

表达式

所有AutoLISP表达式均为下述形式:

(function_name [arguments]……)

左边以左括号“(”开始,其后由函数名和函数的参数组成,最后以右括号“)”结束。每个表达式都有一个返回值。表达式的参数可以是一个表达式,它的返回值将被外层表达式使用。

变量

AutoLISP的变量有四种类型:整型数、实型数、字符串和表。变量的类型根据所赋的值自动确定,并一直保持到下一次再赋值为止。

AutoLISP用setq函数给变量赋值,格式如下:

(setq 变量名值)

其中参数“值”可以是一个表达式,执行结果返回变量的值。

例如:

(setq x 5) x=5 整型数

(setq x 5.0) x=5.0 实型数

(setq x “Hello”) x=”hello”字符串

(setq x ‘(3.7 6.5) ) x=(3.7 6.5) 表

当要用变量来响应AutoCAD提示时,只需在变量名前加一个“!”即可。

例如:

command:

(setq p1 ‘(100 100) )

(setq p2 ‘(200 200) )

(command “line” p1 p2)

函数:

(defun C:aa1(/)

(setq p1 '(100 100))

(setq p2 '(200 200))

(command "line" p1 p2)

)

或者:

command:line

From point:!p1

三、赋值与数值计算函数

1. 赋值函数 (set 符号表达式)与(setq 符号1 表达式1……)

(setq a 3.0)

(setq a 3.0 b 15)

(setq L ‘(a b))

区别:

set函数对第一个变元(符号)进行计算,并可将一个新值间接赋给另一个符号,而setq则不然。

?(setq a ‘b) 将变量名b赋给变量a

?(set a 100) 返回100,且b的值为100

若将set函数的第一个变元加上引用符号,则等价于setq函数。

?(setq a 3.0) 等价于(set ‘a 3.0) 或 (set (quote a) 3.0)

2. 加函数(+数数……)

(+ 2 9)

(+ 2 9 8 1 )

3. 减函数(+数数……)

(- 2 9)

(- 2 9 8 1 )

4. 乘函数(* 数数……)

(* 2 9)

(* 2 9 8 1 )

5. 除函数(/ 数数……)

(/ 8 4)

(/ 24 4 2)

6. 加1函数(1+数数……)

(1+ 3 )

(1+ -7)

7. 减1函数(1+数数……)

(1+ 3 )

(1+ -7)

8. 求绝对值函数(abs 数)

(abs -7)

9. 求最大值函数(max 数数……)

(max -7 16)

10. 求最小值函数(min 数数……)

(min -7 16)

11. 平方根函数(sqrt 数)

(sqrt 16)

12. 乘方函数(expt 数数)

(expt 2 4)

13. 求e的任意次方函数(exp 幂)(exp 2.2)

14. 对数函数(log 数)

(log 4.5)

15. 正弦函数(sin 角)

(sin pi)

(sin (/ pi 2))

16. 余弦函数(cos 角)

(cos pi)

(cos (/ pi 2))

17. 反正切函数(atan 数1 [数2])(atan 0.5)

(atan 1.0 2.0)

18. 求余数函数(rem 数1 数2)(rem 8 3)

(rem 3 4.0)

19. 最大公约数函数(gcd 数1 数2)(gcd 12 20)

(gcd 81 57)

四、自定义函数

defun函数

格式:(defun 符号变元表(形参/局部变量)表达式……)

符号为所要定义的函数名称,将来用户在使用这一自己定义的函数时就用次函数名称调用。

变元表被一个前后均有空格的斜杠符号“/”分成两个部分(形参/局部变量):前一部分为形参部分,在调用函数时接受参数传递而转换为实参;后一部分为局部变量,仅用于函数内部,不参与参数传递。

注:

(1)变元表可以是空格,此时在调用函数时无参数传递。

(2)变元表中的形参与局部变量均只在所定义的函数中起作用,甚至可以与某些外部变量同名,而不会对外部变量造成影响。

用defun函数定义AutoCAD新命令

格式:(defun C:命令名变元表(/局部变量)表达式……)

命令名为所要定义的新命令的名称,其前必须有“C:”,命令名的后面必须带有一张没有形参的变元表。

画一个正方形的命令:

(defun C:square ( / pt1 pt2 pt3 pt4 len)

(setq pt1 (getpoint "Low left corner:"))

(setq len (getdist pt1 "Length of one side:"))

(setq pt2 (polar pt1 0.0 len))

(setq pt3 (polar pt2 (/ pi 2.0) len))

(setq pt4 (polar pt3 pi len))

(command "PLINE" pt1 pt2 pt3 pt4 "c")

)

五程序分支与循环函数

1.条件函数(if 条件式1 [式2])

(if (= 1 3) "yes" "no")

(if (= 2 (+ 1 1)) "yes" "no")

2. 分支函数

(cond (条件1 式1 ……)

(条件2 式2 ……)

……)

例如:

(cond ((minusp a)(- a))

(T a)

)

(cond ((minusp a) (- a) ) (T a))

3. 重复函数(repeat 次数式1 式2 ……)

(defun C:add1( / )

(setq s 0 a 1)

(repeat 100

(setq s (+ s a))

(setq a (1+ a))

)

(print s)

)

4.循环函数(while 条件式1 式2 ……)

(defun C:add2( / )

(setq s 0 a 1)

(while (< a 101)

(setq s (+ s a))

(setq a (1+ a))

)

(print s)

)

5.求多个表达式值的函数(progn 式1 式2 ……)(defun C:progn( / )

(if T

(progn

(setq a 10)

(setq b (+ a 20))

)

(print b)

)

)

六、 逻辑运算函数

AutoLISP 用T 表示逻辑真,用NIL 表示逻辑假。AutoLISP 的逻辑运算分为两种:一种是数值的逻辑运算,它将数值化为二进制数,然后按位进行逻辑运算,仍以数值为其结果(返回值);另一种是根据函数的要求对后面的表达式进行测.....................试,若满足要求,则函数返回.............T .(逻辑真),若不满足要求则返回...............NIL ...(逻辑假)。...... 1. 逻辑“与”函数(and 表达式 ……) (setq a 5) (setq b nil) (setq c “st”) (and a c) (and b c)

2. 逻辑“或”函数(or 表达式 ……) (or b c)

(or 0 ‘() b)

3. 逻辑“非”函数(not 表达式 ……) (not b) (not c)

4. 等于函数(= 原子 原子 ……) (= 4 4.0) (= 4 4 3)

(= “me” “me”) (= “me” “you”)

5. 不等于函数(/= 原子 原子 ……) (/= 4 4.0)

(/= “me” “me”)

6. 小于函数(< 原子 原子 ……) (< 10 20)

(< “b” “c” ) (< 2 3 4 4)

7. 小于等于函数(<= 原子 原子 ……) (< 2 3 4 4) (<= 2 4 3 )

8. 大于函数(> 原子 原子 ……) (> 20 10 )

(> “e” “c” )

9. 大于等于函数(>= 原子 原子 ……) (>= 8 5 4 4)

(>= 2 4 6.0 8 78 )

10. 原子测试函数(atom 项)

若“项”为表,则返回NIL ,否则返回T 。任何不是表的元素都被认为是原子。 (setq a ‘(x y z)) (setq b ‘a ) (atom a) (atom b) (atom ‘a)

11. 表测试函数(listp 项)

若“项”为表,则函数返回T;否则返回NIL。

(listp a)

(listp ‘a)

(listp ‘(x y))

12. 原子值测试函数(boundp 项)

若原子有约束值,则返回T,否则返回NIL。若某原子的值为表,则被认为该原子无值。

(boundp a)

(boundp 'a)

(boundp b)

13. 空测试函数(null 项)

若“项”的约束值为空(NIL),则函数返回T;否则返回NIL。

(null a)

(null 'a)

(null ‘())

14. 数值测试函数(numberp 项)

若“项”为数值(整数或实数),则函数返回T;否则返回NIL。

(setq a 123)

(setq b ‘a)

(numberp a)

(numberp b)

15. 负值测试函数(numberp 项)

若“项”的值为数值且为负数,则函数返回T;否则返回NIL。

(minusp -1)

(minusp 32.1)

16. 零值测试函数(zerop 项)

若“项”的值为数值且为零,则函数返回T;否则返回NIL。

(zerop -0.1)

(zerop 0.0)

17. 相同表达式测试函数(eq 式1 式2)

若“式1”与“式2”完全相同,则函数返回T;否则返回NIL。

(setq f1 ‘(a b)) (setq f2 ‘(a b))

(setq f3 f2)

(eq f1 f2)

(eq f2 f3)

该函数测试两个表达式是否受相同的目标约束。

18. 相等测试函数(equal 式1 式2)

该函数测试两个表达式的值是否相等,相等返回T;否则返回NIL。

(equal f1 f2)

(equal f2 f3)

19. 字符匹配测试函数(wcmatch 字符串模式)

该函数按通配符的匹配模式测试字符串与模式是否相同,若相同该函数返回T;否则返回NIL。

(wcmatch “Name” “N*”) (wcmatch “Name” “*b*”)

七字符串与类型转换函数

该类函数可以对字符串进行处理,对数据进行转换,对数值进行单位制的转换,以及对点进行坐标系的转换等。

1. ASCII码转换函数(ascii 字符串)

(ascii “A”)

(ascii “Big”)

2. 字符转换函数(chr 字符串)

(chr 65)

(chr 66)

3. 字符串长度函数(strlen 字符串……)

(strlen “about”)

(strlen “a” “b” “c”)

(strlen “”)

4. 字符串连接函数(strcat 字符串……)

(strcat “a” “about”)

(strcat “a” “b” “c”)

5. 求子字符串函数(substr 字符串起点 [长度])

(substr “abcde” 2 1)

(su bstr “abcde” 3 2)

(substr “abcde” 2 )

6. 字符串大小写函数(strcase 字符串 [方式])

(strcase “Sample” T)

(strcase “Sample”)

7. 整型变实型函数(float 数)

(float 3)

8.实型变整型函数(fix 数)

(fix 6.5)

9. 整型变字符串函数(itoa 数)

(itoa 65)

10. 字符串变整型函数(atoi 字符串)

(atoi “1998”)

(atoi “19.98”)

11. 字符串变实型函数(atof 字符串)

(atof “1998”)

(atof “19.98”)

八、表处理函数

该类函数可以对表进行取原子、测表长和替换元素等多种操作。

1. 引用函数(quote 表达式)

该函数返回未经计算的表达式。该函数的作用是告诉AutoLISP的求值程序不要对后面的表达式求值。

(quote (x y z))

(quote a)

2. 取表中第一个元素的函数(car 表)

(car ‘(a b c))

(car ‘((a b) c))

(car ‘())

3. 取子表函数(car 表)

(cdr ‘(a b c))

4. 取表中最后一个元素函数(last 表)

(last ‘(a b c))

5. 取表第n个元素函数(nth n 表)

(nth 2 ‘(a b c d e ))

(nth 0 ‘((a b) c (d e)))

6. 测表长函数(length 表)

(length ‘(a b c))

7. 建立表的函数(list 表)

(list ‘(a b c) ‘a 1 ‘b)结果:((A B C) A 1 B)

8. 连接表的函数(append 表1 表2 ……)

(append ‘(a b) ‘(c d))结果: (A B C D)

(append ‘((a) (b)) ‘((c) (d)))结果:((A) (B) (C) (D))

9. 向表中添加元素的函数(cons 新元素表)

(cons ‘a ‘(c d))结果:(A C D)

(cons ‘(a b) ‘(c d)) 结果:((A B) C D)

10.表倒置函数(reverse 表)

(reverse ‘(a b c))

九、交互数据输入函数及相关的计算函数

本节所介绍的函数具有从键盘和光标设备等输入装置读入数据的功能。同时也介绍了对这些数据进行相关计算的一些函数。

1. 整型数输入函数(getint [提示])

该函数等待用户输入一个整型数,并返回该整型数。提示部分可有可无。例如:

(getq num (getint))

(getq num (getint “Enter a number:”))

2. 实型数输入函数(getreal [提示])

该函数等待用户输入一个实型数,并返回该实型数。它和getreal的用法完全相同。

3. 字符串输入函数(getstring [cr] [提示])

该函数等待用户输入一个字符串,并返回该字符串(最大长度为132个字符)。如果提供了cr且cr不为NIL,则输入的字符串中可以有空格,此时只有用回车来终止输入,否则可以用空格来终止输入。

例如:

(setq s (getstring “W hat’s your name?”))

用户输入:

Xiaosan 返回“Xiaoshan“

(setq s (getstring T “W hat’s your name?))

用户输入:

Zhang Xiaoshan 返回“Zhang Xiaoshan “

4. 点输入函数(getpoint [基点] [提示])

该函数等待用户输入一个点。用户可用键盘输入点的坐标或用光标选点的方式输入一个点。若有基点,则AutoCAD会从该点向当前的光标位置画一条可拖动的直线。

例如:

(setq p (getpoint “Where?”))

(setq p (getpoint ‘(2.0 3.6) “Second point:”))

5. 距离输入函数(getdist [基点] [提示])

该函数等待用户输入一个距离值或用光标输入两个点,函数将返回两点间的距离值。若有基点,则只需再输入一个点,该点与基点间的距离就是输入的值。

例如:

(setq dist (getdist ‘(3.5 5.1) “Distance:”))

6. 矩形对角点输入函数(getcorner 基点 [提示])

该函数等待用户输入一个点,并将该点返回。与getpoint函数不同的是它必须有基点,且当用户移动光标时,屏幕上画一个由基点和当前光标点为两个对角点的矩形。

7. 角度输入函数(getangle [基点] [提示])

该函数等待用户输入一个角度,并将该角度以弧度值返回。Getangle在度量角度时,以变量ANGBASE设置的当前角度为零弧度,角度按逆时针方向为正。用户可以用键盘输入一个数值来指定一个角度。也可用指定屏幕上两个点的方式输

相关主题
相关文档
最新文档