상세 컨텐츠

본문 제목

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

IT & Programming/LISP 공부

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

본문

반응형

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

 

(rtos <NUMBER> [<MODE><PRECIS>])

Mode와 소수점 개수 option에 따라 숫자를 문자열로 변환한다. mode값은 아래와 같다. 이 함수 역시 사용 빈도가 매우 높다.

 

1  Scientific 
2  Decimal 
3  Engineering (feet and decimal inches) 
4  Architectural (feet and fractional inches) 
5  Fractional 

예 : Command: (setq x 17.5) 
17.5 
Command: (setq fmtval (rtos x 1 4)) 
"1.7500E+01" 
Command: (setq fmtval (rtos x 2 2)) 
"17.50" 
Command: (setq fmtval (rtos x 3 2)) 
"1'-5.50\"" 
Command: (setq fmtval (rtos x 4 2)) 
"1'-5 1/2\"" 
Command: (setq fmtval (rtos x 5 2)) 
"17 1/2" 
Command: (setvar "unitmode" 1) 
1 
Command: (setq fmtval (rtos x 3 2)) 
"1'5.50\"" 
Command: (setq fmtval (rtos x 4 2)) 
"1'5-1/2\"" 
Command: (setq fmtval (rtos x 5 2)) 
"17-1/2" 
 

(setq <SYM1><EXPR1>...)

변수를 정의한다.

