상세 컨텐츠

본문 제목

4. LISP의 기초 및 필수 기본 함수 설명과 예제 3부

IT & Programming/LISP 공부

by 그림아이 2022. 1. 26. 08:00

본문

반응형

이전 시간에 이어 LISP의 기초 및 필수 기본 함수 설명과 예제를 진행합니다.

 

(assoc <ITEM><ALIST>)

list에서 item을 포함한 list만을 추출해내는 함수.
예 : Command: (setq al '((name box) (width 3) (size 4.7263) (depth 5))) → 변수 al 저장
((NAME BOX) (WIDTH 3) (SIZE 4.7263) (DEPTH 5)) 
Command: (assoc 'size al) 
(SIZE 4.7263) 
Command: (assoc 'weight al) 
nil → 해당하는 list가 없으므로 nil을 출력.

(atan <NUM1> [<NUM2>])

아크 탄젠트 값으로 변환해줌. atan함수 뒤에 숫자가 두 개가 올 때는 두 값을 나눈 값을 이용해 변환해 줌.
예 : Command: (atan 1) 
0.785398 
Command: (atan 1.0) 
0.785398 
Command: (atan 0.5) 
0.463648 
Command: (atan 1.0) 
0.785398 
Command: (atan -1.0) 
-0.785398 
Command: (atan 2.0 3.0) 
0.588003 
Command: (atan 2.0 -3.0) 
2.55359 
Command: (atan 1.0 0.0) 
1.5708 

(atof <STRING>)

문자열을 실수로 변환
예 : Command: (atof "97.1") 
97.1 
Command: (atof "3") 
3.0 
Command: (atof "3.9") 
3.9

(atoi <STRING>)

문자열을 정수로 변환
예 : Command: (atoi "97") 
97 
Command: (atoi "3") 
3 
Command: (atoi "3.9") 
3 

(car <LIST>)

list중에서 가장 첫 번째 원소를 출력. 보통 X좌표 값을 구할 때 사용한다.
예 : Command: (car '(a b c)) 
A 
Command: (car '((a b) c)) 
(A B) 
Command: (car '()) 
nil 

(cadr <LIST>)

list중에서 가장 첫 번째 원소를 출력. 보통 Y좌표 값을 구할 때 사용한다.
예 : Command: (setq pt2 '(5.25 1.0)) 
(5.25 1.0) 
Command: (cadr pt2) 
1.0 
Command: (cadr '(4.0)) 
nil 
Command: (cadr '(5.25 1.0 3.0)) 
1.0 

(caddr <LIST>)

list중에서 가장 첫 번째 원소를 출력. 보통 Z좌표 값을 구할 때 사용한다.
예 : Command: (setq pt3 '(5.25 1.0 3.0)) 
(5.25 1.0 3.0) 
Command: (caddr pt3) 
3.0 
Command: (caddr '(5.25 1.0)) 
nil 

(cdr <LIST>)

list에서 첫 번째 요소만 빼고 나머지를 출력한다.
예 : Command: (cdr '(a b c)) 
(B C) 
Command: (cdr '((a b) c)) 
(C) 
Command: (cdr '()) 
nil 
Command: (cdr '(a . b)) 
B 
Command: (cdr '(1 . "Text")) 
"Text" 

(chr <NUMBER>)

Ascii 값에 해당하는 문자열을 return한다.
예 : Command: (chr 65) 
"A" 
Command: (chr 66) 
"B" 
Command: (chr 97) 
"a" 

(close <FILENAME>)

Text 파일을 닫는다.

예 : (setq fil "SOMEFILE.TXT") → 변수 fil에 somefile.txt 파일을 저장한다.
(setq x (open fil "r") ct 0) → open 함수를 이용해 text 파일을 읽기 모드로 열고
변수 x에 저장 한다. 변수 ch는 정수 0(zero)이다.
(while (read-line x) → text 파일을 차례대로 한 줄씩 읽는다. While 구문이므로 
빈 줄이 아니라면 계속해서 반복한다.
  (setq ct (1+ ct)) → 변수 ch에 1을 더한다.
) ; end of while
(close x) → text 파일을 닫는다. 이 때 이 구문을 이용해 반드시 닫아주어야 한다.

(command <ARGS>...)

AutoCAD 명령을 수행한다.

: (command “line” p1 p2 “”) 이전에 반드시 변수 p1, p2 point 좌표값을 지정해 주어야 한다.

    (command “pline” p1 p2 p3 “c”)

 

(cond (<TEST1><RESULT1>)...)

If문을 확장시킨 함수로 if 함수와는 차이가 있다. If 함수는 가지 조건에 대해 T이거나 nil 경우만을 취급하지만 cond 함수는 조건의 한계가 없고 무한하다.

(cond
  ((= s "Y") 1) 
  ((= s "y") 1) 
  ((= s "N") 0) 
  ((= s "n") 0) 
  (t nil)
) ; end of cond

(cons <NEW FIRST ELEMENT><LIST>)

새로운 list를 생성하는데 이 때 원소가 두 개일 경우에는 가운데 점으로 원소를 구분한다.
이 함수는 DXF code를 다룰 때 흔히 사용된다.
예 : Command: (cons 'a '(b c d)) 
(A B C D) 
Command: (cons '(a) '(b c d)) 
((A) B C D) 
Command: (cons 'a 2) 
(A . 2) 

(cos <ANGLE>)

라디안 각도에 대한 코사인 값을 return.
예 : Command: (cos 0.0) 
1.0 
Command: (cos pi) 
-1.0 

(defun <SYM><ARG LIST><EXPR>...)

LISP 함수를 정의함.

예 : (defun myfunc (x y) ...)         함수가 2개의 인수를 받음
(defun myfunc (/ a b) ...)       2개의 지역변수를 사용
(defun myfunc (x / temp) ...)    1개의 인수, 1개의 지역변수를 사용
(defun myfunc () ...)            인수를 사용하지 않고, 광역변수를 사용

(distance <PT1> <PT2>)

두 점 사이의 거리를 구함.
예 : Command: (distance '(1.0 2.5 3.0) '(7.7 2.5 3.0)) 
6.7 
Command: (distance '(1.0 2.0 0.5) '(3.0 4.0 0.5)) 
2.82843 

(entlast)

가장 최근에 생성된 객체를 입력 받음. 아래의 예를 참조.

 

(entsel [<PROMPT>])

개의 객체만을 선택하여 입력 받음. 아래의 예를 참조.

 

(entdel <ENAME>)

객체를 지움. 아래의 예를 참조.

 

(entget <ENAME>)

입력 받은 객체를 데이터베이스로 변환하여 입력 받음. DXF code 밀접한 관련. 아래의 예를 참조.

 

(entmod <ENAME>)

객체의 데이터베이스를 수정하여 update 함. 아래의 예를 참조.

객체 함수 사용 : 아래의 code vlisp editor 그대로 저장해서 실행해 보자.

 

(defun c:te ()
  (setvar "osmode" 0) ; 시스템 변수 설정
  (setvar "cmdecho" 0) ; 시스템 변수 설정
  (command "line" '(0 0) '(1 1) "") ; line 객체 생성
  (command "zoom" "w" '(-0.8 1.6) '(2.0 0.4)) ; 화면을 원하는 곳으로 이동
  (setq a (entlast)) ; 마지막 생성된 객체, 즉 line 객체를 입력 받음
                     ;  프로그램 종료 후, command 창에서 !a로 확인해 보면
                     ; <Entity name: 7e808e00>와 같이 entity name을 입력 받은 것을 볼 수 있다.
  (command "change" a "" "p" "c" 1 "") ; 변수 a에 입력된 위 객체의 색깔을 빨간색으로 수정
  (setq b (entsel)) ; 사용자로부터 단 한 개의 객체를 입력 받음. 이때 변수 b를 !b로 확인해 
                    ; 보면 (<Entity name: 7e808e00> (0.402796 0.408616 0.0))와 같이 리스트로
                    ; 되어 있다. 앞의 원소는 객체 이름이고, 뒤의 원소는 선택된 좌표이다.
                    ; (setq c (entget (car b))) ; 위의 리스트에서 앞의 원소인 객체 이름을 입력
                    ; 받아 데이터베이스로 변환한다. !c로 변수를 확인해 보면
                    ; ((-1 . <Entity name: 7e808e00>) (0 . "LINE") (330 . <Entity name: 7e808d08>) 
                    ; (5 . "40") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 1)
                    ; (100 . "AcDbLine") (10 0.0 0.0 0.0) (11 1.0 1.0 0.0) (210 0.0 0.0 1.0)) 와 같이
                    ; 매우 복잡하게 이루어진 것을 확인 할 수 있다. 이 모든 데이터들을
                    ; DXF code라고 부르며 이에 대한 자세한 내용은 앞으로 진행될 강좌를
                    ; 참고 바람
  (setq d (subst (cons 62 2) (assoc 62 c) c)) ; 바로 위에서 변수 c는 list로 저장되었고,
                                              ; (cons 62 2)는 (62 . 2)를 뜻한다. 그리고
                                              ; (assoc 62 c)는 리스트 c에서 62번으로 시작하는
                                              ; list를 찾아 그 값을 취하겠다는 뜻으로 위의 list를
                                              ; 살펴보면 (62 . 1) 이라는 것을 알 수 있다.
                                              ; Subst 함수는 뒤에서도 나오지만, 결국 list c에서
                                              ; (62 . 1)을 (62 . 2)로 바꾸는 것이다. 여기서 62는
                                              ; 객체의 데이터베이스에 저장된 정보 중 색깔을
                                              ; 나타내는 DXF code로 1번은 빨간색, 1번은
                                              ; 노란색을 뜻한다. 따라서 이 구문은 객체를
                                              ; 노란색으로 수정하겠다는 구문이다.
  (entmod d) ; list내의 정보를 수정하였으므로 객체에 적용하는 구문이다.
  (setvar "cmdecho" 1)
  (princ)
) ; end of defun

위 예제를 아직은 이르지만 완벽하게 이해하게 될 때 한 단계 실력이 향상되는 것이다. 객체들을 자유자재로 이용하고 필요한 정보만을 골라낼 수 있는 능력을 빨리 키워야 한다.

 

(eq <EXPR1> <EXPR2>)

개의 표현이 같으면 T, 다르면 nil return한다.

예 : (setq f1 '(a b c)) 
(setq f2 '(a b c)) 
(setq f3 f2)
Command: (eq f1 f3) 
nil 
Command: (eq f3 f2) 
T

(equal <EXPR1> <EXPR2>)

두 개의 표현이 같으면 T, 다르면 nil을 return한다. 표현식들 뒤에 비교할 최대 허용 소수점을 넣을 수도 있다.
예 : (setq f1 '(a b c)) 
(setq f2 '(a b c)) 
(setq f3 f2)
(setq a 1.123456) 
(setq b 1.123457)
Command: (equal f1 f3) 
T 
Command: (equal a b) 
nil 
Command: (equal a b 0.000001) 
T 

(eval <EXPR>)

표현식을 평가한다.

예 : Command: (setq a 123) 
123 
Command: (setq b 'a) 
A 
Command: (eval 4.0) 
4.0 
Command: (eval (abs -10)) 
10 
Command: (eval a) 
123 
Command: (eval b) 
123 

(findfile <FILENAME>)

지정된 파일을 찾는다. 단, 명심해야 할 것은 option의 support file path에 등록된 경로에서만 찾게 되므로 반드시 경로를 확인해야 한다.

예 : Command: (findfile "abc.lsp") 
"C:\\Program Files\\AutoCAD 2004\\abc.lsp" 
Command: (findfile "xyz.txt") 
"C:\\Program Files\\AutoCAD 2004\\support\\xyz.txt" 
Command: (findfile "nosuch") 
nil 
그리고, 또 한가지 중요한 점은 lisp에서의 폴더 구분 표시는 백 슬래쉬(\)를 두 번 사용한다는 것이다.

(fix <NUMBER>)

숫자를 정수로 변환
예 : Command: (fix 3) 
3 
Command: (fix 3.7) 
3 

(float <NUMBER>)

숫자를 실수로 변환
예 : Command: (float 3) 
3.0 
Command: (float 3.75) 
3.75 

(foreach <NAME><LIST><EXPR>)

고급함수로 어렵지만 잘 이용하면 가장 사용 빈도가 높고 편리한 함수이다. LIST의 각 원소들에 동일한 조건을 적용하는 함수이다.

예 : Command: (foreach n '(a b c) (print n)) 
A 
B
C

즉, 위의 예제는 아래의 구문을 한 줄로 표현한 것과 같다.

(print a) 
(print b) 
(print c)

(getangle [<PT>][<PROMPT>])

사용자로부터 각도를 입력 받음. 시작점을 지정할 수도 있음.

예 : Command: (setq ang (getangle)) 
Command: (setq ang (getangle '(1.0 3.5))) 
Command: (setq ang (getangle "Which way? ")) 
Command: (setq ang (getangle '(1.0 3.5) "Which way? ")) 

(getcorner [<PT>][<PROMPT>])

Getpoint 함수와 함께 쓰이며 보통 사각형의 대각선 쪽의 point를 얻을 때 사용된다.

예 : Command: (getcorner '(7.64935 6.02964 0.0)) 
(17.2066 1.47628 0.0) 
Command: (getcorner '(7.64935 6.02964 0.0) "Pick a corner") 
Pick a corner(15.9584 2.40119 0.0) 

(getdist [<PT>][<PROMPT>])

사용자로부터 거리를 입력 받음.

예 : (setq dist (getdist)) 
(setq dist (getdist '(1.0 3.5))) 
(setq dist (getdist "How far ")) 
(setq dist (getdist '(1.0 3.5) "How far? "))

(getkword [<PROMPT>])

보통 intiget함수와 함께 쓰이며 한 글자로 된 문자열을 입력 받을 때 사용된다.

예 : Command: (initget 1 "Yes No") 
nil 
Command: (setq x (getkword "Are you sure? (Yes or No) ")) 
Are you sure? (Yes or No) yes 
"Yes" 
Command: (initget 1 "Yes No") 
nil 
Command: (setq x (getkword "Are you sure? (Yes or No) ")) 
Are you sure? (Yes or No) Maybe 
Invalid option keyword. 
Are you sure? (Yes or No) yes 
"Yes" 

(getpoint [<PT>][<PROMPT>])

사용자로부터 좌표로 된 한 점을 입력 받을 때 사용된다.

예 : (setq p (getpoint)) 
(setq p (getpoint "Where? ")) 
(setq p (getpoint '(1.5 2.0) "Second point: ")) 

(getreal [<PROMPT>])

사용자로부터 실수 값을 입력 받을 때 사용된다.

예 : (setq val (getreal)) 
(setq val (getreal "Scale factor: "))

(getstring [<CR>][<PROMPT>])

사용자로부터 문자열을 입력 받을 때 사용된다.

예 : Command: (setq s (getstring "What's your first name? ")) 
What's your first name? Gary 
"Gary" 
Command: (setq s (getstring T "What's your full name? ")) 
What's your full name? Gary Indiana Jones 
"Gary Indiana Jones" 
Command: (setq s (getstring T "Enter filename: ")) 
Enter filename: c:\my documents\vlisp\secrets 
"c:\\my documents\\vlisp\\secrets" 

(getvar <varname>)

시스템 변수 값을 가져온다. 보통 getvar와 setvar 함수는 함께 따라 다니며 이 함수들을 사용하기 위해서는 시스템 변수에 대해 알아야 하며, 그 수많은 종류의 변수들을 다 외울 필요는 없지만 필수적인 시스템 변수는 어느 정도 숙지하고 있어야 한다.

예 : Command: (getvar 'FILLETRAD) 
0.25 

(graphscr)

text화면에서 도면으로 되돌아 간다.

 

다음 편에서 이어집니다.

 

 

728x90
반응형

관련글 더보기

댓글 영역