예 : Command: (setq a 5.0) 
5.0 
Command: (setq b 123 c 4.7) 
4.7 
Command: (setq s "it") 
"it" 
Command: (setq x '(a b)) 
(A B) 

(setvar <VARNAME><VALUE>)

시스템 변수를 설정한다. 시스템 변수에 대한 자세한 설명은 다음 강좌를 참조.

예 : Command: (setvar "FILLETRAD" 0.50) 
0.5 

(sin <ANGLE>)

각도의 사인 값을 return한다. 이때 각도는 라디안 값이다.

예 : Command: (sin 1.0) 
0.841471 
Command: (sin 0.0) 
0.0 

(sqrt <NUMBER>)

숫자의 제곱근을 구한다.

예 : Command: (sqrt 4) 
2.0 
Command: (sqrt 2.0) 
1.41421 

(ssget [<MODE>][<PT1><PT2>])

Entsel 함수와는 달리 객체의 다중 선택이 가능한 함수이며, 사용 빈도가 가장 높은 함수 중 하나이다. mode값에 따라 다양한 선택 방법들이 있다. mode값은 아래와 같다. 선택 방법은 실제 AutoCAD 상에서 사용되는 선택 방법과 거의 유사하다.

 

C  Crossing selection
CP  Cpolygon selection
F  Fence selection
L  Last
P  Previous
W  Window selection
WP  WPolygon
X  All objects

 

예 : Command: (ssget) 
<Selection set: 2> 
Command: (ssget '(2 2)) 
nil 
Command: (ssget "_P") 
<Selection set: 4> 
Command: (ssget "_C" '(0 0) '(1 1)) 
<Selection set: b> 
Command: (ssget "_W" '(0 0) '(5 5)) 
<Selection set: d> 
Command: (setq pt_list '((1 1)(3 1)(5 2)(2 4))) 
((1 1) (3 1) (5 2) (2 4)) 
Command: (ssget "_CP" pt_list) 
<Selection set: 13> 
Command: (ssget "_WP" pt_list '((0 . "LINE") (62 . 5))) → line중 파란색만 선택
<Selection set: 8> 

(sslength <SS>)

다중 선택된 체들의 개수를 return한다.

 

(ssname <SS><INDEX>)

nth 유사한 함수로 선택된 객체들에서 정수 값에 해당되는 순서의 객체를 returm한다.

 

(ssadd [<ENAME>][<SS>])

선택 체들에 객체를 추가한다.

 

(ssdel [<ENAME>][<SS>])

선택 객체들 중에서 해당 객체를 삭제한다.

 

위의 함수들을 이용해서 실무 예제를 직접 만들어보자. 비어있는 도면에 line 5개와 circle 5개를 임의로 그려보자. 크기와 위치에 상관없이 그린다. 서로 교차되어도 상관없다. 함수들을 사용하기 위해서는 객체들의 특성과 DXF code 완벽하게 이해하고 있어야만 한다. 도면에 그림을 완성하였다면 아래의 code vlisp editor 복사해 놓고 실행해 보자.

 

(defun c:test ()

  (setvar "cmdecho" 0)

  (prompt "\nSelect objects : ")

  (setq a (ssget))

  (setq line_list (ssadd))

  (setq circle_list (ssadd))

(repeat (sslength a)

    (setq b (ssname a 0))

    (setq c (entget b))

    (setq d (cdr (assoc 0 c)))

    (if (= d "LINE")

      (progn

             (ssadd b line_list)

             (setq a (ssdel b a))

      ) ; end of 1st progn

      (progn

             (ssadd b circle_list)

             (setq a (ssdel b a))

      ) ; end of 2nd progn

    ) ; end of if

  ) ; end of repeat

  (command "change" circle_list "" "p" "c" 1 "")

  (command "change" line_list "" "p" "c" 2 "")

  (setvar "cmdecho" 1)

  (prompt "\nProgram has been completed...")

  (princ)

) ; end of defun

 

프로그램은 ssdel 함수를 설명하기 위해 억지로 만든 것이고, 보통은 아래와 같이 만든다.

(defun c:test ()

  (setvar "cmdecho" 0)

  (prompt "\nSelect objects : ")

  (setq a (ssget))

  (setq line_list (ssadd))

  (setq circle_list (ssadd))

  (setq n 0)

  (repeat (sslength a)

    (setq b (ssname a n))

    (setq c (entget b))

    (setq d (cdr (assoc 0 c)))

    (if (= d "LINE")

      (progn

             (ssadd b line_list)

             (setq n (1+ n))

      ) ; end of 1st progn

      (progn

             (ssadd b circle_list)

             (setq n (1+ n))

      ) ; end of 2nd progn

    ) ; end of if

  ) ; end of repeat

  (command "change" circle_list "" "p" "c" 1 "")

  (command "change" line_list "" "p" "c" 2 "")

  (setvar "cmdecho" 1)

  (prompt "\nProgram has been completed...")

  (princ)

) ; end of defun

 

화면에 어떤 변화가 일어났는지 보았다면 이제 LISP 대해 서서히 눈을 떠가고 있다는 것을 직감하고 있을지도 모른다. 프로그램의 맛을 보았으니 이제 해석도 당연히 해야 한다. 아래의 설명문을 보고 차근차근 이해해나가길 바란다.

 

(defun c:test () → 함수 정의, 광역변수 사용

  (setvar "cmdecho" 0) → 시스템 변수 설정

  (prompt "\nSelect objects : ") → 메시지 출력

  (setq a (ssget)) → 변수 a 마우스로 선택한 다중 객체들의 조합을 저장

  (setq line_list (ssadd)) → 변수 line_list 비어있는 선택 집합을 생성한다.

  (setq circle_list (ssadd)) → 변수 circle_list 비어있는 선택 집합을 생성한다.

(repeat (sslength a) → 변수 a 선택된 객체들의 개수만큼 반복한다.

    (setq b (ssname a 0)) → 변수 b 선택집합인 변수 a 번째 요소를 저장한다.

    (setq c (entget b)) → 변수 c 변수 b 저장된 객체의 데이터베이스를 불러들인다.

    (setq d (cdr (assoc 0 c))) → 변수 d 변수 c 저장된 데이터베이스 중에서 DXF code

                                        0 객체 이름만을 골라 (0 . “LINE”) 또는 (0 . “CIRCLE”)

                                        불러들인 cdr 함수로 “LINE” 또는 “CIRCLE”만을 저장한다.

    (if (= d "LINE")  만약 변수 d “LINE”이라면, 객체 b line 객체라면

      (progn  조건문이 참이면 아래를 실행한다.

             (ssadd b line_list) → 객체가 line이면 변수 line_list 객체를 추가한다.

             (setq a (ssdel b a)) → 객체 b 선택 조합 a에서 삭제한다.

      ) ; end of 1st progn

      (progn → 조건문이 거짓이면 아래를 실행한다.

            (ssadd b circle_list) → 객체가 circle이면 변수 circle_list 객체를 추가한다.

             (setq a (ssdel b a)) → 객체 b 선택 조합 a에서 삭제한다.

      ) ; end of 2nd progn

    ) ; end of if

  ) ; end of repeat

  (command "change" circle_list "" "p" "c" 1 "") → circle들의 색깔을 모두 빨간색으로 수정

  (command "change" line_list "" "p" "c" 2 "") → line들의 색깔을 모두 노란색으로 수정

  (setvar "cmdecho" 1) → 시스템 변수 값을 다시 돌려준다.

  (prompt "\nProgram has been completed...") → 메시지 출력

  (princ)

) ; end of defun

 

이와 같이 함수들을 적시 적소에 사용함으로써 사용자가 원하는 프로그램을 개발하는데, 원동력은 바로 이와 같은 예제나 샘플 프로그램을 많이 접하는 방법뿐이다.

 

(strcase <STRING>[<WHICH>)]

문자열을 대문자로 변환한다. 이때 option 생략되거나 nil이면 대문자로, T이면 소문자로 변환한다.

: Command: (strcase "Sample")

"SAMPLE"

Command: (strcase "Sample" T)

"sample"

 

(strcat <STRING1><STRING2>..)

문자열을 하나의 문자열로 합친다.

예 : Command: (strcat "a" "bout") 
"about" 
Command: (strcat "a" "b" "c") 
"abc" 
Command: (strcat "a" " " "c") → 띄어쓰기를 하는 방법
"a c" 

(strlen <STRING>)

문자열의 글자 수를 return한다.

예 : Command: (strlen "abcd") 
4 
Command: (strlen "ab") 
2 
Command: (strlen "one" "two" "four") 
10 

(subst <NEWITEM><OLDITEM><LIST>)

list에서 기존의 원소를 새로운 원소로 대체한다.

예 : Command: (setq sample '(a b (c d) b)) 
(A B (C D) B) 
Command: (subst 'qq 'b sample) 
(A QQ (C D) QQ) 
Command: (subst 'qq 'z sample) 
(A B (C D) B) 
Command: (subst 'qq '(c d) sample) 
(A B QQ B) 
Command: (subst '(qq rr) '(c d) sample) 
(A B (QQ RR) B) 
Command: (subst '(qq rr) 'z sample) 
(A B (C D) B) 

(substr <STRING><START><LENGTH>)

문자열에서 지정된 숫자만큼 글자 개수 뒤의 문자만을 출력한다. 이때 개수가 생략되면 끝까지 출력한다.

예 : Command: (substr "abcde" 2) 
"bcde" 
Command: (substr "abcde" 2 1) 
"b" 
Command: (substr "abcde" 3 2) 
"cd" 
 

(tblnext <NAME> [<rewind>])

심벌 테이블을 순서대로 return한다. 여기서 심벌이란 "LAYER", "LTYPE", "VIEW", "STYLE", "BLOCK", "UCS", "APPID", "DIMSTYLE", "VPORT" 등을 말한다. 이 함수의 사용 예를 위해 빈 도면에 layer 5개를 만들어 본다. 이름이 1인 layer는 빨간색, 2번 layer는 노란색, 3번 layer는 녹색, 4번 layer는 하늘색, 5번 layer는 파란색으로 설정한다. 그리고 아래의 방법으로 확인하면 그 결과를 확인할 수 있다. 여기서 2번은 layer의 이름을, 62번은 layer의 색깔을 의미한다는 것을 알 수 있다.

예 : Command: (tblnext "layer")
((0 . "LAYER") (2 . "0") (70 . 0) (62 . 7) (6 . "Continuous"))
Command: (tblnext "layer")
((0 . "LAYER") (2 . "1") (70 . 0) (62 . 1) (6 . "Continuous"))
Command: (tblnext "layer")
((0 . "LAYER") (2 . "2") (70 . 0) (62 . 2) (6 . "Continuous"))
Command: (tblnext "layer")
((0 . "LAYER") (2 . "3") (70 . 0) (62 . 3) (6 . "Continuous"))
Command: (tblnext "layer")
((0 . "LAYER") (2 . "4") (70 . 0) (62 . 4) (6 . "Continuous"))
Command: (tblnext "layer")
((0 . "LAYER") (2 . "5") (70 . 0) (62 . 5) (6 . "Continuous"))

(tblsearch <NAME><SYM>[<setnext>])

심벌 테이블에서 원하는 심벌을 검색해서 찾는다.

예 : Command: (tblsearch "style" "standard") 
((0 . "STYLE") (2 . "STANDARD") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.3)
(3 . "txt") (4 . "")) 

(terpri)

\n 같은 역할을 하는 함수로 아래로 새로운 줄에 메시지를 출력하게 도와준다.

 

(textscr)

(graphscr)과 반대로 도면을 보여주는 화면에서 text 화면으로 전환한다.

 

(type <ITEM>)

주어진 item의 type을 return한다.

(setq a 123 r 3.45 s "Hello!" x '(a b c))
(setq f (open "name" "r"))
(type 'a)                   returns  SYM
(type a)                    returns  INT
(type f)                    returns  FILE
(type r)                    returns  REAL
(type s)                    returns  STR
(type x)                    returns  LIST
(type +)                    returns  SUBR
(type nil)                  returns  nil
 

(ver)

LISP의 버전을 return한다.

예 : Command: (ver) 
"Visual LISP 2004 (en)" 
 

(while <TESTEXPR><EXPR>)

조건식이 참이면 무한 반복한다. 조건식이 거짓이면 빠져나간다.

(setq test 1)
(while (<= test 10)
  (prompt (strcat “\n변수 test의 값은 ”(itoa test) “입니다”))
  (setq test (1+ test))
)

 

 

(write-line <STRING> [<FILENAME>])

read-line함수의 반대 개념으로 text 파일에 한 줄씩 추가하는 함수이다. read-line의 예제에서 option의 “r”을 “w”로 수정하고 사용하면 된다.

 

(zerop <ITEM>)

숫자가 0(zero)이면 T을 return한다.

예 : Command: (zerop 0) 
T 
Command: (zerop 0.0) 
T 
Command: (zerop 0.0001) 
nil
 

이상으로 강좌를 마치겠습니다. 이번 강좌는 어떠셨나요? 예제들을 천천히 번씩 따라 해보시고, 제가 보여드린 기존 lisp 해석 방법에 대해 꾸준히 연습해 보시고, 같은 구문이라도 여러 반복해서 사용해보시면 금방 LISP 구조가 머리 속에 들어올 것입니다. 수고 많으셨습니다. 저는 다음 강좌에서 뵙겠습니다.

 

728x90
반응형

관련글 더보기

댓글 영역