AutoLISP. Praktyczny Kurs
November 17, 2022 | Author: Anonymous | Category: N/A
Short Description
Download AutoLISP. Praktyczny Kurs...
Description
21/ E{jbbojb ob mjtubdi
294
Listy są szeroko szeroko używa ywane ne prze przezz Auto AutoLISP. LISP. Są one efektywną metodą przechowywania licznych, powią zanych zanych ze sobą warto wartości jako jeden symbol. Definicja listy jest następują ca: ca: Lista jest to obiekt elementarny lub ci ą g obiektów elementarnych oddzielony spacjami i uj ęty w nawiasy. Obiekt elementarny mo że by ć atomem cyfrowym (cyfrą — — np. 10.5), atomem literowym (identyfikatorem zmiennej — np. wsp_x), łańcuchem alfanumerycznym (np. ”AutoCAD Release 12”) lub listą . Oto parę przykładów list:
(WSPOLRZEDNE_PUNKTU 5 5 0) jest listą czteroelementową , składają cą się z czterech atomów — jednego literowego i trzech cyfrowych. (LISTA_1 (x 10 "acad")) jest listą dwuelementow dwuelementową , w której pierwszy pierwszy eleme element nt jest atomem literowym, natomiast natomiast drugi element jest listą trójelementow trójelementową , składają cą si się z atomu cyfrowego, atomu literowego oraz łańcucha alfanumerycznego. Powyższy typ listy nazywany jest również listą „zagnieżdżoną ” lub „podrzędną ”. ”. () jest natomiast listą pust pustą . Programy omówione w tym rozdziale PROG_037.LSP Przykład tworzenia listy z wykorzystaniem funkcji list oraz append. PROG_038.LSP Program do zamiany n-tego elementu listy — wersja 1.
295
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst PROG_039.LSP Program do zamiany n-tego elementu listy — wersja 2. PROG_040.LSP Program do wyszukiwania minimum i maksimum na podanej li ście — wersja 1. PROG_041.LSP Program do wyszukiwania minimum i maksimum na podanej li ście — wersja 2. PROG_042.LSP Program do ustalenia pozycji elementu na podanej li ście. PROG_043.LSP Program Progra m do wyświetlenia na ekranie tekstowym wybranych elementów z listy. PROG_044.LSP Program do usuwania wybranego elementu na podanej liście. PROG_045.LSP Program do usuwania wybranej grupy elementów na podanej li ście — wersja 1. PROG_046.LSP Program do usuwania wybranej grupy elementów na podanej li ście — wersja 2. PROG_047.LSP Program do usuwania elementów listy o podanych numerach (indeksach). PROG_048.LSP Program do sortowania listy. PROG_049.LSP Program wypisują cy cy listę DXF dla dowolnego elementu. PROG_050.LSP Przykład wykorzystania identyfikatorów elementów. PROG_051.LSP Modyfikacja elementów z wykorzystaniem funkcji entmod. PROG_052.LSP Modyfikacja elementów z wykorzystaniem funkcji entmod i entupd.
Zanim przejdziemy do dalszego omawiania list, wyjaśnię Ci sposób magazynowania danych przez AutoLISP w pamięci komputera, ze szczególnym uwzględnieniem danych typu lista. Pamięć komputera podzielona jest na poszczególne komórki. Ka żda komórka posiada posia da swój niepowta niepowtarzaln rzalny y adres (tak jak numer PESEL w dowod dowodzie zie osobistym osobistym)) oraz miejsce na przechowywanie przypisanej wartości. Adres komórki wskazuje jednoznacznie na określone miejsce w pamięci komputera. Jeśli zastosujemy funkcję przypisania
21/ E{jbbojb ob mjtubdi
296
postaci: (setq x 10), to od tego momentu zmienna x b ędzie miała wartość 10. Powyższe wyrażenie interpreter AutoLISPu rozwią zuje zuje następują co: co: lokuje cyfrę 10 w komórce należą cej c ej do obszaru pamięci zarezerwowanego dla danych i zapami ętuje adres, pod który dokonał tej lokacji. Adres ten stanowi wła ściwą warto wartość przechowywaną w w identyfikatorze tyfika torze zmiennej zmiennej x. Od tej chwili, chwili, ilekro ilekroć żą damy damy podania wartości zmien zmiennej nej x, interpreter AutoLISPu podaje nam wartość przechowywaną w w komórce pamięci o adresie wskazywanym przez zmienną x x . Gdyby zmienna x została już wcześniej zadeklarowana (tzn. chcemy zmienić jej wartość), interpreter AutoLISPu nie musiałby rezerwować nowego obszaru pamięci, a tylko wstawił nową warto wartość zmiennej x w obszar pamięci (komórk ę) o podanym adresie. Instrukcję podstawienia (setq x 10) możemy więc przedstawić następują cco: o:
Kolejna instrukcja przypisania (setq y x), dokona ewaluacji zmiennej x, a jej wartość równą 10 10 ulokuje w nowym obszarze o adresie wskazywanym przez zmienn ą y. y.
Gdyby zmienną x x potraktować dosłownie (tzn. nie dokonuj ą c jej ewaluacji) i wykonać następują cą instrukcj instrukcję przypisania: (setq y (quote x) x)) )
(setq y 'x)
nową sytuacj sytuację można zilustrować następują cco: o:
Zmienna y wskazuje na zmienną x x , której wartością jest jest 10. Ewaluacja zmiennych x i y da więc następują ce ce wyniki: (eval (ev al x) (eval (ev al y) (eval (ev al 'y)
zwraca 10 zwraca 10 zwraca X
297
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Jeśli dokonamy teraz kolejnej instrukcji przypisania postaci (setq x 0), wówczas: (eval (ev al x) (eval y) (eval (eval (ev al 'x)
zwraca 0 zwraca 0
zwraca X
Trochę inaczej ma się sprawa sprawa z reprezenta reprezentacj cją list w pamięci kompu komputera. tera. Rysowana Rysowana dotychczas komórka zawierają ca ca wskazanie do wartości zmiennej stanie się dwuczęciowa. wa. Pierws Pierwsza za cz wskazu wskazuje je na war warto tość zmienne zmiennej, j, druga druga część podaje podaje adres ścio nast ępnego elementu ęść listy, który tak że jest komórk ąą dwucz dwuczęściową , itd. Z chwilą osi osi ą gnięcia końca lis listy, ty, adres adres nas nasttępnego elementu jest równy nil. Nazwa listy stanowi natomiast adres jej pierwszego elementu. Schematy budowy list przedstawione s ą na poniższych przykładach: Command: (setq (setq lis lista_ ta_1 1 (li (list st 1))↵ (1) Command:
Command: (set (setq q list lista_ a_2 2 (lis (list t 1 2 3)) 3))↵ (1 2 3) Command:
Command: (set (setq q list lista_ a_3 3 (lis (list t 1 (lis (list t 2 3) 4)) 4))↵ (1 (2 3) 4) Command:
Command: (set (setq q list lista_ a_4 4 (lis (list t 1 "A" "A" "ACA "ACAD" D" 2 (lis (list t "B" "B" "C")))↵ (1 "A "A" " "A "ACA CAD" D" 2 (" ("B" B" "C "C") ")) ) Command:
21/ E{jbbojb ob mjtubdi
298
W przykładzie ostatnim pokazany został dodatkowo sposób reprezentacji pojedynczych znaków oraz łańcuchów znaków w AutoLISPie. Poszczególn Poszc zególnee eleme elementy nty listy numerowane s ą od 0 do n – 1, gdzi gdziee n jest lic liczb zbą elementów w liście. Listy „zagnieżdżone” liczone są jako elementów jako jeden element, lecz mogą by by ć rozbijane dalej na poszczególne składniki. Przykładowo:
(1 2 3 4) jest list ą czteroelementow czteroelementową (n=4), (n=4), gdzie E1 — E4 — poszczególne elementy listy. E0 = 1 E1 = 2 E2 = 3 E3 = 4 (1 (2 3) 4) jest list ą „zagnie „zagnieżdżoną ” trójelementową , gdzie: E0 = 1 E1 = (2 3) E2 = 4 Element pierwszy E1, jako lista, może by ć rozbity dalej na poszczególne składniki: E1_0 = 2 E1_1 = 3
299
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Omawiają c pos poszcz zczegó ególne lne elemen elementy ty listy, listy, nale należy wsp wspomn omnie ieć je jeszc szcze ze o tzw tzw.. „parze „parze kropkowej”. Jest ona często wykorzystywana do opisu listy DXF elementów. Przykłady par kropkowych: kropkowych: (0 . "LAYER") (70 . 0) (–1 . ). Para kropkowa traktowana jest jako jeden element listy. O sposobie tworzenia par kropkowych oraz pobierania jej poszczególnych składników powiemy sobie w dalszej części książki. Lista, opr Lista, oprócz ócz tego, tego, że skła składa da się z kolejno kolejno ponume ponumerowan rowanych ych eleme elementów, ntów, posia posiada da również „głowę” (head) oraz „ogon” (tail). Głowę listy stanowi jej pierwszy element, zaś ogon to cała reszta listy. Można to przedstawić poniższymi diagramami:
21/ E{jbbojb ob mjtubdi
29:
Ogon listy jednoe jednoelement lementowej owej jest pusty, stą d wskaz wskazanie anie NIL. Natomiast Natomiast dla przypa przypadku dku ostatniego (para kropkowa), ogon listy jest to drugi element pary kropkowej. Głowa listy listy jest jest atom atomem em lub lub list listą , ogon ogonem em list listy y je jest st li list staa (z wyj wyją ttkiem kiem lis listt specja specjalni lniee konstr kon struow uowany anych ch — prz przy y użyciu funkcji funkcji cons). Prz Przyj yjęte w prz przykł ykładz adzie ie pie pierws rwszym zym oznaczenia car dla głowy listy i cdr dla ogona listy są nazwami nazwami funkcji AutoLISPu dają cymi cymi w wyniku głowę oraz ogon listy. Funkcje te zostaną przedstawione przedstawione w dalszej części książki.
Podstawową funkcją interprete interpretera ra język zykaa Aut AutoLI oLISP SP jes jestt wykony wykonywan wanie ie ope operac racji ji na listach. AutoLISP posiada trzy wbudowane funkcje słu żą ce ce do tworzenia list z danych elementów (atomów lub sublist) oraz do umieszczania elementów na li ście już utworzonej. Omówię teraz po kolei poszczególne funkcje oraz sposoby ich zastosowania.
21/2/2/ Uxps{fojf qpnpd pnpd gvold gvoldkj kj MJTU Uxps{fojf mjtuz {b q Format funkcji list jest następują ccy: y: (list expr expr ... ...)
Funkcja list ł ą czy czy dowolną liczb liczbę argumentów expr w w jeden łańcuch wyrażeń i zwraca utworzoną w w ten sposób list ę. Przykładowo, jeśli dokonamy następują cych cych przypisań: (setq x1 1 x2 2. 2.0 0
x3 "AutoC "AutoCAD" AD" x4 '( '(10 10 20 20) ) );setq
zwraca 1 zwraca 2.0 zwraca "AutoCAD" zwraca (10 (10 20 20) )
wówczas: (s (set etq q y (l (lis ist t x1 x2 x2)) ))
powoduje pobranie wartości zmiennych x1 i x2 , utworzenie listy z tych dwóch wyrażeń oraz podstawienie otrzymanej listy pod zmienną y y . W efekcie końcowym zmienna y ma wartość (1 2.0).
2:1
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (s (set etq q y (l (lis ist t x1 'x 'x2) 2)) )
powoduje pobranie wartości zmiennej x1 , połą czenie czenie jej w listę z symbolem literowym x2 (znak ' przed zmienną x2 x2 zapobiega jej ewaluacji) oraz podstawienie otrzymanej listy pod zmienną y y . W efekcie efekcie końcowym zmienna y ma wartość (1 X2). Powyższy sposób tworzenia listy można jeszcze wyjaśnić na następują cym cym przykładzie: (setq x 1 y 2 z 3 );setq (list x y z)
(l (lis ist t 'x 'y 'z 'z) )
zwraca zwraca (1 2 3) zwraca zwraca (X Y Z)
(s (set etq q y (l (lis ist t 'x 'x1 1 x1 x1)) ))
powoduje utworz powoduje utworzenie enie dwuelemen dwuelementowej towej listy, w której pierwszy element jest nazwą zmiennej, a drugi element jest warto ścią tej zmiennej. W efekcie końcowym zmienna y ma wartość (X1 1). (s (set etq q y (l (lis ist t x3 x4 x4)) ))
powoduje utworzenie listy z ła ńcucha i sublisty. W efekcie ko ńcowym zmienna y ma wartość ("AutoCAD" (10 20)). (s (set etq q y (l (lis ist t 'x 'x3 3 'x 'x4) 4)) )
powoduje powodu je utw utworz orzeni eniee lis listy ty z dwó dwóch ch atomów atomów lit litero erowyc wych h (żaden aden z ni nich ch ni niee podl podleg egaa ewaluacji). W efekcie końcowym zmienna y ma wartość (X3 X4). (s (set etq q y (l (lis ist t 'a 'b 'b)) ))
przykł prz ykład ad taki taki sam jak pow powy yżej. ej. Różnic nicaa pole polega ga ty tylko lko na ty tym, m, że a i b nie mają przypisanych żadnych wartości. W efekcie końcowym zmienna y ma wartość (A B). Należy jeszcze wspomnieć, ż e wszystkie atomy literowe przedstawiane s ą przy przy pomocy dużych liter alfabetu. (s (set etq q y (l (lis ist t a b) b)) )
w przykładzie tym żą damy damy ewaluacji zmiennych, które nie zostały jeszcze utworzone. Próba ewaluacji takiej zmienn zmiennej ej daje nil , tak więc w efekcie końcowym zmienna y ma wartość (nil nil). (s (set etq q y (l (lis ist t 'a '( '(b b c) 'd 'd)) ))
tworzymy tworzy my listę trójelementową , w której element środkow rodkowy y jest sublistą . Wszys Wszystkie tkie elementy listy są atomami atomami literowymi. literowymi. W efekcie efekcie ko ńcowym zmienna y ma wartość (A (B C) D). (s (set etq q y (l (lis ist t 10 100 0 10 100 0 20 200) 0)) )
tworzymy listę z trzech liczb całkowitych. całkowitych. Mogą to to być na przykład współrz ędne jakiegoś punktu w przestrzeni. W efekcie końcowym zmienna y ma wartość (100 100 200).
21/ E{jbbojb ob mjtubdi
2:2
Jeśli w liście nie ma zmiennych lub niezdefiniowanych wyrażeń, do tworzenia listy można wykorzysta wykorzystać alternatywną metodę, polega polegajją cą na prostym prostym oznacz oznaczeniu eniu listy znakiem cytatu. (s (set etq q y '( '(10 100 0 10 100 0 20 200) 0)) ) (s (set etq q y (l (lis ist t 10 100 0 10 100 0 200) 200)) ) (s (set etq q y (l (lis ist t x1 (+ x1 x2 x2) ) (+ x1 x2 10 10)) ))) )
tworzymy trójelementową listę, której składnikami są liczba całkowita i dwie liczby rzeczywiste. Dodatkowo posługujemy się operatorami arytmetycznymi w celu zmiany wartości drugiej i trzeciej liczby. W efekcie ko ńcowym zmienna y ma wartość (1 3.0 13.0). Posłużenie się w tym przykładzie przykładzie znakiem cytatu da następują cy cy rezultat: (s (set etq q y '( '(x1 x1 (+ x1 x2 x2) ) (+ x1 x2 10 10)) ))) )
zwraca (X (X1 1 (+ X1 X2 X2) ) (+ X1 X2 10)) 10))
Na koniec koniec pod podam am jes jeszcz zczee jeden jeden prz przykł ykład ad two tworze rzenia nia lis listy ty skł składa adajją cej c ej się z atomów atomów literowych litero wych i cyfrow cyfrowych. ych. Niech dane b ędą k k ą ąty t y począ tkowe: tkowe: minimalny alfa1min = –30° i maksymalny alfa1max = 30° obrotu danego podzespołu wokół przyj ętej osi. Chcą c utworzyć listę katyminmax, za zawi wier eraj ają cą n naz azwy wy i wart warto ości k ąą t tów, ów, post postępujemy następują cco: o: (setq katyminmax katymi nmax (list (quote (quot e alfa1min) alfa1min) alfa1min (quote (quot e alfa1max) alfa1max) alfa1max );list );setq
W efekcie końcowym otrzymujemy: (ALFA1 (AL FA1MIN MIN -30 ALFA1M ALFA1MAX AX 30)
Mają c tak utworzoną listę, możemy modyfi modyfikowa kować ją po każdym obroc obrocie, ie, uzysk uzyskuj ują c w efekcie końcowym aktualny zakres obrotu podzespołu.
21/2/3/ U Uxps{fojf xps{fojf mjtuz DPOT POT mjtu z {b qpnpd gvoldkj D Format funkcji cons jest następują ccy: y: new-first-element ent list) (cons new-first-elem
Jest Jest to dru druga ga pod podsta stawow wowaa fun funkcj kcjaa służą ccaa do two tworze rzenia nia lis list. t. Argume Argument nt new-firstelement jest jest wprowadzany jako pierwszy argument listy okre ślonej przez argument list . Argumentem new-first-element mo może by ć zarówno atom, jak i lista.
2:3
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Przykładowo, jeśli dokonamy następują cych cych przypisań: (setq x1 1 x2 (l (lis ist t 10 20 30) x3 "A "A" " x4 (l (lis ist t "a "a" " "B "B" " "b "b") ") x5 (l (lis ist) t) ;u ;utw twor orze zeni nie e pu pust stej ej listy listy );setq
wówczas: (s (set etq q y (c (con ons s x1 x2 x2)) ))
dołą czamy czamy wartość zmiennej x1 na począ tek tek listy podstawionej pod zmienną x2. W efekcie końcowym zmienna y ma wartość (1 10 20 30). (s (set etq q y (c (con ons s 'x 'x1 1 x2 x2)) ))
dołą czamy czamy atom literowy X1 (bo występuje apostrof przed zmienną x1) na począ tek tek listy podstawionej pod zmienną x2 x2. W efekcie końcowym zmienna y ma wartość (X1 10 20 30). (s (set etq q y (c (con ons s 'x 'x1 1 'x 'x2) 2)) )
w przypadku, gdy argument list jest atomem (' x2 x2 jest atomem literowym), cons tworzy wtedy strukturę znaną w w języku LISP jako para kropkowa. Pomi ędzy pierwszym i drugim elementem pary kropkowej znajduje si ę kropka. W efekcie końcowym zmienna y ma wartość (X1 . X2). Pomiędzy pierwszym elementem pary kropkowej a kropką oraz oraz pomiędzy kropką a drugim elementem pary kropkowej znajduje się spacja. Np. (cons 1 2) => (1 . 2). Musisz o tym pamiętać, by odróżnić taką parę kropkową od zwykłej liczby rzeczywistej — np. (list 1.2) => (1.2). Dostęp do poszczególnych elementów pary kropkowej zapewniają nam funkcje car oraz cdr cdr.. Car zwraca pierwszy element pary kropkowej, cdr zwraca drugi element. (c (car ar y) (c (cdr dr y)
zwraca X1 zwraca X2
Jeżeli jakiś składnik pary kropkowej jest nazw ą zmiennej, zmiennej, możemy dokonać jego ewaluacji w celu otrzymania wartości tej zmienne zmiennej. j. (e (eva val l (c (car ar y) y)) ) (e (eva val l (c (cdr dr y) y)) )
zwraca 1 zwraca (10 (10 20 30 30) )
(s (set etq q y (c (con ons s x1 x5 x5)) ))
w tym przypadku, ponieważ wartość zmiennej x5 jest równa nil , zostaje utworzona lista składają ca c a się z jedneg jednego o elemen elementu tu — war warto tości zmienn zmiennej ej x1. W efekcie końcowym zmienna y ma wartość (1).
21/ E{jbbojb ob mjtubdi
2:4
(s (set etq q y (c (con ons s x5 x1 x1)) ))
w tym przypadku zamieniono ze sob ą miejscami zmienne x1 i x5. Wynik operacji jest jednak zupełnie inny. W poprzednim przykładzie wstawialiśmy wartość zmiennej x1 (1) jako pierwszy element listy x5 . Poniew Poniewaaż x5 była listą pust pustą ( ( nil), w efekcie końcowym otrzymaliśmy listę jednoelementową . Tutaj natomiast wstawiamy wartość zmiennej x5 (nil), traktowanej jako atom literowy, jako pierwszy element listy x1 . Ponieważ jednak x1 jest również atomem atomem literow literowym, ym, zos zostan tanie ie utw utworz orzona ona par paraa kro kropko pkowa. wa. W efe efekci kciee końcowym zmienna y ma wartość (nil . 1). (s (set etq q y (c (con ons s x3 x4 x4)) ))
dołą czamy czamy literę "A" na począ tek tek listy liter alfabetu. W efekcie końcowym zmienn zmiennaa y ma wartość ("A" "a" "B" "b"). (s (set etq q y (c (con ons s 1 2) 2)) )
tworzymy parę kropkową z z dwóch atomów cyfrowych. W efekcie końcowym zmienna y na wartość (1 . 2). (s (set etq q y (c (con ons s 'a 'b 'b)) ))
tworzymy parę kropkową z z dwóch atomów literowych. W efekcie końcowym zmienna y ma wartość (A . B). (s (set etq q y (c (con ons s 'a '( '(b b c d) d)) )
dołą czamy czamy atom literowy A na począ tek tek listy atomów literowych (B C D). W efekcie końcowym zmienna y ma wartość (A B C D). (s (set etq q y (c (con ons s '( '(a) a) '( '(b b c d) d))) ))
dołą czamy czamy listę na począ tek tek innej listy. W efekcie końcowym zmienna y ma wartość ((A) B C D). (s (set etq q y (c (con ons s '( '(a a b) 'c 'c)) ))
dołą czamy c zamy lis listtę (A B) prze przed d atom atom lite litero rowy wy C — zost zostan anie ie więc utw utworz orzona ona par paraa kropkowa. W efekcie końcowym zmienna y ma wartość ((A B) . C). (car y) (cdr y)
zwraca (A B) zwraca C
Na tym przykładzie kończę omawianie funkcji cons. Chciałbym, abyś z tego punktu zapamiętał cztery rzeczy: 1. Arg Argume ument nt new-first-element jest jest wpr wprowa owadza dzany ny jako jako pie pierws rwszy zy elemen elementt lis listy ty określonej przez argument list . 2. Jeśli argumentem list jest jest atom, tworzona jest wówczas para kropkowa. 3. Dost Dostęp do poszczególnych elementów pary kropkowej zapewniaj ą funkcje car oraz cdr. 4. Częściej będziesz przetwarzał gotowe pary kropkowe, niż je tworzył. Wynika to z faktu, ż e lista DXF opisu poszczególnych elementów rysunkowej bazy danych AutoCADa zawiera już utworzone pary kropkowe.
2:5
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst
21/2/4/ G Gvoldkb voldkb BQQ BQQFOE FOE — vnjft{d{bojf vnjft{d{bojf — vnjft fmfnfoux x ob mjdjf kv vuxps{pofk kk fmfnfou kv vuxps{pof Format funkcji append jest następują ccy: y: expr ... ...) (append expr
Argumentami funkcji może być dowolna ilość argumentów expr , które są brane jako jedna lista, otrzymana z ich połą czenia. czenia. Funkcja append wymaga, aby jej argumenty były listami. Przykładowo, jeśli dokonamy następują cych cych przypisań: (setq x1 (list (list 1 2) x2 (list (list 3 4) x3 (l (lis ist t "A "A" " "a "a") ") x4 (l (lis ist t "B "B" " "b "b") ") lista lis ta (list) (list) );setq
wówczas: (s (set etq q y (a (app ppen end d x1 x2 x2)) ))
łą czy czy dwie listy w jedną . W efekcie końcowym zmienna y ma wartość (1 2 3 4). (s (set etq q y (a (app ppen end d 'x 'x1 1 'x 'x2) 2)) )
powoduje wypisanie błędu AutoLISPu "error: bad argument type", gdy ż zarówno 'x1 jak i 'x2 s ą atomami atomami literowymi, a powinny być listami. (s (set etq q y (a (app ppen end d x3 x4 x4)) ))
łą czy c zy dwie listy ła ńcuchów alfanumerycznych. W efekcie końcowym zmienna y ma wartość ("A" "a" "B" "b"). (s (set etq q y (a (app ppen end d '( '(a a b) '( '(c c d) d))) ))
powoduje podstawienie pod zmienną y y listy (A B C D). (s (set etq q y (a (app ppen end d '( '((a (a b) b)) ) '( '((c (c d) d))) ))) )
powoduje podstawienie pod zmienną y y listy ((A B)(C D)) (setq (se tq lista lista (appen (append d lista lista (list (list x1))) x1)))
działa następują cco: o: (list x1) zwraca ((1 2) (list 2)), ), bo x 1 = ( 1 2 ) (a (app ppen end d li list sta a (l (lis ist t x1 x1)) )) (a (app ppen end d ni nil l (( ((1 1 2) 2))) ))
zwraca ((1 ((1 2) 2)) ) W efekcie końcowym zmienna lista ma wartość ((1 2)).
21/ E{jbbojb ob mjtubdi
2:6
(setq (se tq lista lista (appen (append d lista lista (list (list x2))) x2)))
działa następują cco: o: (list x2) zwraca ((3 4) (list 4)), ), bo x 2 = ( 3 4 ) (a (app ppen end d li list sta a (l (lis ist t x2 x2)) )) (a (app ppen end d (( ((1 1 2) 2))( )((3 (3 4) 4))) ))
zwraca ((1 2) 2)(3 (3 4) 4)). ). W efekcie końcowym zmienna lista ma wartość ((1 2)(3 4)). Różnicę w działaniu funkcji list i append przedstawiają cztery cztery poniższe przykłady (bez komentarza): (list '(a b) '(c d)) (append '(a b) '(c d)) (list '(( '((a b)) b)) ' '( ((c d)) d))) (a (app ppen end d '( '((a (a b)) b)) '( '((c (c d))) d)))
=> => => =>
((A B)(C D)) (A B C D) ((( (((A B)) B))((C D)) D))) ((A ((A B) B)(C (C D)) D))
Na koniec tego punktu omawiają cego cego tworzenie listy oraz dołą czanie czanie elementów do listy już utworzonej, przedstawię program wykorzystują cy cy funkcje list oraz append. Zadaniem programu jest utworzenie siatki punktów (węzłów) oraz umieszczenie danych o poszczególnych węzłach na liście *lista_wezlow. Dane dla każdego węzła składają si si ę z jego numeru oraz współrzędnych X, Y i Z węzła — np. (1 10 –25 5). Dodatkowo należy opisać węzeł na rysunku. Program ma działać w pętli, z której wychodzimy wybierają c literę " E" lub "e". Po wyjściu z pętli należy wypisać na ekranie tekstowym listę utworzonych węzłów. A oto i program realizuj ą cy cy powyższe zadania. ;*************************************************PROG_037 ;Przyklad ;Przy klad tworzenia tworzenia listy. ;Wykor ;Wy korzys zystan tanie ie funkcj funkcji i LIST LIST oraz oraz APPEND APPEND. . ; ;------------------------------------------------;wylaczenie ;wyla czenie echa komend (setva (se tvar r "cmdec "cmdecho" ho" 0) ;------------------------------------------------;ustawienie ;usta wienie zmiennych zmiennych globalnych globalnych (comma (co mmand nd "_zoom "_zoom" " "_wind "_window" ow" "0, "0,0" 0" "12,9" "12,9") ) (setva (se tvar r "blipm "blipmode ode" " 0) ;wylac ;wylaczen zenie ie znaczn znaczniko ikow w punkto punktow w (s (set etva var r "p "pdm dmod ode" e" 33 33) ) ;w ;wyg ygla lad d pu punk nktu tu (setva (se tvar r "pdsize" "pdsize" 0.08) 0.08) ;rozmi ;rozmiar ar punktu punktu (setq *lista_wezlo *lista _wezlow w (list) *numer_wezla *numer _wezla 1 *h_tek *h_tekstu stu 0.10 *delta_tekst *delta _tekstu u 0.10 );setq ;------------------------------------------------;zdefiniowa ;zdef iniowanie nie funkc funkcji ji UTWORZ_WEZL UTWORZ_WEZLY Y (defun (de fun UTW UTWORZ ORZ_WE _WEZLY ZLY ( / jeszcz jeszcze e punkt punkt wsp_op wsp_op_wz _wz opis_wezla )
2:7
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (progn ;---------;wejsc ;we jscie ie w petle petle WHILE WHILE ;tworzenie ;tworz enie poszczegoln poszczegolnych ych wezlow wezlow ukladu (setq (se tq jeszcz jeszcze e T) (while jeszcze jeszcze (progn ;---------;sprawdzeni ;spraw dzenie, e, czy konie koniec c wprowadzania wprowadzania danych (i (ini nitg tget et 1 "E e" e") ) (setq punkt (getpoint (getpoint (strcat "\nPod "\n Podaj aj wspolr wspolrzed zedne ne dla wezla wezla numer numer " (rtos (rt os *numer *numer_we _wezla zla 2 0) " (E - ko koni niec ec): ): " );strcat );getpoint );setq (i (if f (o (or r (= pu punk nkt t "E "E") ")(= (= pu punk nkt t "e "e") ")) ) (progn (setq (se tq jeszcz jeszcze e nil) nil) );progn );if ;---------;gdy podano podano wspolrzedne wspolrzedne (if jeszcze jeszcze (progn ;---------;wykresleni ;wykr eslenie e wezla (command "_point" "_poi nt" punkt );command ;---------;opisanie ;opis anie wezla (setq wsp_op_wz (list (- (car (car punkt) punkt) *delta *delta_te _tekst kstu) u) (+ (cadr (cadr punkt) punkt) *delta *delta_te _tekst kstu) u) (caddr punkt) );list );setq (command "_text" "_tex t" wsp_op_wz wsp_op_wz *h_tekstu *h_tekstu "0" *numer_wezla *numer_wezla );command ;---------;utworzenie ;utwo rzenie listy opisujacej opisujacej wezel (setq opis_wezla (list *numer_wezla (c (car ar pun punkt kt) ) ;w ;wsp spol olrz rzed edna na X (c (cad adr r pu punk nkt) t) ;w ;wsp spol olrz rzed edna na Y
21/ E{jbbojb ob mjtubdi (caddr (ca ddr pun punkt) kt) ;wspol ;wspolrze rzedna dna Z );list );setq ;---------;dodan ;do danie ie opisu opisu wezla wezla do listy listy *lista *lista_we _wezlo zlow w (setq *lista_wezlow (append (appen d *lista_wezl *lista_wezlow ow (list opis_wezla) opis_wezla)) ) );setq ;---------;zwiek ;zw ieksze szenie nie num numeru eru wezla wezla o 1 (setq *numer_wezla *numer_wezla (1+ *numer_wezl *numer_wezla)) a)) ;---------);progn );if jeszcze jeszcze ;---------);progn );while );whil e jeszcze jeszcze ;---------;wyswietleni ;wyswi etlenie e listy wezlow (textpage) (princ (pr inc "Ot "Oto o twoja twoja lista lista wezlow wezlow:") :") (princ"\n\n\n") (princ *lista_wezl *lista_wezlow) ow) (princ "\n\n\n") "\n\n\n") (getstring (getst ring T "Nacisnij "Nacisnij ENTER ENTER...") ...") (graphscr) ;---------(princ) ;---------);progn );UTWORZ_WEZLY ;------------------------------------------------;wywolanie ;wywo lanie funkcji funkcji UTWORZ_WEZLY UTWORZ_WEZLY (UTWORZ_WEZLY) ;------------------------------------------------(princ) ;------------------------------------------------;*************************************************KONIEC
Wykonanie powyższego programu może wyglą da dać następują cco: o: Command: (load "prog "prog_037") _037")↵ Po Poda daj j ws wspo polr lrze zedn dne e dl dla a we wezl zla a nu nume mer r 1 (E - ko koni niec ec): ): 1,1,0↵ Po Poda daj j ws wspo polr lrze zedn dne e dl dla a we wezl zla a nu nume mer r 2 (E - ko koni niec ec): ): 1,3,0↵ Po Poda daj j ws wspo polr lrze zedn dne e dl dla a we wezl zla a nu nume mer r 3 (E - ko koni niec ec): ): 3,3,0↵ Po Poda daj j ws wspo polr lrze zedn dne e dl dla a we wezl zla a nu nume mer r 4 (E - ko koni niec ec): ): 3,1,0↵ Po Poda daj j ws wspo polr lrze zedn dne e dl dla a we wezl zla a nu nume mer r 5 (E - ko koni niec ec): ): e↵ Oto twoja twoja lista lista wezlow wezlow: : (( ((1 1 1. 1.0 0 1. 1.0 0 0. 0.0) 0)(2 (2 1. 1.0 0 3. 3.0 0 0. 0.0) 0)(3 (3 3. 3.0 0 3. 3.0 0 0. 0.0) 0)(4 (4 3. 3.0 0 1. 1.0 0 0.0))
2:8
2:9
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Nacisnij Nacis nij ENTER. ENTER... ..↵ Command:
Omówmy teraz wyróżnione bloki i linie programu. bloku tym ustawiamy zmienne globalne dla programu: wył ą czamy czamy wyświetlanie znaczników punktów, ustalamy wyglą d oraz rozmiar punktu, tworzymy pustą listę węzłów, ustalamy numer począ tkowy tkowy węzła oraz wysokość napisu
W
opisują cego cego węzeł i jego odległ odległo ość od środka węzła. Z pewnością zauwa zauważyłeś, ż e nazwy zmiennych globalnych rozpoczyna rozpoczynajją si si ę od znaku gwiazdki "*". W moich programach (a już na pewno w aplikacjach) tak właśnie ozn oznacz aczam am zmienn zmienne e glo global balne. ne. Ty ocz oczywi ywiście cie możesz esz użyć innego sposobu sposob u oznacz oznaczania ania zmiennych globalnych. Taki sposób wydzielen wydzielenia ia w progr gram amie ie zmie zmienn nnyc ych h gl glob obal alny nych ch bard bardzo zo ułat ułatwi wia a pr prac acę (ma (ma to szcz szczeg egól ólne ne znaczenie w dużych programach — takich na kilka lub kilkanaście tysięcy linii kodu). Zmienna globalna jest to zmienna dost ępna z wnętrza wszystkich funkcji programu — więcej na ten temat powiemy sobie podczas omawiania funkcji. Korzystają c
z funkcji initget, ustalamy warunki oraz słowa kluczowe dla funkcji getpoint. Bit 1 oznacza, ż e nie wolno nam podać odpowiedzi pustej (tzn. pusty ENTER), słowa kluczowe „E e” ustalają nam nam znaki, jakie b ędą dodatkowo dodatkowo akceptowane oprócz współrzędnych punktu.
Pobieramy
współrzędną punktu punktu (węzła), lub słowo kluczowe.
W
bloku tym, sprawdza sprawdzamy, my, czy zosta zostało ło wprowadzon wprowadzonee słowo kluczo kluczowe we („ E” lub „e”). Jeśli tak, ustawiamy wartość zmiennej jeszcze na nil, umożliwiają c tym samym wyjście z pętli while.
Jeśli
zam zamias iastt sło słowa wa klu kluczo czoweg wego o został zostały y wpr wprowa owadzo dzone ne wsp współr ółrzzędne pun punktu ktu,, wykonujemy tę cz ęść programu.
bloku tym, wykre ślamy węzeł, oblic obliczamy zamy wspó współrz łrzędne punktu wstawien wstawienia ia opisu węzła oraz wstawiamy opis węzła (jego numer).
W
Korzystają c z
funkcj funkcjii list, tworzymy listę opisują cą aktualny aktualny węzeł.
Korzystają c z
funkcj funkcjii append oraz list, dołą czamy czamy opis węzła do listy węzłów.
blok bloku u tym, tym, po prze przejjściu na ekr ekran an teksto tekstowy, wy, wyp wypisu isujem jemy y zaw zawart arto ość listy *lista_wezlow, po czym po naciśnięciu przez użytkown ytkownika ika klawisza klawisza ENTER, wracamy na ekran graficzny.
W
21/ E{jbbojb ob mjtubdi
2::
W poprzednich punktach omówiłem tworzenie listy. Jednak nawet najdoskonalsza lista nie byłaby nic warta, gdyby nie istniały mechanizmy służą ce ce do jej modyfikacji, tzn. wyszukiwania informacji na liście, zmiany jej poszczególnych elementów, kasowania wybranych wybran ych elementów oraz sortowania listy. Niektóre z tych mechaniz mechanizmów mów s ą predefi predefiniowanymi funkcjami języka AutoLISP, inne zostały zaś stworzone jako funkcje zewnętrzne języka AutoLISP (funkcje (funkcje użytkownika). Poniżej w poszczególnych punktach zostaną szczegółowo szczegółowo omówione funkcje do operacji na listach.
21/3/2/ Plsf Plsfmbojf mbojf evh evhpdj pdj mjtuz Aby określić długość interesują cej cej nas listy, posługujemy si ę predefiniowaną (wbudo (wbudowaną ) funkcją AutoLISPu AutoLISPu length. Format tej funkcji jest nast ępują ccy: y: (length list)
Funkcja ta zwraca liczbę typu integer (całkowita), określają cą liczb liczbę elementów argumentu list . Przykładowo, jeśli dokonamy następują cych cych przypisań: (setq li list sta_ a_1 1 (l (lis ist t 1 2 3 4 5) li list sta_ a_2 2 '( '((1 (1 2 2 0) 0)(2 (2 2 4 0) 0)( (3 5 10 2)) li list sta_ a_3 3 (l (lis ist) t) ;l ;lis ista ta pusta pusta lista_4 lista_ 4 10 lista_ lis ta_5 5 nil );setq
wówczas: (length (leng th lista_2) lista_2)
(length (leng th lista_3) lista_3)
(length (leng th lista_4) lista_4)
(length (leng th lista_5) lista_5)
(length (leng th lista_1) lista_1)
zwraca 5. zwraca 3, gdyż lista_2 jest listą zagnie zagnieżdżoną trójelementową (1 (1 2 2 0), (2 2 4 0) oraz (3 5 10 2). Poszczegól Poszc zególne ne eleme elementy nty zagnie zagnieżdżone również mogą być argumentami funkcji length. zwraca 0, gdyż lista_3 jest listą pust pustą — jej ewaluacja daje nil. zwraca "error: bad argument type", gdyż argument lista_4 nie jest listą , lecz liczbą całkowit całkowitą . zwraca 0 — identycznie jak w przypadku zmiennej lista_3.
Aby dowiedzieć się, jaki typ reprezentuje dana zmienna, posługujemy się wbudowaną funkcją AutoLISPu (type item), która zwraca określenie typu argumentu item lub nil, jeżeli argument item w wyniku ewaluacji daje nil. Przykładowo, dla zmiennych lista_1 — lista_5: (type lista_1) lista_1) (type lista_2) lista_2)
zwraca LIST zwraca LIST
311
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (type lista_3) lista_3) (type lista_4) lista_4) (type lista_5) lista_5)
zwraca nil zwraca INT zwraca nil
21/3/3/ Xzt{vljxbojf fmfnfouv mjtu mjtuz z 21/3/3/ Xzt{vljxbojf Xzt{vl z p {bebozn l lmvd{v mvd{v Załóżmy, że dokonują c następują cego cego przypisania: (s (set etq q li list sta_ a_2 2 '( '((1 (1 2 2 0) 0)(2 (2 2 4 0) 0)(3 (3 5 10 2) 2)) ))
otrzymujemy pod zmienną lista_2 lista_2 następują cą list listę: ((1 2 2 0)(2 2 4 0)(3 5 10 2))
Otrzymaliśmy więc listę zagnieżdżoną trójelementow trójelementową , o indek indeksach sach eleme elementów ntów 0, 1 i 2. Niech każdy element listy opisuje nam numer oraz współrz ędne punktu na rysunku. Załóżmy, że chcemy otrzymać dane elementu (punktu) o numerze 2. Gdyby indeks elementu był na sztywno zwi ą zany zany z numerem punktu, wtedy można by nakazać wyszukać opis elementu o indeksie 1. Co jednak si ę stanie, jeśli dane o punkcie 1 zostaną skasowane z listy? Wtedy punkt o numerze 2 otrzyma indeks 0 (będzie pierw pierwszym szym elementem listy), natomiast indeks 1 zostanie przydzielony punktowi o numerze 3, i ten opis punktu dostaniemy. Aby uniknąć tego typu „niespodzianek”, AutoLISP posiada wbudowaną funkcj funkcję assoc, pozwalają cą na na wyszukiwanie elementu listy według zadanego klucza. Format funkcji assoc jest następują ccy: y: (assoc item alist alist)
Funkcjaa ta prz Funkcj przesz eszuku ukuje je lis listtę asocjacji asocjacji podaną w argume argumencie ncie alist , szu szukaj kają c w niej skojarzeń z elementem item, pełnią cym cym tu funkcję elementu kluczowego. Asocjacja ta (lista (lis ta złożona ona z pa pary ry skoj skojar arzo zony nych ch ze sob sobą element elementów) ów) jes jestt zwraca zwracana na jako jako wyn wynik ik ewaluacji ewalu acji wyrażenia. Jeżeli item nie zostanie w liście asocjacji znaleziony, to funkcja assoc zwraca nil. Przykładowo, użycie funkcji Przykładowo, funkcji assoc w stosun stosunku ku do zmi zmienn ennej ej lista_2, da następują ce ce rezultaty: (assoc (as soc 1 lista_ lista_2) 2) zwraca (1 2 2 0) (assoc (as soc 2 lista_ lista_2) 2) zwraca ( 2 2 4 0 )
cej (assoc (as soc 5 lista_ lista_2) 2) zwraca nil, gdyż listy podrzędnej opisują cej element numer 5 nie ma na liście lista_2 Jeśli dokonamy następują cych cych przypisań: (setq
21/ E{jbbojb ob mjtubdi
312
li list sta_ a_3 3 (l (lis ist t 1 2 3 4 5) li list sta_ a_4 4 '( '(1 1 (2 10) 3 (4 20 20) ) 5) lista_5 lista_ 5 (list) lista_6 lista_ 6 '((imie '((imie "Marek")(naz "Marek")(nazwisko wisko "Dudek")(za "Dudek")(zaklad klad "CMG KOMAG Gliwice")(d Gliwice")(dzial zial "SK")) );setq
wówczas: (assoc (as soc 2 lista_ lista_3) 3) zwraca "err "error: or: bad associ associati ation on list" list" (assoc 1 lista_ (assoc lista_4) 4) zwraca "err "error: or: bad associ associati ation on list" list" (assoc (as soc 2 lista_ lista_4) 4) zwraca "err "error: or: bad associ associati ation on list" list"
Wynika to z faktu, że każdy element listy poddanej działaniu funkcji assoc musi być listą zagnie zagnieżdżoną . zwraca nil, gdyż lista_5 jest listą pust pustą . (assoc 'im (assoc 'imie ie lista_ lista_6) 6) zwraca (IMIE "Marek") "Marek") (assoc (as soc imi imie e lista_ lista_6) 6) zwraca nil , gdyż funkcja assoc próbuje tu wyszuka ć na liście klucz występują cy cy pod zmienną imie imie. Ponieważ taka zmienna nie istnieje, jej ewaluacja daje nil, co sprowadza się do postaci (ass (assoc oc nil
(assoc (as soc 1 lista_ lista_5) 5)
lista_6).
Problem powyższy można rozwią za zać następują cco: o: (setq klucz (setq klucz "imie" "imie") ) (assoc (as soc (re (read ad klucz) klucz) lis lista_ ta_6) 6) (setq lista "lista_6") "lista_6")
zwraca (IMIE "Marek") "Marek")
(assoc (as soc (re (read ad klucz) klucz)(ev (eval al (read (read lista) lista))) ))zwraca (IMIE "Marek") "Marek")
gdzie zmienne zmienne klucz oraz lista zostają pobran pobranee z kla klawia wiatur tury y przy przy pom pomocy ocy funk funkcji cji getstring. (assoc (asso c 'nazwisko 'nazwisko lista_6) lista_6) zwraca (NAZWISKO (NAZWISKO "Dudek") "Dudek") (assoc (asso c 'zaklad 'zaklad lista_6) lista_6) zwraca (ZAKLAD (ZAKLAD "CM "CMG G KOMAG KOMAG Gliwice") (assoc (asso c 'dzial lista_6)
zwraca (DZIAL (DZIAL "SK") "SK")
(assoc (asso c 'numer_ew 'numer_ew lista_6) lista_6) zwraca nil
Funkcji assoc używamy wtedy, kiedy chcemy uzyskać opis konkretnego elementu z listy.
21/3/4/ Xzt{vljxbojf Xzt{vlj xbojf o.ufhp fmf fmfnfouv nfouv mjtuz Xzt{vlj Bardzo często spotkasz się z przypadkiem, gdy chcesz przejrzeć wszystkie elementy listy, w celu ich aktualizacji, policzenia ś redniej itp. Posłużenie się w tym przypadku funkcją assoc da albo błędne wyniki, albo komunikat o błędzie AutoLISPu. Wyjaśnijmy to na następują cych cych przykładach:
313
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst
Qs{zlbe 2 Niech zmienna lista_1 składa się z n podlist, z których ka żda zawiera numer i współrzędne punktu na rysunku. Przyjmijmy, że aktualnie lista_1 zawiera opis pi ęciu punktów o numerach od 11 do 15 (punkty o numerach od 1 do 10 zostały wcze śniej skasowane z listy). Tak więc niech zmienna lista_1 wyglą da da następują cco: o: (( ((11 11 1. 1.0 0 1. 1.0 0 0. 0.0) 0)(1 (12 2 2. 2.0 0 2. 2.0 0 0. 0.0) 0)(1 (13 3 3. 3.0 0 3. 3.0 0 0. 0.0) 0)(1 (14 4 4. 4.0 0 4. 4.0 0 0.0)(1 0.0 )(15 5 5.0 5.0 0.0))
Długość listy lista_1 otrzymana za pomocą funkcji funkcji length wyniesie więc 5. Gdybyśmy jednak nie znali numerów punktów i próbowali otrzymać opis kolejnych podlist (punktów, węzłów), używają c do tego celu funkcji assoc z argumentem item od 1 do 5, wówczas za każdym razem wartością zwrotn zwrotną funkcji funkcji byłoby nil . Tak więc, nie znają c klucza, względem którego należy przeszukiwać listę, możemy tylko „strzelać na oślep”, liczą c, c, ż e w końcu coś trafimy. Jaki da to efekt w postaci wykonywania programu, nie muszę chyba wyjaśniać.
Qs{zlbe 3 Niech zmienna wyniki jest listą zawieraj zawierają cą wyniki wyniki pomiarów pewnej wielko ści, np.: (1 (1.1 .1 1. 1.25 25 1. 1.18 18 1. 1.20 20 1. 1.33 33) )
Naszym Naszy zadaniem zadaniem jestą policz policzenie rednie niejwypisanie j ary arytme tmetyc tyczne z tej lis listy. ty. "error Posłu Posłużenie eni e się śred w tymmwypadku funkcj spowoduje błznej assocenie assoc ęduj AutoLISPu "error: : bad association associ ation list", gdyż ż aden element listy wyniki nie jest list ą zagnie zagnieżdżoną . Powyższe dwa przykłady pokazały, ż e w takich przypadkach u życie funkcj funkcjii assoc jest poważnym błędem. Pomocna okaże się tutaj inna wbudowana funkcja AutoLISPu — nth. Format tej funkcj funkcjii jest następują cy: cy: list st) (nth n li
Funkcja nth zwraca n-ty eleme element nt argume argumentu ntu list , gdzie n jest numerem numerem zwracanego zwracanego elementu (pierwszy element listy ma numer zerowy — nale ży o tym pamiętać!!!). Jeżeli wartość n jest większa od najwyższego numeru elementu listy, to funkcja zwraca nil. Przykładowo, dla zmiennej lista_1, otrzymamy: (nth (nth (nth (nt h (nth (nt h (nth (nt h
0 2 4 5
lista_ lista_1) 1) lista_ lista_1) 1) lista_ lista_1) 1) lista_ lista_1) 1)
zwraca (11 (11 1. 1.0 0 1. 1.0 0 0. 0.0) 0) zwraca (1 (13 3 3. 3.0 0 3. 3.0 0 0. 0.0) 0) zwraca (1 (15 5 5. 5.0 0 5. 5.0 0 0. 0.0) 0) zwraca nil
a dla zmiennej wyniki: (n (nth th (n (nth th (n (nth th (n (nth th
0 2 4 5
wy wyni niki ki) ) wy wyni niki ki) ) wy wyni niki ki) ) wy wyni niki ki) )
zwraca 1.1 zwraca 1.18 zwraca 1.33 zwraca nil
21/ E{jbbojb ob mjtubdi
314
Funkcji nth Funkcji nth u u żywamy wtedy, gdy chcemy otrzymać opis n-tego elementu z listy.
221/3/5/ 1/3/5/ Ebof ptubuojfhp fmfnfou fmfnfouv v mjtuz Jeśli jeste potrzebne są dane w dane ostatniego elementu na li ście, moż esz ś pewien, żieAutoLI żyć stand standardowe ardowej j funkcj funkcji AutoLISPu SPuCi last celu ich otrzymania. Format funkcji lastu jest następują ccy: y: (last list)
Funkcja zwrac Funkcja zwracaa ostat ostatni ni eleme element nt argum argumentu entu list . W przypa przypadku dku listy pus pustej tej funkcj funkcjaa zwraca nil . Przykładowo, jeśli dokonano następują cych cych podstawień: (setq li list sta_ a_1 1 lista_ lis ta_2 2 "C")) li list sta_ a_3 3 lista_4 lista_ 4 );setq
(l (lis ist t 1 2 3 4 5) 5);z ;zwr wra aca (1 2 3 4 5) '((1 '((1 "A")(2 "A")(2 "B" "B")(3 )(3 "C" "C")); ));zwr zwraca aca ((1 "A")(2 "A")(2 "B" "B")(3 )(3 (l (lis ist t 1 2 (l (lis ist t 3 4) 4)); );zw zwra raca ca (1 2 (3 4) 4)) ) (list);zwrac (list);zwraca a nil
wówczas: (last lista_1) lista_1) (last lista_2) lista_2) (last lista_3) lista_3) (last lista_4) lista_4)
zwraca 5 zwraca (3 "C "C") ") zwraca (3 4) zwraca nil
21/3/6/ Gvoldkf DBS BS j DES psb psb{{ jdi lpncjo lpncjobdkf bdkf D Jak już wspomniałem wcześniej, funkcje car i cdr zwracają odpowiednio odpowiednio „głowę” oraz „ogon” listy. Dla przypomnienia: (c (car ar (c (car ar (car (ca r (c (cdr dr
'( '(a a b c) c)) ) '( '((a (a b) c) c)) ) '()) '()) '( '(a a b c) c)) )
(c (cdr dr '( '((a (a b) c) c)) ) (cdr '()) (cdr '())
zwraca A zwraca (A B) zwraca nil zwraca (B (B C) zwraca (C) zwraca nil
W przypadku pary kropkowej funkcja cdr zwraca drugi element pary jako atom, a nie jako list ę. Przykładowo: zwraca B (c (cdr dr '( '(1 1 . "T "Tek ekst st") ")) ) zwraca "Tekst"
(c (cdr dr '( '(a a . b) b)) )
315
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Car i cdr s ą elementarnymi postaciami funkcji AutoLISPu. Dopuszczalne jest również zagnieżdżanie tych funkcji naprzemian i wewną trz trz samych siebie, przy czym superpozycja ta może si ęgać do czterech poziomów w gł ą b b.. (c (car ar (c (cdr dr '( '(a a b c) c))) ))
oznacza poszukiwanie głowy ogona listy (A B C) i zwraca B, ponieważ ogon listy to (B C), a jego głowa to B. Ponadto, dla takich zagnie żdżeń, przyjmuje się specjalną , skróconą notacj notację. Powyższy przykład można zapisać inaczej: (c (cad adr r '( '(a a b c) c)) )
Skrócony zapis polega na wstawieniu pomiędzy c … r charakterystycznych dla funkcji car i cdr liter a i d . Przykładowo, jeśli dokonano przypisania: (setq x '((a b) c d) );setq
;zwraca ((A B) C D)
wówczas:
(c (car ar x) (c (cdr dr x)
zwraca (A B) zwraca (C D) zwraca A zwraca (B)
(caar x) x)
(c (car (c (car x) x))
(cdar x) x)
(c (cdr (c (car x) x))
(c (cad adar ar x) (cadr x) x)
(car (car (cdr (cdr (car (car x))) x))) zwraca B zwraca C (c (car (c (cdr x) x))
(cddr x) x)
(c (cdr (c (cdr x) x))
(c (cad addr dr x)
zwraca (D) (car (car (cdr (cdr (cdr (cdr x))) x))) zwraca D
Powyższe rezultaty (ale nie wszystkie), mo żna również osią g gn nąć posługują c się tylko funkcjami car i cdr w połą czeniu czeniu z funkcją nth nth . Tak więc dla powyższych przypadków, inną metod metodą doj dojścia do tych samych wyników jest: (car x)
(nth 0 x)
(cdr x) (caar x) x) (cdar x) x) (cadar x) (cadr x) x)
— brak ( (n nth ( (c cdr (nt (nth ( (n nth
(cddr x) (caddr x) x)
— brak (n (nth 2 x) x)
0 (n (nth 0 x) x)) (n (nth 0 x) x)) 1 (nth 0 x)) 1 x)
W języku AutoLISP funkcje car , cadr oraz caddr s ą cz cz ęsto używane w celu uzyskania współrzędnych X, Y oraz Z punktu. Przykładowo, jeśli zmienna punkt jest jest listą trzech trzech liczb (współrzędnych) — (1 2.5 –5), wówczas: (car punkt)
(nth 0 punkt) i zwraca 1
(c (cad adr r pun punkt kt) )
(nt (nth h 1 pu punk nkt) t) i zwraca 2.5
(c (cad addr dr punk punkt) t)
(nth (nth 2 pu punk nkt) t) i zwraca -5
21/ E{jbbojb ob mjtubdi
316
21/3/7/ [bnjbob fmfnfou fmfnfoux x ob mjdjf Jedną z z podstawowych czynności operacji na listach jest wymiana jej poszczególnych elementów. Do tego celu służy wbudowana funkcja AutoLISPu subst. Jej format jest następują ccy: y: newitem old oldite item m lis list t) (subst newitem
Funkcja wyszukuje argument olditem wśród elemen elementów tów argumentu argumentu list i i zwraca kopię tej listy, w której każdy argument olditem został zastą piony piony przez argument newitem. Jeżeli lista podana w argumencie list nie nie zawiera elementów olditem, to funkcja subst zwracaa argument zwrac argument list w niezmienionej niezmienionej posta postaci. ci. U życie funkcji funkcji subst wyjaśnim nimy y na poniższych przykładach.
Qs{zlbe 2 Używają c instrukcji przypisania (s (set etq q li list sta_ a_1 1 (l (lis ist t 1 2 3 4 5) 5)) ) ;z ;zwr wrac aca a (1 2 3 4 5)
tworzymy listę pięciu atomów cyfrowych. Lista ta zapisana jest pod zmienn ą lista_1. Jeżeli chcemy wymienić na tej liście cyfrę 2 na 25, możemy zrobić to następują cco: o: (s (sub ubst st 25 2 li list sta_ a_1) 1) zwraca (1 25 3 4 5)
Ewaluacja zmiennej lista_1 daje jednak !lista !li sta_1 _1 (ev (eval al 'lista 'lista_1) _1) (eval (eval (quote (quote lista_ lista_1)) 1))
zwraca (1 2 3 4 5). Aby zmienna lista_1 została uaktualniona, należy u żyć instrukcji podstawienia setq. (s (set etq q li list sta_ a_1 1 (s (sub ubst st 25 2 li list sta_ a_1) 1)) ) zwraca (1 25 3 4 5) oraz przypisuje
powyższą list listę zmiennej lista_1. Tak więc ewaluacja zmiennej lista_1 daje ( 1 2 5 3 4 5 ). Jeśli chcemy wcześniej pobrać z klawiatury klawiatury nowy i stary wzorz wzorzec ec do wymian wymiany y na liście, albo deklarujemy je wprost np. (setq x1 25 x2 2), albo pobieramy je przy pomocy funkcji getxxx ,np. (setq lista_1 (list 1 2 3 4 5) zwraca (1 2 3 4 5) x1 (get (getre real al "Pod "Podaj aj nowa nowa wart wartos osc: c: ") ;2 ;25 5 x2 (getre (getreal al "Poda "Podaj j st star ara a wa wart rtos osc: c: ") ;2 );setq (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 li list sta_ a_1) 1)) ) zw zwra raca ca (1 25 3 4 5)
Jeśli chcemy chcemy dodat dodatkowo kowo podstawić pod wyb wybran raną zmienną nazwę listy, listy, możemy to zrobić na trzy sposoby:
317
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst sposób 1: Nazwę listy deklarujemy wprost, np. (s (set etq q li list sta_ a_1 1 (l (lis ist t 1 2 3 4 5) 5)) ) zwraca ( 1 2 3 4 5 )
zwraca ( 1 2 3 4 5 ) zwraca LIST (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 x3 x3)) )) zwraca ( 1 2 5 3 4 5 ) (setq (se tq x3 lista_ lista_1) 1)
(type (ty pe x3)
sposób 2: Nazwę listy deklarujemy wprost, z tym, że jest to nazwa kwotowana, np. (s (set etq q li list sta_ a_1 1 (l (lis ist t 1 2 3 4 5) 5)) ) zwraca ( 1 2 3 4 5 )
zwraca LISTA_1 zwraca SYM zwraca ( 1 2 3 4 5 ) (eval x3) (eval (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 x3 x3)) )) zwraca error: error: bad arg argume ument nt (setq (se tq x3 'lista 'lista_1) _1)
(type (ty pe x3)
type (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 (e (eva val l x3 x3)) ))) )zwraca ( 1 2 5 3 4 5 )
sposób 3: Nazwę listy pobieramy z klawiatury za pomocą funkcji funkcji read oraz getstring, np. (s (set etq q li list sta_ a_1 1 (l (lis ist t 1 2 3 4 5) 5)) ) zwraca ( 1 2 3 4 5 ) (setq x3 (read (read (getst (getstrin ring g "Podaj "Podaj naz nazwe we listy: listy: ")) );setq
Podanie w odpowiedzi lista_1 zwróci LISTA_1. (type (ty pe x3) zwraca SYM (eval (ev al x3) zwraca ( 1 2 3 4 5 ) (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 x3 x3)) )) zwraca error: error: bad arg argume ument nt type (s (set etq q li list sta_ a_1 1 (s (sub ubst st x1 x2 (e (eva val l x3 x3)) ))) ) zwraca ( 1 2 5 3 4 5 )
Qs{zlbe 3 Używają c instrukcji przypisania (s (set etq q li list sta_ a_2 2 (l (lis ist t 1 2 -5 2 10 2)) 2)) ;z ;zwr wrac aca a (1 2 -5 2 10 2)
tworzymy listę sze ściu atomów cyfrowych. Lista ta zapisana jest pod zmienn ą lista_2 lista_2. Wymiana na tej liście cyfry 2 na 25 za pomoc ą funkcji Wymiana funkcji subst, da następują cy cy wynik: se setq tq li list sta_ a_2 2 (s (sub ubst st 25 2 li list sta_ a_2) 2)) ) zwraca (1 (1 25 -5 25 10 25)
Funkcja subst wymienia wszystkie wystą pienia pienia cyfry 2 na li ście lista_2 na liczbę 25. Jeśli zachod zachodzi zi pot potrze rzeba ba wym wymian iany y tylk tylko o jedneg jednego o wys wysttą p pien ienia ia cy cyfr fry y 2 (o okre określonym indeksie) na liście, należy napisać własną funkcj funkcję wymiany.
21/ E{jbbojb ob mjtubdi
318
Qs{zlbe 4 Używają c instrukcji przypisania (setq (se tq lista_ lista_3 3 '((1 '((1 "A")(2 "A")(2 "B" "B")(3 )(3 "C")(4 "C")(4 "D" "D"))) )))
zwraca ((1 "A")(2 "A")(2 "B" "B")(3 )(3 "C")(4 "C")(4 "D"))) "D"))) tworzymy listę czteroelementową , w której ka żdy element jest podlistą . Wymiana podlis listt jest jest troch trochę bardziej bardziej skomp skomplikowa likowana, na, podam więc tylk tylko o got gotowe owe rozwią zania zania bez wgłębiania się w szczegóły.
sposób 1: Wszystkie elementy są nam nam z góry znane. (s (sub ubst st (3 "A "ACA CAD" D") ) (3 "C "C") ") li list sta_ a_3) 3)
zwraca error: bad function (3 "ACAD") (subst (su bst '(3 "AC "ACAD" AD") ) '(3 "C" "C") ) lista_ lista_3) 3)
zwraca ((1 "A")(2 "B")(3 "ACAD")(4 "D"))
sposób 2: Nazwy elementów pobieramy z klawiatury i podstawiamy pod odpowiednie zmienne, z którymi wywołujemy funkcję subst. (s (set etq q x1 (r (rea ead d (g (get etst stri ring ng T "P "Pod odaj aj no nowy wy el elem emen ent t li list sty: y: ") "))) ))
Argument T w funkcj funkcjii getstring umożliw liwia ia nam wst wstawi awiani aniee spacji spacji w podawa podawanym nym łańcuchu cuchu,, a tym samym możemy podać poszczególne elementy podlisty. Jeśli na powyższe zapytanie odpowiemy np. (2 "Marek"), wówczas: zwraca LIST (eval (ev al x1) zwraca error: error: bad fun functi ction on (2 "Marek "Marek"), "), gdyż w tym przypadku interpreter próbował wykonać funkcję o nazwie 2 z argumentem (type (ty pe x1)
"Marek". (e (eva val l 'x 'x1) 1) (e (eva val l (q (quo uote te x1 x1)) )) zwraca (2 "Marek "Marek") ") (s (set etq q x2 (r (rea ead d (g (get etst stri ring ng T "P "Pod odaj aj st star ary y el elem emen ent t li list sty: y: ") "))) ))
Jeśli na powyższe pytanie odpowiemy np. (2 "B"), wówczas: zwraca LIST zwraca error error: : ba bad d fu func ncti tion on (2 "B "B") ") (eval (ev al 'x2) 'x2) zwraca (2 "B "B") ") (type (ty pe x2) (eval x2) (eval
(setq (se tq x3 (read (read (getst (getstrin ring g "Podaj "Podaj nazwe nazwe listy: listy: "))) ")))
Brak argumentu T w w funkcji getstring powoduje zakończenie podawania stringu w momencie naciśnięcia spacji bą dź klawisza ENTER.
319
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Jeśli na powyższe pytanie odpowiemy np. lista_3, wówczas: zwraca SYM zwraca ((1 "A")(2 "A")(2 "B" "B")(3 )(3 "C")(4 "C")(4 "D" "D")) )) (eval (ev al 'x3) 'x3) zwraca LISTA_3
(type (ty pe x3)
(eval (ev al x3)
(s (sub ubst st (e (eva val l 'x 'x1) 1) (e (eva val l 'x 'x2) 2) (e (eva val l x3 x3)) ))
zwraca ((1 "A" "A")(2 )(2 "Ma "Marek rek")( ")(3 3 "C")(4 "C")(4 "D" "D")) )) (s (set etq q x4 10 10) ) zwraca 10 (eval (ev al x4)
zwraca 10
(eval (ev al 'x4) 'x4) zwraca 10 (s (sub ubst st x4 (e (eva val l 'x 'x2) 2) (e (eva val l x3 x3)) )) jest równoważne (s (sub ubst st (e (eva val l 'x 'x4) 4) (e (eva val l 'x 'x2) 2) (e (eva val l x3 x3)) ))
i zwraca (( ((1 1 "A "A") ") 10 (3 "C "C") ")(4 (4 "D "D") ")) )
Qs{zlbe 5 Użycie funkcji funkcji subst w połą czeniu czeniu z assoc umo żliwia wygodną wymian wymianę wartości powią zanej zanej z jednym kluczem na liście asocj asocjacji. acji. Przykładow Przykładowo, o, jeżeli dokonamy podstawienia: (setq kto '((IMI '((IMIE E "Marek")(NA "Marek")(NAZWISKO ZWISKO "Dudek")(ZAKLAD "Dudek")(ZAKLAD "CMG KOMAG Gliwice")) );setq
wówczas: (s (set etq q x1 (a (ass ssoc oc 'i 'imi mie e kt kto) o)) ) zwraca (IMIE "Marek") "Marek") (setq x2 '(imie (setq '(imie "Jacek "Jacek")) ")) zwraca (IMIE "Jacek") "Jacek") (s (set etq q kt kto o (s (sub ubst st x2 x1 kt kto) o)) )
zwraca ((IMIE "Jacek")(NAZ "Jacek")(NAZWISKO WISKO "Dudek")(ZA "Dudek")(ZAKLAD KLAD "CMG KOMAG Gliwice"))
Na koniec tego punktu zostanie przedstawiony program wymieniają cy cy n-ty element na liście. ;*************************************************PROG_038 ;Progr ;Pr ogram am do zamian zamiany y n-tego n-tego ele elemen mentu tu na liscie liscie. . ; ;------------------------------------------------;Zdefiniowa ;Zdef iniowanie nie funkc funkcji ji zatrzymujac zatrzymujacej ej realizacje realizacje programu. programu. ;Kontynuacj ;Kont ynuacja a po nacisnieciu nacisnieciu ENTER. ENTER. ; (defun (de fun PAU PAUSE_ SE_1 1 () (progn ;---------(getstring (getst ring "\nNacisnij "\nNacisnij ENTER...") ENTER...") ;---------(princ) ;----------
21/ E{jbbojb ob mjtubdi );progn );PAUSE_1 ; ;------------------------------------------------;Zdefi ;Zd efinio niowan wanie ie funkcj funkcji i do wymian wymiany y n-tego n-tego ele elemen mentu. tu. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z trzema trzema argume argumenta ntami: mi: ;numer ;nu mer - numer numer elemen elementu tu wymien wymienian ianego ego ; liczac od zera ;nowa_ ;no wa_war wartos tosc c - lancuc lancuch h z nowym nowym elemen elementem tem ;l ;lis ista ta - la lanc ncuc uch h z na nazw zwa a li list sty y ; (defun (defu n WYMIEN_ELEM WYMIEN_ELEMENT ENT (numer nowa_wartos nowa_wartosc c lista / dlugos dlugosc c lista_ lista_pom pom_1 _1 lista_pom_2 lista_ pom_2 licznik licznik element ) (progn ;---------(setq dlugos dlu gosc c (lengt (length h (eval (eval (read (read lista) lista))) )) lista_ lis ta_pom pom_1 _1 (eval (eval (read (read lista) lista)) ) lista_pom_2 lista_ pom_2 (list) liczni lic znik k 0 );setq ;---------(repeat (repea t dlugosc dlugosc (progn ;---------(setq (se tq elemen element t (nth (nth liczni licznik k lista_ lista_pom pom_1) _1)) ) (if (= liczni licznik k numer) numer) (progn (pr ogn ;wymie ;wymienia niaj j (setq lista_pom_2 (appen (ap pend d lista_ lista_pom pom_2 _2 (list (list (read (read nowa_wartosc))) );setq );progn (p (pro rogn gn ;e ;els lse e - ni nie e wymien wymienia iaj j (setq lista_pom_2 (append (appen d lista_pom_2 lista_pom_2 (list element)) element)) );setq );progn );if (setq (se tq liczni licznik k (1+ lic liczni znik)) k)) ;---------);progn );repeat );repe at licznik licznik ;---------(set (se t (read (read lista) lista) lis lista_ ta_pom pom_2) _2) ;---------(princ) ;----------
31:
321
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst );progn );WYMIEN_ELEMENT ; ;------------------------------------------------;Utworzenie ;Utwo rzenie listy lista_1. lista_1. ; (setq lista_ lis ta_1 1 '( 1 (2 "AutoC "AutoCAD") AD") (3 . 50) (4 (1 2 3)) "TEST" 1.25 ) );setq ;------------------------------------------------;Wyswietlen ;Wysw ietlenie ie zawartosci zawartosci poczatkowej poczatkowej listy lista_1. lista_1. ; (textpage) (princ (prin c "Oto zawartosc zawartosc poczatkowa poczatkowa listy lista_1:\n\n lista_1:\n\n") ") (prin1 (prin 1 lista_1) lista_1) (terpri) (PAUSE_1) (princ) ;------------------------------------------------;W ;Wej ejsc scie ie w pe petl tle e WH WHIL ILE E - wy wymi mian ana a na li lisc scie ie. . ; (setq (se tq jeszcz jeszcze e T) (while (whil e jeszcze jeszcze (progn ;---------;sprawdzenie ;spraw dzenie, , czy konczy konczymy my (textpage) (i (ini nitg tget et 1 "T t N n" n") ) (setq warunek warune k (getkword (getkword "Czy "Cz y konczy konczysz sz [T/N]: [T/N]: " );getkword );setq ;---------;gdy konczymy konczymy (i (if f (o (or r (= wa waru rune nek k "T "T") ")(= (= wa waru rune nek k "t "t") ")) ) (progn (setq (se tq jeszcz jeszcze e nil) nil) (graphscr) );progn );if ;---------;gdy ;gd y nie kon konczy czymy my (i (if f (o (or r (= wa waru rune nek k "N "N") ")(= (= wa waru rune nek k "n "n") ")) ) (progn ;---------;pobranie ;pobra nie argumentow argumentow funkcji funkcji WYMIEN_ELEM WYMIEN_ELEMENT ENT
21/ E{jbbojb ob mjtubdi (setq arg_1 (getint (getint "\ "\nP nPod odaj aj nu nume mer r el elem emen entu tu do wy wymi mian any y ar arg_ g_1 1 = " );getint arg_2 arg _2 (getst (getstrin ring g T "P "Pod odaj aj no nowa wa wa wart rtos osc c ar arg_ g_2 2 = " );getstring arg_3 (getstring (getstring "P "Pod odaj aj na nazw zwe e li list sty y ar arg_ g_3 3 = : " );getstring );setq (i (if f (= ar arg_ g_3 3 "" "") ) (progn (setq arg_3 "lista_1") "lista_1") );progn );if ;---------;sprawdzeni ;spraw dzenie e argumentow argumentow ;wywolanie ;wywol anie funkcji funkcji WYMIEN_ELEM WYMIEN_ELEMENT ENT w przypadku przypadku ;poprawnego ;popra wnego podania podania argumentow argumentow (if (/= (type (eval (eval (read (read arg_3) arg_3))) )) 'LIST) 'LIST) (progn (princ (strcat "\ "\nA nArg rgum umen ent t ar arg_ g_3 3 = " arg_3 " ni nie e je jest st na nazw zwa a li list sty! y!!! !!" " );strcat );princ (PAUSE_1) );progn (p (pro rogn gn ;e ;els lse e - sp spra rawd wdza zaj j da dale lej j (setq (se tq dlugos dlugosc c (lengt (length h (eval (eval (read (read arg_3) arg_3)))) ))) (i (if f (o (or r (< ar arg_ g_1 1 0) 0)(> (>= = ar arg_ g_1 1 dl dlug ugos osc) c)) ) (progn (princ (strcat "\ "\nE nEle leme ment nt o in inde deks ksie ie ar arg_ g_1 1 = " (r (rto tos s ar arg_ g_1 1 2 0) " ni nie e is istn tnie ieje je na li lisc scie ie " arg_3 "!!!" );strcat );princ (PAUSE_1) );progn (p (pro rogn gn ;e ;els lse e - wy wymi mian ana a na li lisc scie ie ;---------(WYMIEN_ELEM (WYMIE N_ELEMENT ENT arg_1 arg_2 arg_3) arg_3) ;---------;wyswietleni ;wyswi etlenie e nowej wartosci listy (princ (strcat "\n\nZawart "\n\nZ awartosc osc listy "
322
323
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst arg_3 " po wymian wymianie: ie:\n\ \n\n" n" );strcat );princ (prin1 (pr in1 (ev (eval al (read (read arg_3) arg_3))) )) (PAUSE_1) ;---------);progn );if );progn );if ;---------);progn );if ;---------);progn );while );whi le jeszcze jeszcze ;------------------------------------------------(princ) ;------------------------------------------------;*************************************************KONIEC
Wykonanie powyższego programu może wyglą da dać następują cco: o: Command: (load "prog "prog_038") _038")↵ Oto zawart zawartosc osc poczat poczatkow kowa a listy listy lista_ lista_1: 1: (1 (2 "A "Aut utoC oCAD AD") ") (3 . 50 50) ) (4 (1 2 3) 3)) ) "T "TES EST" T" 1. 1.25 25) ) Nacisnij Nacis nij ENTER. ENTER... ..↵ Czy konczy konczysz sz [T/N]: [T/N]: n↵ Po Poda daj j nu nume mer r el elem emen entu tu do wy wymi mian any y ar arg_ g_1 1 = 2↵ Po Poda daj j no nowa wa wa wart rtos osc c ar arg_ g_2 2 = (3 . 100) 100)↵ Podaj Pod aj nazwe nazwe listy listy arg_3 arg_3 = : :
↵
Zawart Zaw artosc osc lis listy ty lista_ lista_1 1 po wymian wymianie: ie: (1 (2 "A "Aut utoC oCAD AD") ") (3 . 10 100) 0) (4 (1 2 3) 3)) ) "T "TES EST" T" 1. 1.25 25) ) Nacisnij Nacis nij ENTER. ENTER... ..↵ Czy konczy konczysz sz [T/N]: [T/N]: n↵ Po Poda daj j nu nume mer r el elem emen entu tu do wy wymi mian any y ar arg_ g_1 1 = 4↵ Po Poda daj j no nowa wa wa wart rtos osc c ar arg_ g_2 2 = demo1↵ Podaj Pod aj nazwe nazwe listy listy arg_3 arg_3 = : :
↵
Zawart Zaw artosc osc lis listy ty lista_ lista_1 1 po wymian wymianie: ie: (1 (2 "A "Aut utoC oCAD AD") ") (3 . 10 100) 0) (4 (1 2 3) 3)) ) DE DEMO MO1 1 1. 1.25 25) )
21/ E{jbbojb ob mjtubdi
324
Nacisnij Nacis nij ENTER. ENTER... ..↵ Czy konczy konczysz sz [T/N]: [T/N]: n↵ Po Poda daj j nu nume mer r el elem emen entu tu do wy wymi mian any y ar arg_ g_1 1 = 4↵ Po Poda daj j no nowa wa wa wart rtos osc c ar arg_ g_2 2 = "D "Dem emo2 o2" "↵ Podaj Pod aj nazwe nazwe listy listy arg_3 arg_3 = : :
↵
Zawart Zaw artosc osc lis listy ty lista_ lista_1 1 po wymian wymianie: ie: (1 (2 "A "Aut utoC oCAD AD") ") (3 . 10 100) 0) (4 (1 2 3) 3)) ) "D "Dem emo2 o2" " 1. 1.25 25) ) Nacisnij Nacis nij ENTER. ENTER... ..↵ Czy konczy konczysz sz [T/N]: [T/N]: n↵ Po Poda daj j nu nume mer r el elem emen entu tu do wy wymi mian any y ar arg_ g_1 1 = 3↵ Po Poda daj j no nowa wa wa wart rtos osc c ar arg_ g_2 2 = (1 (3 . 10) 10) "tes "test" t") )↵ Podaj Pod aj nazwe nazwe listy listy arg_3 arg_3 = : :
↵
Zawart Zaw artosc osc lis listy ty lista_ lista_1 1 po wymian wymianie: ie: (1 (2 "A "Aut utoC oCAD AD") ") (3 .1 .100 00) ) (1 (3 . 10 10) ) "t "tes est" t") ) "D "Dem emo2 o2" " 1. 1.25 25) ) Nacisnij Nacis nij ENTER. ENTER... ..↵ Czy konczy konczysz sz [T/N]: [T/N]: t↵ Command:
Omówmy teraz wyróżnione bloki i linie programu. bloku tym, definiujemy funkcję WYMIEN_ELEMEN WYMIEN_ELEMENT T, służą cą do do wymiany n-te n-tego go elemen elementu tu na pod podane anejj liście. Argume Argument nt numer , pod podany any jako lic liczba zba całkowita, określa pozycję elementu na liście. Argument nowa_wartosc, podany jako łańcuc cuch, h, zaw zawier ieraa nową wartość elementu. elementu. Argum Argument ent lista, pod podany any jako łańcuch, określa nazwę listy, na której b ędziemy dokonywać wymiany. Funkcja nie sprawdza poprawności podanych argumentów — jest to zrobione przed jej wywołaniem. wywoł aniem. Zmienna Zmienna długosc oznacza oznacza liczbę element elementów ów na liście, zmien zmienna na lista_pom_1 jej zawartość, natomiast zmienna lista_pom_2 jest to zawartość listy po wymianie (na począ tku, tku, przed wejściem w pętlę repeat, jest to lista pusta). Następnie, w pętli repeat, posług posługuj ują c się zmienną licznik , pobie pobieramy ramy kolejne elem elemen enty ty listy listy.. Jeśli za zach chod odzi zi równ równo ość zmiennych licznik oraz numer , dokonujemy wymiany, jeśli nie — element pozostaje nie zmieniony. Po wyj ściu z pętli repeat, zmienna lista_pom_2 zawiera uaktualnione uaktualnione eleme elementy. nty. Instru Instrukcj kcją przypisania set, pods podsta tawi wiam amy y zawa zawarto rtość listy lista_pom_2 pod zm zmie ienn nną określoną w w argumencie lista.
W
Tworzymy
listę lista_1, składają cą si się z sześciu elementów różnych typów.
bloku tym, gdy zmienna warunek = "T" lub "t" , umożliwiamy opuszczenie pętli while oraz powrót do ekranu graficznego.
W
325
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst zmienna zmienna warunek = "N" lub "n" , uaktyw uaktywniamy niamy dalszą część programu, pozostają c nadal w pętli while.
Gdy
bloku tym, pobieramy wartości zmiennych arg_1, arg_2 oraz arg_3, będą ce ce argume arg umenta ntami mi wyw wywoła ołania nia funkcj funkcjii WYMIEN_ELEMENT. Pr Przy zy pobi pobier eran aniu iu zmiennej arg_2 stosujemy funkcję getstring z argumentem T — umożliwia to podanie listy — np. (3 . 10) lub ła ńcucha znaków ze spacjami — np. "AutoCAD 12". Przy pobieraniu pobieraniu zmiennej arg_3, funkcję getstring wywołujemy wywołujemy już bez
W
argumentu T , tym samym podawanie łańcucha kończymy naciśnięciem spac spacji ji lub klawisza ENTER. Ma to swoje uzasadnienie w tym, ż e nazwa zmiennej nie może zawierać spacji. Dodatkowo zmienna arg_3 zawiera domyślną nazw nazwę listy , która to lista zostanie wybrana, gdy w odpowiedzi na podanie nazwy listy naciśniemy sam klawisz ENTER (tzn. podamy pusty string). Sprawdzamy,
czy ewaluacja zmiennej arg_3 daje listę.
Jeśli
ewaluacja zmiennej arg_3 nie daje listy, wypisujemy stosowny komunikat, po czym wracamy na począ tek tek pętli while.
Jeśli
ewalua ewaluacja cja zmiennej zmiennej arg_3 daje list listę, obl oblicz iczamy amy jej długo długość oraz spr spraawdzamy, czy numer elementu podany w zmiennej arg_1 jest na podanej liście. Jeśli nie, wypisujemy stosowny komunikat, po czym wracamy na pocz ą tek tek pętli while.
Jeśli
naz nazwa wa lis listy ty i num numer er elemen elementu tu został zostały y pod podane ane pop popraw rawnie nie,, wywołu wywołujem jemy y funkcję WYMIEN_ELEMENT z argumentami arg_1, arg_2 oraz arg_3, po
czym czy m wyświetl wietlamy amy zawar zawarto tość listy po wym wymian ianie. ie. Nas Nasttępni pniee wra wracam camy y na począ tek tek pętli while, umożliwiają c wymianę następnego elementu na liście. Powyższy program przeznaczony jest do interaktywnego dialogu z użytkownikiem. Jeżeli funkcja WYMIEN_ELEMENT ma działać z argumentami pobieranymii aut nym automa omatyc tyczni znie e z np. inn innej ej lis listy, ty, wtedy wtedy argume argument nt nowa_wartosc należy podać dosłownie (np. (1. 30) lub 1.25 zamiast "(1 . 30)" lub "1.25"). Wynika to z niemożności konwersji listy lub symbolu na typ ła ńcuchowy. "(1 . 30)" => (1 . 30) — zastosowanie funkcji read (1 . 30) => "(1 . 30)" — ?
W takim przypadku (argument nowa_wartosc pobierany pobierany automatycznie), linię (append (appen d lista_pom_2 lista_pom_2 (list (read nowa_wartos nowa_wartosc))) c)))
w funkcji funkcji WYMIEN_ELEMEN WYMIEN_ELEMENT T należy zastą pi pić przez (append (appen d lista_pom_2 lista_pom_2 (list nowa_wartos nowa_wartosc)) c))
Odpowiedn Odpowi ednie ie zmiany zmiany wra wraz z z tes testem tem fun funkcj kcjii WYMIEN_ELEMENT_1 zawiera program PROG_039.LSP , znajdują cy cy się na dołą czonej czonej dyskietce.
21/ E{jbbojb ob mjtubdi
326
W wymia wymianie nie automatyczne automatycznejj przew przewa ażnie posługujemy się funkcją subst. subst. Jest to spowodowane tym, ż e każdy klucz wymia wymiany ny posiada inną warto wartość, np.: (( ((1 1 (. (... ..)) )) (2 (. (... ..)) )) (3 (. (... ..)) )) .. ... . (n (. (... ..)) ))) )
Jest to regułą w w listach DXF elementów elementów.. W niektórych przypadk przypadkach ach musimy się jednak posłużyć funkcją WYMIEN_ELEMENT_1 (np. gdy zdefin zdefiniow iowano ano dwa atrybuty o tych samych nazwach lecz innych warto ściach).
21/3/8/ 21/3/8/ Pexsbdbojf Pexsbdbojf lpmfkopdj fmfnfoux djf fmfnfoux ob mjmjdjf Do odwracania kolejności elementów na liście służy wbudowana funkcja AutoLISPu reverse. Format funkcji jest następują ccy: y: (reverse list)
Funkcjaa zwr Funkcj zwraca aca list listę, któ która ra jes jestt two tworzo rzona na prz przez ez odw odwróc róceni eniee kol kolejn ejno ości eleme elementów ntów argumentu list . Przykładowo, jeśli dokonamy następują cych cych podstawień (setq lista_1 ( li list 1 2 3 4 5 ) ;zwraca ( 1 2 3 4 5) li list sta_ a_2 2 (l (lis ist t "A "A" " "B "B" " "C "C" " "D "D") ") ;z ;zwr wrac aca a (" ("A" A" "B "B" " "C "C" " "D "D") ") lista_ lis ta_3 3 '((1 '((1 "A")(2 "A")(2 "B" "B")) )) ;zwrac ;zwraca a ((1 "A" "A")(2 )(2 "B")) "B")) );setq
wówczas: (setq lista_1 (reverse (reverse lista_ lista_1)) 1))
zwraca ( 5 4 3 2 1 ) i podstawia otrzymaną warto wartość pod zmienną lista_1 lista_1 (setq lista_2 (reverse (reverse lista_ lista_2)) 2))
zwraca (" ("D" D" "C "C" " "B "B" " "A "A") ") i podstawia otrzymaną warto wartość pod zmienną lista_2 (setq lista_3 (reverse (reverse lista_ lista_3)) 3))
zwraca ((2 "B")(1 "B")(1 "A" "A")) )) i podstawia otrzymaną warto wartość pod zmienną lista_3
21/3/9/ [ [xspu xspu qpemjtuz qpemjtu z pe ebofhp fmfnfouv fmfnfouv Niech dana będzie następują ca ca lista: (setq (se tq lista_ lista_1 1 '(1.01 '(1.01 1.3 1.35 5 1.20 1.20 1.15 1.15 1.30)) 1.30))
Chcą c sprawdzić np., czy liczba 1.20 wyst ępuje na powyższej liście, możemy posłużyć się wbudowaną funkcj funkcją AutoLISPu AutoLISPu member. Format tej funkcji jest nast ępują ccy: y: expr lis list t) (member expr
327
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Funkcja ta wyszukuje wśród elementów elementów argume argumentu ntu list przypadki występowania obiektu podanego w argumencie expr . W przypadku występowania obiektu expr , zwrac zwracana ana jest lista, której pierwszym elementem jest właśnie ten element, a elementami następnymi są wszystkie wszystkie elementy z listy list , występują ce ce po pierwszym wystą pieniu pieniu elementu wysttępuj pujee w przesz przeszuki ukiwan wanej ej liści cie, e, to wyra wyrażenie enie z funk funkcj cją expr . Jeżeli expr nie wys member zwraca nil. Tak więc dla powyższej listy, użycie funkcji member da następują ce ce rezultaty: (membe (me mber r 1.20 1.20 lista_ lista_1) 1) zwraca (1.2 (1.2 1. 1.15 15 1. 1.3) 3) (setq (se tq zwrot zwrot (membe (member r 1.15 1.15 lista_ lista_1)) 1)) zwraca (1.15 (1.15 1.3) 1.3) oraz
podstawia wartość zwrotną funkcji funkcji member pod zmienną zwrot zwrot . (membe (me mber r 2.50 2.50 lista_ lista_1) 1) zwraca nil, gdyż element 2.50 nie wyst ępuje
na liście lista_1 (setq (se tq zwrot zwrot (membe (member r 2.50 2.50 lista_ lista_1)) 1)) zwraca nil oraz podstawia nil
pod zmienną zwrot zwrot . pustą (membe (me mber r 1.20 1.20 lista_ lista_2) 2) zwraca nil, gdyż lista _2 jest listą pust Użycie funkcji member przedstawię jeszcze na przykładzie zmiennej lista _2. (s (set etq q li list sta_ a_2 2 '( '(1. 1.20 20 "A "Aut utoC oCAD AD" " (1 (10 0 . 20 20) ) (1 (2 3) 3)) ) TE TEST ST)) ))
zwraca (1 (1.2 .2 "A "Aut utoC oCAD AD" " (1 (10 0 . 20 20) ) (1 (2 3) 3)) ) TE TEST ST) ) (member (membe r 1.2 lista_ lista_2) 2) zwraca (1.2 (1.2 "A "Aut utoC oCAD AD" " (1 (10 0 . 20 20) ) (1 (2 3)) TEST) TEST) (s (set etq q x 1. 1.20 20) ) zwraca 1.2 (member (membe r x lista_ lista_2) 2) zwraca (1.2 (1.2 "A "Aut utoC oCAD AD" " (1 (10 0 . 20 20) ) (1 (2 3) 3)) ) TEST) (member "AutoCAD" (member "AutoCAD" lista_2) lista_2) zwraca ("Au ("Auto toCA CAD" D" (1 (10 0 . 20 20) ) (1 (2 3)) TEST) TEST) (setq (se tq x "AutoC "AutoCAD" AD") ) zwraca "AutoCAD" (membe (me mber r x lista_ lista_2) 2) zwraca ("Au ("Auto toCA CAD" D" (1 (10 0 . 20 20) ) (1 (2 3) 3)) ) TEST) (m (mem embe ber r '( '(10 10 . 20 20) ) li list sta_ a_2) 2) zwraca ((10 ((10 . 20 20) ) (1 (2 3) 3)) ) TE TEST ST) ) (s (set etq q x '( '(10 10 . 20 20)) )) zwraca (10 (10 . 20 20) ) (membe (me mber r x lista_ lista_2) 2) zwraca ((10 ((10 . 20 20) ) (1 (2 3)) TE TEST ST) ) (m (mem embe ber r '( '(1 1 (2 3) 3)) ) li list sta_ a_2) 2) zwraca ((1 ((1 (2 3) 3)) ) TE TEST ST) ) (s (set etq q x '( '(1 1 (2 3) 3)) ) zwraca (1 (2 3) 3)) ) (membe (me mber r x lista_ lista_2) 2) zwraca ((1 ((1 (2 3) 3)) ) TE TEST ST) ) (member (memb er 'TEST lista_2) lista_2) zwraca (TEST) (s (set etq q x TE TEST ST) ) zwraca nil (s (set etq q x 'T 'TES EST) T) (s (set etq q x (r (rea ead d "t "tes est" t")) )) zwraca TEST (membe (me mber r x lista_ lista_2) 2) zwraca (TEST)
21/ E{jbbojb ob mjtubdi
328
21/3/:/ Xzt{vljxbojf njojnvn j nbltjnvn 21/3/:/ Xzt{vljxbojf Xzt{vl x qpebofk mjmjdjf djf Interpreter AutoLISPu nie posiada w swojej bibliotece funkcji realizuj ą cej cej to zadanie. Pozostaje nam więc napisać własną funkcj funkcję obsługi. Niech dana będzie lista lista_1: (2 -5 7 20 8 -13 45 -10 15)
Funkcję do wys wyszuk zukiwa iwania nia min minimum imum i mak maksim simum um w pod podane anejj liście nazwie nazwiemy my np. MIN_MAX_Z_LISTY. Funkcja ta będzi dziee wyw wywoły oływan wanaa z arg argume umenta ntami. mi. Gdy Gdyby by funkcja ta miała być zastosowana do list powyższej postaci, wtedy liczbę argumentów funkcjii można ograniczyć do trzech (zakładaj ą cc,, ż e argumentami funkcj argumentami są równie również ła ńcuchy z nazwami nazwa mi zmiennych, zmiennych, pod które zostaną podstawione wyszukane wielkości). Nazwijmy je odpowiednio: nazwa_listy, warto ść_min, warto ść_max. Wywoł Wywołanie anie naszej funkcji mogłoby więc wyglą da dać tak: (MIN_MAX_Z_ (MIN_ MAX_Z_LISTY LISTY lista_1 lista_1 "w_min" "w_min" "w_max") "w_max")
Po wykonaniu wykonaniu funkcj funkcji, i, zmien zmienna na w_min zawiera zawiera wartość minimalną na liście lista_1 (w naszym przypadku jest to –13), zmienna w_max zawiera natomiast wartość maksymalną na na liście (w naszym przypadku jest to 45). Jednak już tutaj daje się zauważyć, ż e funkcj fun kcjaa taka tak a nie spe spełni łni wym wymaga agań uniwersalno Gdy by bow bowiem chc chcie ie policzyć ści. Gdyby ć najpierw minimum i maksimum z wydzielonego obszaru listy, wówczas listiem ę trzeba by rozbić tak, aby wydzielony obszar znalazł się na osobnej liście, a dopiero później wywołać z nią funkcję MIN_MAX_Z_LISTY. Tak więc li licz czba ba ar argu gume ment ntów ów po uzupełnieniu wynosi 5. Brakują cymi cymi argumentami są : nr_pocz — numer elementu na li ście, od którego zaczynamy wyszukiwanie (liczą c od 1 dla elementu pierwszego (zerowego!!!) na li ście), nr_konc — numer elementu na li ście, na którym kończymy wyszukiwanie.
Załóżmy dodatkowo, ż e gdy nr_pocz = –1, wtedy do obliczeń jest brana cała lista (nie jest wtedy brany pod uwagę argument nr_konc) oraz oraz gdy gdy nr_konc = –1, –1, wted wtedy y obliczamy do ostatniego elementu włą cznie cznie (może się to okazać pomocne, gdy chcemy przeszukać listę od numeru np. 8 do końca). Wywołanie naszej uzupełnionej funkcji mogłoby więc wyglą da dać tak: (MIN_M (MI N_MAX_ AX_Z_L Z_LIST ISTY Y lista_ lista_1 1 8 -1 "w_min "w_min" " "w_max "w_max") ")
Naszą list listę lista_1 zaw ężamy wówczas do przedziału (45 –10 15), gdzie warto ść minimalna wynosi wynosi –10, a wartość maksymalna wynosi 45. Nie jest to jednak jeszcze rozwi ą zanie do końca poprawne. Gdyby bowiem zmienna lista_1 miała inną posta postać, np.: (( ((1 1 (0 0 0) 0))( )(2 2 (1 3 5) 5))( )(3 3 ((-5 5 -4 12) 12))( )(4 4 (2 (20 0 4 -1 -10) 0))) ))
wówczas poszczególne elementy listy są podlistami, należy więc wskazać, po którym elemencie eleme ncie podlis podlisty ty przepr przeprowadz owadzamy amy porówn porównywani ywania. a. Dochodzimy Dochodzimy więc do szó szóste stego go i zarazem zarazem ostat ostatniego niego argumentu funkcji: klucz. Jest to łańcuc cuch h określają cy c y zad zadany any
329
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst warunek warune k — wyb wybór ór poszcz poszczegó ególny lnych ch elemen elementów tów z lis listy. ty. Jeśli klucz = "( "(nt nth h 2 (n (nth th 1 x1))", gdzie x1 są to kolejne elementy listy, wówczas dla elementu drugiego x1 = (2 (1 3 5)), a klucz = 5. Dla listy typu (1 4 –8 4 10) klucz = "", a wtedy x1 dla np. trzeci trzeciego ego elemen elementu tu lis listy ty wyn wynosi osi –8. Pon Poniiżej zamie zamieszczo szczono no wydruk programu realizują cego cego wszystkie powyższe zadania. ;*************************************************PROG_040 ;Funkc ;Fu nkcja ja MIN_MA MIN_MAX_Z X_Z_LI _LISTY STY szu szuka ka minimu minimum m i maksim maksimum um ;w pod podane anej j liscie liscie wedlug wedlug zad zadane anego go klucza klucza i wartos wartosci ci ;nr_po ;nr _pocz cz i nr_kon nr_konc c oraz oraz podsta podstawia wia wyszuk wyszukane ane wartos wartosci ci ;pod zmienne wartosc_min wartosc_min oraz wartosc_max wartosc_max. . ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z szesci szescioma oma arg argume umenta ntami: mi: ;nazwa_list ;nazw a_listy y - nazwa_listy nazwa_listy np. *lista_wezlo *lista_wezlow, w, ;klucz ;kl ucz - lancuc lancuch h okresl okreslaja ajacy cy zadany zadany war warune unek k ; np. "(nth 2 x1)" ; gdzie x1 - kolejne pozycje listy ; gdy klucz = "" - x1 = x1 ; np. dla listy (2 9 3 6 -3 ...) ;n ;nr_ r_po pocz cz - nu nume mer r el elem emen entu tu na li lisc scie ie, , od kt ktor oreg ego o ; zaczynamy wyszukiwanie ; (liczac od 1 dla elementu pierwszego). ; Jesli nr_pocz = -1 - wtedy do obliczen ; jest brana cala lista, ;n ;nr_ r_ko konc nc - nu nume mer r el elem emen entu tu na li lisc scie ie, , na kt ktor orym ym ; konczymy wyszukiwanie. ; Jesli nr_konc = -1 - obliczamy do ostatniego ; elementu wlacznie, ;warto ;wa rtosc_ sc_min min - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe zmienn zmiennej, ej, ; pod ktora zostanie podstawiona ; wartosc minimalna, ;warto ;wa rtosc_ sc_max max - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe zmienn zmiennej, ej, ; pod ktora zostanie podstawiona ; wartosc maksymalna. ; ;------------------------------------------------;Przyklady ;Przy klady wywolania: wywolania: ; gdy lista1 = ( 2 - 5 1 -7 20) ; (M (MIN IN_M _MAX AX_Z _Z_L _LIS ISTY TY li list sta1 a1 "" 1 -1 "w "w_m _min in" " "w "w_m _max ax") ") ; => !w_min => -7 ; => !w_max => 20 ; ; ; (setq ; lista_wezlow ; ; ; ; ; ; ; ; ;
'( (1 (2 (3 (7 (9 ) );setq gdzie:
(0 0 0)) ; x1 dla i=0 (1 1 1)) ; x1 dla i=1 (-7 8 12)) ; x1 dla i=2 (5 -10 -4)) ; x1 dla i=3 (2 5 8)) ; x1 dla i=4
21/ E{jbbojb ob mjtubdi ; (1 ( (0 0 0 0) 0)) ) - (n (num umer er_w _wez ezla la (ws (wsp_ p_x x wsp_ wsp_y y wsp_ wsp_z) z)) ) ; ; znalez znalezien ienie ie minima minimalne lnego go i maksym maksymaln alnego ego numeru numeru wezla wezla ; (MIN_M (MIN_MAX_ AX_Z_L Z_LIST ISTY Y ; li list sta_ a_we wezl zlow ow "(c "(car ar x1) x1)" " 1 -1 "w_m "w_min in" " "w_m "w_max ax") ") ; => !w_min => 1 ; => !w_max => 9 ; ; znalez znalezien ienie ie minimal minimalnej nej i maksym maksymaln alnej ej ; ws wspo polr lrze zedn dnej ej X wezlo wezlow w ; (MIN_M (MIN_MAX_ AX_Z_L Z_LIST ISTY Y ; li list sta_ a_we wezl zlow ow "(c "(car ar (nth (nth 1 x1)) x1))" " 1 -1 "x "x_m _min in" " "x_ma "x_max" x") ) ; => !x_min => -7 ; => !x_max => 5 ; ;------------------------------------------------(defun (defu n MIN_MAX_Z_L MIN_MAX_Z_LISTY ISTY (nazwa_list (nazwa_listy y klucz nr_pocz nr_pocz nr_konc nr_kon c wartosc_min wartosc_min wartosc_max wartos c_max / minimu min imum m maksim maksimum um dlugos dlugosc c i j wykona wyk onaj j x1 ) (progn (setq minimum minimu m nil maksimum maksim um nil dlugosc dlugos c (length (length nazwa_listy nazwa_listy) ) i 0 j 0 );setq ;---------;ustal ;us taleni enie e i poczat poczatkow kowego ego oraz oraz rzeczy rzeczywis wistej tej dlugos dlugosci ci ;przeszukiwa ;przes zukiwanej nej listy (i (if f (= nr nr_p _poc ocz z -1 -1) ) (progn (setq i 0 dlugosc dlugos c dlugosc dlugosc );setq );progn );if (i (if f (/ (/= = nr nr_p _poc ocz z -1 -1) ) (progn (i (if f (= nr nr_k _kon onc c -1 -1) ) (progn (setq i (- nr nr_p _poc ocz z 1) dl dlug ugos osc c (- dl dlug ugos osc c i) );setq );progn );if (i (if f (/ (/= = nr nr_k _kon onc c -1 -1) ) (progn (setq
32:
331
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst i (- nr nr_p _poc ocz z 1) dl dlug ugos osc c (+ 1 (- nr nr_k _kon onc c nr nr_p _poc ocz) z)) ) );setq );progn );if );progn );if ;---------;budow ;bu a lis ty-fun i WYKONA WYKONAJ, J, gdy klu klucz cz /= "" (i (if fdowa (/ (/= = listykl kluc ucz z funkcj "" "") )kcji (progn (setq WYKONAJ WYKONA J (list '(/) (append '(setq '(s etq x1) (list (li st (read (read klucz) klucz)) ) );append );list );setq );progn );if ;---------(repeat (repea t dlugosc dlugosc (progn (setq x1 (nth (nth i nazwa_ nazwa_lis listy) ty) );setq (i (if f (= kl kluc ucz z "" "") ) (progn (s (set etq q x1 x1 x1) ) );progn (p (pro rogn gn ;e ;els lse e (WYKONAJ) );progn );if (if (= j 0) (progn (setq minimu min imum m x1 maksim mak simum um x1 );setq );progn );if (i (if f (/ (/= = j 0) (progn (setq minimu min imum m (min (min minimu minimum m x1) maksim mak simum um (max (max maksim maksimum um x1) );setq );progn );if (setq i (+ i 1)
21/ E{jbbojb ob mjtubdi j (+ j 1) );setq );progn );repeat ;---------(set (read wartosc_min) wartosc_min) minimum) minimum) (set (read wartosc_max wartosc_max) ) maksimum) maksimum) ;----------
332
(princ) );progn );MIN_MAX_Z_LISTY ; ;------------------------------------------------;*************************************************KONIEC
Omówmy teraz wyróżnione linie i bloki programu. bloku tym ustalamy warto ści począ tkowe tkowe dla funkcji: zmiennym minimum i maksimum nadajem nadajemy y war warto tośći nil, zmie zmienn nnaa dlugosc określa nam ilość elementów na liście, zmien zmienna na i jest licznikiem pętli repeat, natomiast zmienna j określa nam nam,kt ,który óry elemen elementt lis listy ty będziem dziemy y przet przetwarza warzać (0 — prz przetw etwarz arzamy amy pierws pierwszy zy elemen elementt lis listy ty o ind indeks eksie ie 0, 1 — prz przetw etwarz arzamy amy n-t n-ty y elemen elementt lis listy) ty).. Zmienna j jest wykorzystana przy okre ślaniu minimum i maksimum.
W
blo bloku ku tym tym,, gdy argument argument nr_pocz = –1, ustal ustalamy amy wartość zmiennej i na 0 oraz oraz dług długo ość obliczan obliczanej ej lis listy ty jes jestt rów równa na rze rzeczy czywis wistej tej długo długości li list sty y (t (tzn zn..
W
obliczamy minimum i maksimum ze wszystkich elementów listy). bloku bloku tym tym,, gdy argument argument nr_pocz ≠ 1, ustalamy indeks elementu elementu począ tkowego, tkowe go, od któreg którego o rozpoc rozpoczynamy zynamy przetwarz przetwarzanie anie listy. Dodat Dodatkowo, kowo, je śli argument nr_konc ≠ 1, ustalamy długość przetwarzanej listy (a tym samym indeks elementu końcowego, na którym kończymy przetwarzanie listy).
W
bloku tym sprawdzamy warto ść argumentu klucz. Jeśli jest on inny niż pusty string string,, zna znaczy czy to, że przetw przetwarz arzamy amy lis listtę zagnieżdżoną (tzn. poszczegól poszczególne ne elementy listy głównej są też listami, np.: ((1 (1 3))(2 (5 –8)) ... ). W takim przypadku budujemy listę-funkcję WYKONAJ, która pozwala na wyodr ębnienie daneg danego o skład składnika nika podlisty. Budowa i zastos zastosowanie owanie listy-funkcji listy-funkcji zostanie szczegółowo omówione w rozdziale o funkcjach, tutaj dodam jedynie, że gdy klucz = np. np. "(car "(car x1) x1)" " , wówc wówczas zas ewaluacja ewaluacja listylisty-funkcj funkcjii WYKONAJ daje ((/)(SETQ X1 (CAR X1))) .
W
Wchodzą c
w pętlę repeat, rozpoc rozpoczynam zynamy y wysz wyszukiwan ukiwanie ie minimu minimum m i maksi maksimum mum
wykonujemy emy tyle tyle raz razy, y, ile wyn wynosi osi z podane podść anego go prz przedz edział iału u listy. lis warto zmiennej dlugosc . ty. Pętlę repeat wykonuj Pobieramy
element listy o indeksie i oraz podstawiamy go pod zmienną x1 x1.
bloku tym sprawdzamy, czy mamy do czynienia z list ą zagnie zagnieżdżoną . Jeśli nie, wartość zmiennej x1 nie ulega zmianie. Jeśli mamy do czynienia z listą zagnieżdżoną , wywołu wywołujem jemy y lis listtę-funkcję WYKONAJ, ab aby y pod pod zm zmie ienn nną x1 podstawić wybrany element podlisty.
W
333
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst blok instrukcji zostaje wykonany wówczas, gdy zmienna j ma wartość 0. Jest to prawda tylko dla pierwszego elementu listy. W tym przypadku zarówno zmienna minimum jak i zmienn zmiennaa maksimum ma wartość zmiennej x1.
Ten
przetw przetwarzam arzamy y drugi lub dalsze element elementy y listy, mo żemy je już porównać z poprzednimi wartościami: minimalną i i maksymalną . Do obliczenia nowych wartości minimum i maksimum stosujemy standardowe funkcje AutoLISPu min oraz max. Na koniec, przed powrotem na począ tek t ek pętli repeat, dokonujemy zwiększenia wartości zmiennych i oraz j o 1.
W przypadku, przypadku, gdy
bloku tym, będą c już poza pętlą repeat repeat, korzystają c z instrukcji przypisania set, pod podsta stawia wiamy my obl oblicz iczone one war warto tości nin ninima imaln lną i mak maksym symaln alną pod pod naz nazwy wy zmiennych zmien nych przekazane przekazane w argume argumentach ntach wywołania funkcji: wartosc_min oraz wartosc_max.
W
Przeds Prz edstaw tawion iony y spo sposób sób zwr zwrotu otu obl oblicz iczony onych ch war warto tości ni niee je jest st je jedy dyny nym m możliwym sposobem. Na dyskietce sposobem. dyskietce znajduje si ę program PROG_041.LSP (modyfikacja programu PROG_040.LSP), przedstawi przedstawiaj ają ccy y inny inny spos sposób ób rozw rozwiią zania z ania zwr zwrotu otu warto wartości prze przezz funkcję. Wiecej na ten temat powiemy sobie w rozdziale o funkcjach.
21/3/21/ Vt Vtubmfojf ubmfojf qp{zdkj qp{zdkj fmfnfouv ob mjmjdjf djf W punkci punkciee tym zos zostan tanie ie prz przeds edstaw tawion ionaa funk funkcja cja do ust ustale alenia nia poz pozycj ycjii elemen elementu tu na podanej liście. Zadaniem funkcji jest przeszukanie lub w cz listy, ścielement ęściępodanej znalezienie wybranego elementu lub elementów (jew ślicało dany wyst puje na li ście wielokrotnie), utworzenie listy z numerem (numerami) pozycji elementu na liście oraz zwrot tak utworzonej listy. W przypadku, gdy podany element nie wyst ępuje na liście, funkcja zwraca listę jednoelementową z elementem o wartości –1. A oto i program realizują cy cy powyższe zadania. ;*************************************************PROG_042 ;Funkcja ;Funk cja USTAL_ USTAL_POZYC POZYCJE_ELE JE_ELEMENTU MENTU ustala pozycje pozycje elementu elementu ;w pod podane anej j liscie liscie wedlug wedlug zad zadane anego go klucza klucza i wartos wartosci ci ;nr_po ;nr _pocz cz i nr_kon nr_konc c oraz oraz podsta podstawia wia wyszuk wyszukana ana wartos wartosc c ;pod zmienna zmienna lista_zwrot lista_zwrotna. na. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z szesci szescioma oma arg argume umenta ntami: mi: ;nazwa ;na zwa_li _listy sty - nazwa nazwa listy listy np. *lista *lista_we _wezlo zlow, w, ;nazwa ;na zwa_el _eleme ementu ntu - szukan szukany y elemen element t np. 5 ;klucz ;kl ucz - lancuc lancuch h okresl okreslaja ajacy cy zadany zadany war warune unek k - wybor wybor ; poszczegolnych elementow z listy ; ; ; ; ;n ;nr_ r_po pocz cz ; ; ; ; ;nr_ko ;nr _konc nc
n xl 1e )j "ne pozycje listy gp d. zi" e(n xt 1h-2ko gdy klucz = "" - x1 = x1 np. dla listy (2 9 3 6 –3 ...) - nu nume mer r el elem emen entu tu na li lisc scie ie, , od kt ktor oreg ego o zaczynamy wyszukiwanie (liczac od 1 dla elementu pierwszego). Jesli nr_pocz = -1 - wtedy do obliczen jest brana cala lista, - numer numer elemen elementu tu na liscie liscie, , na ktorym ktorym konczymy konczymy
21/ E{jbbojb ob mjtubdi
334
; wyszukiwanie. Jesli nr_konc = -1 - obliczamy ; do ostatniego elementu wlacznie, ;lista ;li sta_zw _zwrot rotna na - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe zmienn zmiennej, ej, ; pod ktora zostanie podstawiona wyszukana ; wartosc - lista z numerem/numerami ; pozycji podanego elementu. ; Pierwszy element listy ma numer 1. ; UWAGA - w AutoLISPie pierwszy element ; 0o . elementu nie ; W przypal di ks ut ,ygm da y n pu om de ar neg ; ma na liscie,funkcja zwraca wartosc -1. ; ;------------------------------------------------;Przyklady ;Przy klady wywolania: wywolania: ; ;---------------------------------;g ;gdy dy lista lista1 1 = (2 -5 1 -7 20) ;(USTA ;(U STAL_P L_POZY OZYCJE CJE_EL _ELEME EMENTU NTU lis lista1 ta1 -7 "" -1 -1 "wy "wynik nik") ") ; => !wy !wynik => (4) (4) ;(USTA ;(U STAL_P L_POZY OZYCJE CJE_EL _ELEME EMENTU NTU lis lista1 ta1 10 "" -1 -1 "wy "wynik nik") ") ; => !wynik => (-1 (-1) ;---------------------------------;g ;gdy dy li list sta2 a2 = (( ((2) 2) ((-5) 5) (1 (1) ) ((-7) 7) (2 (20) 0)) ) ;(USTAL_POZYCJE_ELEMENTU ; li list sta2 a2 -7 "( "(n nth 0 x1 x1)" )" -1 -1 "wyn "wynik ik" " ;) ; => !wy !wynik => (4) (4) ;---------------------------------;g ;gdy dy li list sta3 a3 = ; ((LIST ((LISTA_W A_WEZL EZLOW) OW)(1 (1 (...)) (...))(2 (2 (...)) (...))(5 (5 (...)) (...))(8 (8 (...)) (...))) ) ;(USTA ;(U STAL_P L_POZY OZYCJE CJE_EL _ELEME EMENTU NTU lis lista3 ta3 2 "(nth "(nth 0 x1)" x1)" 2 -1 "wynik "wynik") ") ; => !wy !wynik => (3) (3) ;---------------------------------;gdy lista4 = (-5 2 8 2 -20 15 2) ;(USTA ;(U STAL_P L_POZY OZYCJE CJE_EL _ELEME EMENTU NTU lis lista4 ta4 2 "" -1 -1 "wynik "wynik") ") ; => ! w wy ynik = > (2 (2 4 7) ;------------------------------------------------; (defun (defu n USTAL_POZYC USTAL_POZYCJE_ELE JE_ELEMENTU MENTU (nazwa_list (nazwa_listy y nazwa_eleme nazwa_elementu ntu klucz klu cz nr_poc nr_pocz z nr_kon nr_konc c lista_zwrotna / li list sta_ a_po pom m dl dlug ugos osc c i j wykona wyk onaj j x1 ) (progn ;---------(setq lista_pom lista_ pom (list) dlugosc dlugos c (length (length nazwa_listy nazwa_listy) ) i 0 j 0 );setq ;---------;ustal ;us taleni enie e i poczat poczatkow kowego ego oraz oraz rzeczy rzeczywis wistej tej dlugos dlugosci ci
335
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst ;przeszukiwa ;przes zukiwanej nej listy (i (if f (= nr nr_p _poc ocz z -1 -1) ) (progn (setq i 0 dlugosc dlugos c dlugosc dlugosc );setq );progn
);if (i (if f (/ (/= = nr nr_p _poc ocz z -1 -1) ) (progn (i (if f (= nr nr_k _kon onc c -1 -1) ) (progn (setq i (- nr nr_p _poc ocz z 1) dl dlug ugos osc c (- dl dlug ugos osc c i) );setq );progn );if (i (if f (/ (/= = nr nr_k _kon onc c -1 -1) ) (progn (setq i (- nr nr_p _poc ocz z 1) dl dlug ugos osc c (+ 1 (- nr nr_k _kon onc c nr nr_p _poc ocz) z)) ) );setq );progn );if );progn );if ;---------;budow ;bu dowa a listylisty-fun funkcj kcji i WYKONA WYKONAJ, J, gdy klu klucz cz /= "" (i (if f (/ (/= = kl kluc ucz z "" "") ) (progn (setq WYKONAJ WYKONA J (list '(/) (append '(setq '(s etq x1) (list (li st (read (read klucz) klucz)) ) );append );list );setq );progn );if ;---------(repeat (repea t dlugosc dlugosc (progn (setq x1 (nth (nth i nazwa_ nazwa_lis listy) ty) );setq (i (if f (= kl kluc ucz z "" "") ) (progn (s (set etq q x1 x1 x1) ) );progn
21/ E{jbbojb ob mjtubdi
336
(p (pro rogn gn ;e ;els lse e (WYKONAJ) );progn );if (if (= x1 nazwa_ nazwa_ele elemen mentu) tu) (progn (setq lista_ lis ta_pom pom (ap (appen pend d lista_ lista_pom pom (li (list st (+ i 1))) 1))) j 1 );setq );progn );if (setq i (+ i 1) );setq );progn );repeat ;---------(i (if f (= j 0) ;e ;ele leme ment ntu u ni nie e ma na li lisc scie ie (progn (setq (se tq lista_ lista_pom pom (li (list st -1)) -1)) );progn );if ;---------(set (read lista_zwrot lista_zwrotna) na) lista_pom) lista_pom) ;----------
(princ) );progn );USTAL_POZYCJE_ELEMENTU ; ;*************************************************KONIEC
Omówmy teraz wyróżnione bloki i linie programu. bloku tym ustalamy wartości począ tkowe tkowe dla funkcj funkcji: i: deklar deklarujemy ujemy pustą list listę lista_pom, do której będziemy wpisywać numery pozycji szukanego elementu na liście; obliczamy długość listy (zmienna dlugosc); zerujemy licznik pętli repeat (zmienna i) oraz zerujemy zmienną j (0 oznacza tu, że podanego elementu nie ma na liście).
W
bloku tym ustalamy ustalamy wartość począ tkow tkową zmiennej zmiennej i oraz rzeczywistą długo długość przeszukiwanej listy. Robimy to analogicznie jak w programie PROG_040.
W
W
blok bloku u tym tym budu buduje jemy my list listę-funkcję WYKONAJ. Będzie dziemy my ją stosować
wówc wówcza zas, s, gdy gd y prze przesz szuk ukiw iwan anaa lis lista tajakjest jewstprogramie li list stą zagnie isttę-funkcję żdżoną .. Lis WYKONAJ budujemy analogicznie PROG_040 Wchodzimy
w pętlę repeat i rozpoczynamy przetwarzanie kolejnych elementów
listy. Pobieramy
element o indeksie i oraz podstawiamy go pod zmienną x1 x1.
337
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst bloku tym sprawdzamy, czy mamy do czynienia z list ą zagnie zagnieżdżoną . Jeśli nie, wartość zmiennej x1 nie ulega zmianie. Je śli tak, wywołujemy listę-funkcję WYKONAJ, aby pod zmienną x1 x1 podstawić wybrany element podlisty.
W
Ten
blok instrukcji zostaje wykonany wówczas, gdy zmienna x1 jest szukanym elementem. Dopisujemy wówczas numer elementu na li ście do listy lista_pom oraz ustawiamy wartość zmiennej j na 1.
Zwiększamy wartość zmiennej i o 1, umożliwiają c tym samym pobranie i sprawdzenie kolejnego elementu z listy. blo blok k instru instrukcj kcjii zos zostaj tajee wyk wykona onany ny wów wówcza czas, s, gdy na liście nie wyk wykryto ryto poszukiwan poszu kiwanego ego eleme elementu. ntu. Zwrac Zwracana ana lista lista_pom zawiera zawiera wtedy wtedy elemen elementt o wartości –1.
Ten Ten
Korzystają c
z instrukcji przypisania set , podstawiamy zawartość listy lista_pom pod naz nazw wę zmiennej przeka przekazan zaną w argume argumenci nciee wyw wywoła ołania nia fun funkcj kcjii — lista_ zwrotna.
21/3/22/ zxjfumfojf xzcsbozdi 21/3/22/ Xzxjfumfojf X X xzcsbozdi fmfnfoux fmfnfoux { mjtuz Czasami zachodzi Czasami zachodzi konieczno konieczność wyświetle wietlenia nia wybranych elementów z listy listy.. Wydruk taki może być informacją dla dla użytkownika programu, może być również użyty przez programistę w fa fazi ziee pisa pisani niaa i test testow owan ania ia funk funkcj cjii twor tworzzą ccych ych li list sty y da dany nych ch oraz oraz dokonują cych cych ich modyfikacji. Poniżej przedstawiono program realizują cy cy to zadanie. ;*************************************************PROG_043 ;Funkc ;Fu nkcja ja wypisu wypisujac jaca a wybran wybrane e elemen elementy ty z listy. listy. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z trzema trzema argume argumenta ntami: mi: ;list_ ;li st_nam name e - nazwa nazwa listy listy ;from ;fr om - numer numer elemen elementu, tu, od ktoreg ktorego o rozpoc rozpoczyn zynamy amy ; wy wypi pisy sywa wani nie e (li (licz czac ac od ze zer ra) ;to - numer numer elemen elementu, tu, na ktorym ktorym konczy konczymy my wypisy wypisywan wanie ie ; ;Przyklad ;Przy klad wywolania wywolania funkcj funkcji: i: ; ;(setq ; li list sta_ a_1 1 ; '( ; (1 (0.0 0.0 0.0) 12) ; (2 (1.0 2.0 0.0) 5) ; (3 (4.0 2.0 0.0) 24) ; (4 (6.0 9.0 0.0) 8) ; ) ;);setq ;(WYPI ;(W YPISZ_ SZ_ELE ELEMEN MENTY TY lista_ lista_1 1 0 2) ; ;================================================= ;
21/ E{jbbojb ob mjtubdi (defun (de fun WYP WYPISZ ISZ_EL _ELEME EMENTY NTY (li (list_ st_nam name e from from to / argumenty argume nty dlugosc dlugosc akt_poz akt_poz licznik_pom ) (progn ;---------(setq (se tq argume argumenty nty T) ;---------;sprawdzenie argumentow ;sprawdzenie argumentow ; ;czy ;cz y LIST_N LIST_NAME AME wskazu wskazuje je na liste liste (if (/= (type (type (eval (eval 'list_ 'list_nam name)) e)) 'LI 'LIST) ST) (progn (princ "\nBledny typ argum argumentu entu LIST_NAME.") LIST_NAME.") (setq (se tq argume argumenty nty nil nil) ) );progn );if ; ;c ;czy zy FR FROM OM je jest st ty typu pu IN INT T (i (if f (a (and nd (/= (type (type from) from) 'INT) 'INT) (/= argume argumenty nty nil nil) ) );and (progn (princ (pr inc "\n "\nBle Bledny dny typ arg argume umentu ntu FRO FROM." M.") ) (setq (se tq argume argumenty nty nil nil) ) );progn );if ; ;c ;czy zy TO je jest st ty typu pu IN INT T (i (if f (a (and nd (/ (/= = (t (typ ype e to to) ) 'I 'INT NT) ) (/= argume argumenty nty nil nil) ) );and (progn (princ (pr inc "\n "\nBle Bledny dny typ arg argume umentu ntu TO. TO.") ") (setq (se tq argume argumenty nty nil nil) ) );progn );if ; ;c ;czy zy FR FROM OM je jest st wi wiek eksz szy y lu lub b ro rown wny y ze zero ro (i (if f (a (and nd (< fr from om 0) (/= argume argumenty nty nil nil) ) );and
338
(progn (princ "\nArg "\n Argume ument nt FROM FROM ma byc wiekszy wiekszy lub rowny zero." zero." );princ (setq (se tq argume argumenty nty nil nil) ) );progn );if ;
339
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst ;c ;czy zy TO je jest st wi wiek eksz szy y lu lub b ro rown wny y ze zero ro (i (if f (a (and nd (< to 0) (/= argume argumenty nty nil nil) ) );and (progn (p (pri rinc nc "\ "\nA nArg rgum umen ent t TO ma by byc c wi wiek eksz szy y lu lub b ro rown wny y zero.") (setq (se tq argume argumenty nty nil nil) ) );progn );if ; ;c ;czy zy FR FROM OM je jest st mn mnie iejs jszy zy lu lub b ro rown wny y od TO (i (if f (a (and nd (> fr from om to to) ) (/= argume argumenty nty nil nil) ) );and (progn (princ (strcat "\nArg "\n Argume ument nt FROM FROM ma byc mni mniejs ejszy zy lub rowny" rowny" " od ar argu gume ment ntu u TO TO." ." );strcat );princ (setq (se tq argume argumenty nty nil nil) ) );progn );if ; ;c ;czy zy FR FROM OM mi mies esci ci si sie e w za zakr kres esie ie li list sty y (i (if f (a (and nd (= (type (type (eval (eval 'list_ 'list_nam name)) e)) 'LI 'LIST) ST) (= (t (typ ype e fr from om) ) 'I 'INT NT) ) (> (>= = fr from om 0) (/= argume argumenty nty nil nil) ) );and (progn (i (if f (= (n (nth th fr from om li list st_n _nam ame) e) ni nil) l) (progn (princ (pr inc "\nArg "\nArgume ument nt FROM FROM wskazu wskazuje je poza poza liste. liste.") ") (setq (se tq argume argumenty nty nil) nil) );progn );if );progn );if ;---------;jesli ;je sli pod podano ano popraw poprawne ne argume argumenty nty (if argume argumenty nty (progn ;---------(i (if f (= fr from om to to) ) (progn (princ (pr inc "\nEle "\nElemen ment t ") (p (pri rinc nc (r (rto tos s fr from om 2 0) 0)) ) (p (pri rinc nc ": ")
21/ E{jbbojb ob mjtubdi (prin1 (pr in1 (nth (nth from from list_n list_name ame)) )) );progn ; (p (pro rogn gn ;e ;els lse e (textscr) (setq dl dlug ugos osc c (+ (- to fr from om) ) 1) akt_poz akt_p oz from licznik_pom liczn ik_pom 1 )setq ; (repeat (repe at dlugosc dlugosc (progn ;---------(princ (pr inc "\n "\nEle Elemen ment t ") (p (pri rinc nc (r (rto tos s ak akt_ t_po poz z 2 0) 0)) ) (p (pri rinc nc ": ") (prin1 (pr in1 (nt (nth h akt_po akt_poz z list_n list_name ame)) )) ;---------(setq akt_po akt _poz z (1+ akt_po akt_poz) z) licznik_pom liczni k_pom (1+ licznik_pom licznik_pom) ) );setq ;---------(i (if f (a (and nd (= liczni licznik_p k_pom om 24)
33:
(< liczni licznik_pom k_pom dlugosc) dlugosc) );and (progn ;---------(getstring (getst ring "\nNacisnij "\nNacisnij ENTER... ENTER... ") (textpage) (setq (se tq liczni licznik_p k_pom om 1) ;---------);progn );if ;---------);progn );repeat );rep eat dlugos dlugosc c );progn );if ;---------);progn );if argumenty argumenty ;---------(princ) ;---------);progn );WYPISZ_ELEMENTY ; ;================================================= ;*************************************************KONIEC
341
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Wykonanie powyższego programu może wyglą da dać następują cco: o: Command: (s (setq test1 '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))↵ (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) Command: (load "prog "prog_043") _043")↵ WYPISZ_ELEMENTY Command: (WYPISZ (WYPISZ_EL _ELEME EMENTY NTY tes test t 0 4)↵ El Elem emen ent t El Elem emen ent t El Elem emen ent t El Elem emen ent t El Elem emen ent t
0: 1: 2: 3: 4:
1 2 3 4 5
Command: (WYPISZ (WYPISZ_EL _ELEME EMENTY NTY tes test t 8 12)↵ El Elem emen ent t 8: 9 El Elem emen ent t 9: 10 El Elem emen ent t 10 10: : 11 El Elem emen ent t 11 11: : 12 El Elem emen ent t 12 12: : 13 Command:
Omówmy teraz wyróżnione linie i bloki programu. wartość zmiennej argumenty na T (prawda). Zmienna ta określa, czy wszystkie wszys tkie argumenty argumenty funkc funkcji ji zosta zostały ły podan podanee popraw poprawnie nie (tzn. spełniają zało założone kryteria). kryter ia). Od wartości tej zmi zmienn ennej ej zale zależy wykonanie lub nie głównej części
Ustawiamy
funkcji WYPISZ_ELEMENTY. bloku tym sprawdzamy, czy argumenty funkcji s ą okre określonego typu oraz czy mieszczą się w zadany zadanych ch prz przedz edział iałach ach.. Spr Sprawd awdzen zeniu iu pod podleg legaj ają następują ce ce wielkości:
W
•
czy arg argume ument nt list_name wskaz wskazuj ujee na li list stę — ina inacz czej ej funk funkcj cjaa nth zasygnalizuje błą d, d,
•
czy argument from jest liczbą całkowit całkowitą — — warunek dla funkcji nth ,
•
czy argument to jest liczbą całkowit całkowitą — — warunek dla funkcji nth ,
•
czy argument from jest większy lub równy zero — pierws pierwszy zy element listy ma indeks 0,
•
czy argument to jest większy lub równy zero — j.w.,
•
czy argument from jest mniejszy lub równy od argume argumentu ntu to — założenie do funkcji — porusz poruszamy amy się do przodu listy,
•
czy argument from mieści się w zakresie listy — warunek dla funkcji nth . Jeżeli choć jeden z powyższych warunków nie jest spełniony, wypisywany jest odpowiedni komunikat o błędzie, po czym wartość zmiennej argumenty ustawiana jest na nil , zapobiegają c tym samym wykonaniu dalszej części funkcji. instrukcja warunkowa if , zawierają ca ca kod do wypisania wybranych elementów, wykonywana jest tylko w przypadku poprawnego podania wszystkich argumentów funkcji WYPISZ_ELEMENTY.
Ta
21/ E{jbbojb ob mjtubdi
342
instrukcja warunkowa if składa się z dwóch bloków. O tym, który blok zostanie wykonany, decyduje wyrażenie (= from to).
Ta
blok instrukcji instrukcji warunk warunkowej owej if wykonywan wykonywany y jest wówcz wówczas, as, gdy żą damy damy wyświetlenia tylko jednego elementu z listy (tzn. gdy argumenty from i to są sobie równe). Zauważ, że do wyświetle wietlenia nia eleme elementu ntu używamy funkcji prin1. Robimy tak dlatego, aby nie straci ć cudzysłow cudzysłowów ów w łańcuchach tekstowych, które mogą by być składnikami elementu listy.
Ten
Ten
blok instrukcji warunkowej if (warunek (warunek na else) wykonywany jest wówczas, gdy żą damy damy wyświetlenia więcej niż jednego elementu z listy. blo bloku ku tym ustaw ustawiam iamy y war warto tości zmiennych zmiennych sterują cych cych pracą pętli repeat. Zmienna dlugosc określa liczbę powtórzeń p ętli. Zmienna akt_poz określa numer elementu do wyświetlenia. Zmienna licznik_pom steruje podziałem wszystkich elementów do wyświetlenia na zestawy po 24 sztuki. Po wyświetle wietleniu niu każdego zestawu realizacja programu jest zatrzymywana do chwili naci śnięcia klawisza ENTER.
W
w pętlę repeat i wypisujemy na ekranie tekstowym poszczególne elementy listy.
Wchodzimy
bloku tym zwiększamy wartości zmiennych akt_poz oraz licznik_pom o 1, umożliwiają c tym samym wyświetlenie kolejnego elementu.
W
Ten
blok instrukcji wykonywany jest wówczas, gdy wyświetlono jeden zestaw
elementów. eleme ntów. Realizac Realizacja ja progra programu mu jest zatrzymywana, zatrzymywana, elementów a użytkownik ma Kontymożliwo ść obejrzenia zawarto ści ekranu — poszczególnych z listy. nuacja programu i wyświetlenie następnych elementów następuje po naciśnięciu klawisza ENTER.
Wydaje się, że funkcja do kasowania podanego/podanych elementów na li ście powinna być w standardowym standardowym wyposażeniu biblioteki AutoLISPu. Niestety, nawet AutoLISP wydanie 12 nie posiada tego typu funkcji. Pora więc na jej stworzenie jako funkcji zewnętrznej. Zanim jednak jedn ak do tego dojd dojdzie, zie, zastanó zastanówmy wmy się przez przez chwi chwillę nad algo algorytm rytmem em jej dzia działani łania. a. Załóżmy, ż e dana jest lista: (1 5 3 2 2 3 8). Jeśli chcielibyśmy usunąć z listy element o wartości 5, powinniśmy otrzymać następują cą list listę: (1 3 2 2 3 8). Efektem usuni ęcia z listy elementu o wartości 2 powinna być lista: (1 5 3 3 8). Może się jednak zdarzyć tak, że chcemy usunąć element listy o podanym numerze (indeksie). W takim wypadku, usunięcie z listy elementu o indeksie 3 (czwarty element na liście, liczą c od 1), powinno dać następują cy cy wynik: (1 5 3 2 3 8). Z powyższych rozważań wynika więc, ż e trudno jest napisać jedną uniwersalną funkcj funkcję do realizacji powyższych zadań (byłaby ona bardzo skomplikowana). Tak Tak więc powy powyższe sze za zada dani niaa rozb rozbije ijemy my na trzy trzy osob osobne ne funk funkcj cje, e, z kt któr óryc ych h każda realizować będzie pojedyncze zadanie.
343
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst
221/4/2/ 1/4/2/ Vtvxb Vtvxbojf ojf xzcsbof xzcsbofhp hp fmfnfouv ob qpebofk mjmjdjf djf W punkcie tym napiszemy funkcj ę do usuwania wybranego elementu na podanej liście. Funkcję nazwiemy USUN_OBIEKT. Powinna być ona wywoływana z co najmniej dwoma argumentami: argumentami: nazwa obiektu do usunięcia oraz nazwa listy. Jak jednak widzieliśmy w poprzednich punktach, lista może być listą zwykł zwykłą — — np. (1 5 –8 10 ... ), lub może to być te ż lista zagnieżdżona — np. ((1 (3 5))(2 (–5 10)) ... ). Nale ży więc dołą czyć trzeci argument funkcji: typ_listy. Argumenty wywołania funkcji nazwiemy odpowiednio: nazwa_obiektu, nazwa_listy oraz typ_listy. Algorytm działania funkcji będzie następują ccy: y: Funkcja przeglą da d a w pętli repeat poszczególne elementy listy. Je śli dany element ma być z niej usunięty, to nie jest on wpisywany na list ę pomocniczą . Po wyjściu z pętli repeat, lista pomocnicza nie zawiera już elementu przeznaczonego do usunięcia. Pod nazwę listy podaną w argumencie wywołania funkcji podstawiona zostaje zawarto ść listy pomocniczej. A oto i program realizuj ą cy cy to zadanie. ;*************************************************PROG_044 ;Funkc ;Fu nkcja ja USUN_O USUN_OBIE BIEKT KT sluzy sluzy do usuwan usuwania ia obiekt obiektu u z listy. listy. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z trzema trzema argume argumenta ntami mi : ;nazwa ;na zwa_ob _obiek iektu tu - obiekt obiekt do usunie usuniecia cia - liczba liczba lub lan lancuc cuch, h, ;nazwa ;na zwa_li _listy sty - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe listy listy ; np. "lista_wezlow" ;typ_l ;ty p_list isty y - typ przetw przetwarz arzane anej j listy listy ; 1 - lista typu (1 5 4 12 ...) ; lub ("mes" "cad" "acad" ...) ; 2 - lista typu ((1 ...)(5 ...)(4 ...) ...) ; lub (("mes" ...)("cad" ...) ...) ; ;------------------------------------------------;Przyklady ;Przy klady wywolania wywolania : ; ;np *x1=>((1 *x1=>((1 ((1)(4)))(2 ((1)(4)))(2 ((5)))(3 ((5)))(3 ((4)(7)(10) ((4)(7)(10)))) ))) ; (USUN_OBIEKT 1 "*x1" 2) ; !*x1 => ((2 ((5)))(3 ((4)(7)(10)))) ; ;np *x2=>((1)(2) *x2=>((1)(2)(3)(4) (3)(4)) ) ; (USUN_OBIEKT 1 "*x2" 2) ; !*x2 => ((2)(3)(4)) ; ;np *x3=>(1 3 2 3 4 3 5) ; (USUN_OBIEKT 3 "*x3" 1) ; !*x3 => (1 2 4 5) ; ;np *x4=>( *x4=>("me "mes" s" "cad" "cad" "acad" "acad") ) ; (USUN_OBIEKT "cad" "*x4" 1)
21/ E{jbbojb ob mjtubdi
344
; !*x4 => ("mes" "acad") ; ;np *x5=>(("mes")("cad")("acad")) ; (USUN_OBIEKT "cad" "*x5" 2) ; !*x5 => (("mes")("acad")) ; ;------------------------------------------------; (defun (defu n USUN_OBIEKT USUN_OBIEKT (nazwa_obiektu (nazwa_obie ktu nazwa_ x1 x2 dl dlug ugos osc c nazwa_listy li list sta1 a1listy i x typ_listy / ) (progn ;---------;ustawienia ;ustaw ienia poczatkowe poczatkowe ; (setq x1 nazwa_ nazwa_listy listy x2 (r (rea ead d x1 x1) ) dlugos dlu gosc c (lengt (length h (eval (eval x2)) x2)) lista1 lis ta1 nil i 0 );setq ;---------;wejsc ;we jscie ie w petle petle repeat repeat ;usuwa ;us uwanie nie podane podanego go elemen elementu tu z listy listy lista1 lista1 ;
(repea (repeat t dlugosc dlugosc (progn (i (if f (= ty typ_ p_li list sty y 1) (s (set etq q x (n (nth th i (e (eva val l x2 x2)) ))) ) (s (set etq q x (c (car ar (nth (nth i (e (eva val l x2 x2)) )))) )) ;e ;els lse e );if (if (/= x nazwa_ nazwa_obi obiekt ektu) u) (setq li list sta1 a1 (a (app ppen end d li list sta1 a1 (l (lis ist t (n (nth th i (e (eva val l x2 x2)) )))) )) );setq );if (s (set etq q i (+ i 1) 1)) ) );progn );repeat ;---------;zwrot zmienionej listy ; (set (se t (read (read x1) lista1 lista1) ) ;---------(princ) ;---------);progn );USUN_OBIEKT ; ;*************************************************KONIEC
345
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Omówmy teraz wyróżnione linie i bloki programu. bloku tym ustalamy warto ści począ tkowe tkowe dla funkcji: pod zmienną x1 podstawiamy łańcuch stawiamy cuch z na nazw zwą li list sty y — np. np. "lw1" ; zmi zmienn ennaa x2 jest symbo symbolem lem oznaczają cym cym nazwę listy — np. LW1 ; ewaluacja zmiennej x2 daje listę, a więc można obliczy obliczyć jej długość i podstawić ją pod zmienną dlugosc; lista pomocnicza lista1 jest na razie list ą pust pustą ; licznik pętli repeat (zmienna i ) ustawiony zostaje na 0.
W
w pętlę repeat i rozpoczynamy przetwarzanie listy głównej. P ętlę repeat wykonujemy tyle razy, ile wynosi wartość zmiennej dlugosc.
Wchodzimy
bloku tym badamy, czy mamy do czynienia z list ą zwykł zwykłą czy czy zagnieżdżoną . Jeśli list listaa jest jest list listą zwykłą , pod pod zm zmie ienn nną x zostaje zostaje podstawiony podstawiony jej kolejny kolejny element (o indeksie i). Jeśli lista jest listą zagnie zagnieżdżoną , pod zmienną x zostaje podstawiona głowa kolejnej podlisty.
W
bloku tym sprawdzamy, sprawdzamy, czy element listy o indeksie i jest różny od elementu przeznaczonego do usunięcia z listy. Je śli tak, element zostaje dopisany na listę pomocniczą lista1 lista1. Jeśli nie, element nie jest dopisywany do listy pomocniczej (tym samym zostanie usunięty z listy głównej głównej). ).
W
Zwiększamy
wartość zmiennej i o 1, umożliwiają c tym samym pobra pobranie nie i sprawdzenie kolejnego elementu z listy.
Będą c
już poz poza pętlą repeat, korz korzys ysta tajją c z in inst struk rukcj cjii przyp przypis isan ania ia set,
podstawiamy listyżpomoc pomocnicze lista1 podwnazw przekazanej zanej ę listy przeka w zmiennej x1zawarto (jest to ść równie nazwaniczej listyjprzekazana argumencie wywołania funkcji nazwa_listy).
21/4/3/ Vtvxbojf x xzcsbofk zcsbofk hsvqz fmfnfoux x hsvqz fmfnfou ob qpebo qpebofk fk mjdjf Funkcja zapre Funkcja zaprezentow zentowana ana poprzednio usuwała pojedynczy obiekt na liście. Obecn Obecnie, ie, zaprezentowane zostaną funkcje, funkcje, usuwają ce ce wybraną grup grupę obiektów na podanej liście. Gdyby na przykład zmienna lista_1 była listą o o następują cej cej zawartości: (1 2 1 3 4 2 4 4 5), wówczas usunięcie z niej liczb 1 i 4 da w efekcie końcowym listę (2 3 2 5). Tak samo, w przypadku listy ((1 2)(2 "ACAD")(1 4)(3 "mes")), usuni ęcie z niej podlist o numerach począ tkowych tkowych 1 i 2 da w efekcie ko ńcowym listę ((3 "mes")). Funkcje te mogą być przydatne do pracy z długimi listami, gdy chcemy usun ąć wszystk wszystkie ie niepotrzebne elementy w jednym przebiegu. Poniżej zaprezentowane zostaną dwie dwie funkcje, realizują ce ce to samo zadanie, wywoływane z tymi samymi argumentami, ró żnią ce c e się jedynie mi ędzy sobą sposobem sposobem działania. Algorytm działania funkcji pierwszej będzie następują ccy: y: Funkcja przeglą da d a w pętli repeat poszczeg poszczególne ólne elementy listy. Dany eleme element nt jest sprawdzany, czy występuje na liście elementów przeznaczonych do usuni ęcia. Jeżeli tak, element nie jest wpisywany na listę pomocniczą lista_temp lista_temp. Po wyjściu z pętli repeat, lista pomocnicza nie zawiera już elementów przeznaczonych do usunięcia. Pod nazwę
21/ E{jbbojb ob mjtubdi
346
listy podaną w argumencie argumencie wywołania funkcj funkcjii podst podstawiona awiona zostaje zawar zawarto tość listy pomocniczej. A oto i program realizuj ą cy cy to zadanie. ;*************************************************PROG_045 ;Funkc ;Fu nkcja ja USUN_O USUN_OBIE BIEKTY KTY_1 _1 sluzy sluzy do usuwan usuwania ia wybran wybranej ej grupy grupy ;obiek ;ob iektow tow z listy. listy. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z trzema trzema argume argumenta ntami: mi: ;lista ;li sta_ob _obiek iektow tow - lista lista obiekt obiektow ow do usunie usuniecia cia - liczby liczby ; lub lancuchy, ; np. (2 7 9 ...) ; lub ("c" "mes" "ACAD" ...) ;nazwa ;na zwa_li _listy sty - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe listy listy ; np. "lista_wezlow" ;typ_l ;ty p_list isty y - typ przetw przetwarz arzane anej j listy listy ; 1 - lista typu (1 5 4 12 ...) ; lub ("mes" "cad" "acad" ...) ; 2 - lista typu ((1 ...)(5 ...)(4 ...) ...) ; lub (("mes" ...)("cad" ...) ...) ; ;------------------------------------------------;Przyklady ;Przy klady wywolania wywolania : ; ;np *x1 => ((1 ((1 ((1)(4 )(4))) )))(2 (2 ((5))) ((5)))(3 (3 ((4)(7 ((4)(7)(1 )(10)) 0)))) )) ; ( UN= _> OB( I( E3 KT( Y( _4 1)) '( (1 ; !U *S x1 7)2 () 10" )* )x )1" 2) ; ;np *x2 => ((1)(2 ((1)(2)(3 )(3)(4 )(4)(5 )(5)) )) ; (USUN_OBIEKTY_1 '(1 3) "*x2" 2) ; !*x2 => ((2)(4)(5)) ; ;np *x3 => (1 2 3 4) ; (USUN_OBIEKTY_1 '(3) "*x3" 1) ; !*x3 => (1 2 4) ; ;n ;np p *x *x4 4 => (" ("me mes" s" "c "cad ad" " "a "aca cad" d") ) ; (USUN_OBIEKTY_1 '("cad") "*x4" 1) ; !*x4 => ("mes" "acad") ; ;np *x5 => (("mes")("c (("mes")("cad")(" ad")("acad" acad")) )) ; (USUN_OBIEKTY_1 '("mes" "cad") "*x5" 2) ; !*x5 => (("acad")) ; ;------------------------------------------------; (defun (defu n USUN_OBIEKT USUN_OBIEKTY_1 Y_1 (lista (lista_obie _obiektow ktow nazwa_listy nazwa_listy typ_li typ _listy sty / x1 x2 dl dlug ugos osc c li list sta_ a_tm tmp p i x ) (progn ;---------;ustalenie ;ustal enie zmiennych zmiennych poczatkowych poczatkowych
347
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst ; (setq x1 nazwa_ nazwa_listy listy x2 (r (rea ead d x1 x1) ) dlugos dlu gosc c (lengt (length h (eval (eval x2)) x2)) lista_tmp lista_ tmp nil i 0 );setq ;---------;wejsc ;we jscie ie w petle petle repeat repeat ;przetwarzan ;przet warzanie ie kolejnych kolejnych eleme elementow ntow listy ; (repeat (repea t dlugosc dlugosc (progn ;---------;pobra ;po branie nie kolejn kolejnego ego elemen elementu tu z listy listy ; (i (if f (= ty typ_ p_li list sty y 1) (s (set etq q x (n (nth th i (e (eva val l x2 x2)) ))) ) (s (set etq q x (c (car ar (nth (nth i (e (eva val l x2 x2)) )))) )) ;e ;els lse e );if ;---------;spraw ;sp rawdze dzenie nie, , czy ele elemen ment t jest jest na ;liscie ;lisci e elementow elementow usuwa usuwanych nych ; (if (membe (member r x lista_ lista_obi obiekt ektow) ow) (progn (p (pri rinc nc) ) ;n ;nie ie rob rob nic );progn (p (pro rogn gn ;e ;els lse e (setq lista_tmp (appen (ap pend d lista_ lista_tmp tmp (list (list (nth (nth i (eval (eval x2)))) x2)))) );setq );progn );if ;---------(s (set etq q i (+ i 1) 1)) ) );progn );repeat ;---------;zwrot zmodyfikowa zmodyfikowanej nej listy ; (set (se t (read (read x1) lista_ lista_tmp tmp) ) ;---------(princ) ;---------);progn );USUN_OBIEKTY_1 ; ;*************************************************KONIEC
Ponieważ program program ten jest jest pod podobn obny y do pro progra gramu mu usu usuwaj wają cego cego pojedy pojedynczy nczy eleme element nt z listy, omówiona zostanie jedynie jego najważniejsza część.
21/ E{jbbojb ob mjtubdi
348
Wykorzystują c
funkcję member, sprawdzamy, czy element z listy głównej jest na liście elementów przeznaczonych do usuni ęcia.
Jeśli
elem elemen entt ma być usunięty z lis listy ty,, ni niee wyko wykonu nuje jemy my ni nicc — ty tym m samy samym m element nie zostanie umieszczony na liście pomocniczej.
Jeśli
elem elemen entt ma pozo pozost staać na liście, cie, dop dopisu isujem jemy y go do listy listy pom pomocn ocnicz iczej ej lista_tmp.
Pora teraz na przed przedstawi stawienie enie drugiego algorytmu do realizacji realizacji powyższeg szego o zadan zadania. ia. Algorytm ten wykorz Algorytm wykorzystuj ystujee konst konstrukcj rukcję tzw. listy-funkcji. Konstr Konstrukc ukcja ja ta zos zostan tanie ie szczegółowo omówiona w rozdziale o funkcjach, teraz więc tylko omówiony zostanie sam algorytm. Załóżmy, ż e mamy następują cą list listę: (1 2 1 3 4 4 5). Je śli chcemy usunąć z listy liczbę 1, możemy napisać poniższy warunek: (i (if f (a (and nd (/ (/= = x 1) 1)) ) (progn (setq lista_ lis ta_tmp tmp (appen (append d lista_ lista_tmp tmp (list (list elemen element)) t)) );setq );progn );if
gdzie: x — pierwszy element podlisty — głowa podlisty element — poszczególne podlisty
Dla powyższego przykładu, x = element . Gdyby jednak lista miała posta ć ((1 "mes")(2 "acad")), wówczas dla podlisty "acad")), podlisty o indek indeksie sie 0, x = 1, a element = = (1 "mes"). Z pewno ścią zauważyłeś również operator and, wyst ystępują cy w wyrażeniu eniu war warunk unkowy owym m if . Oczywiście, gdy należy spełnić tylko jeden warunek, jego obecno ść nie jest konieczna. Ja jedn jednak ak um umie iesz szcz czam am go już ttut utaaj — powó powód d te ten n sta tani niee się oczyw oczywist isty y po przeanalizowaniu reszty przykładu. Wróćmy jednak do naszych rozważań. Jeśli chcemy usunąć z listy liczby 1 i 3, warunek przybierze postać: (i (if f (a (and nd (/ (/= = x 1)( )(/= /= x 3) 3)) ) (progn (setq lista_ lis ta_tmp tmp (appen (append d lista_ lista_tmp tmp (list (list elemen element)) t)) );setq );progn );if
Jeśli chcemy usunąć z listy liczby 1, 3 i 4, warunek przybierze posta ć: (i (if f (a (and nd (/ (/= = x 1)( )(/= /= x 3) 3)(/ (/= = x 4) 4)) ) (progn (setq
349
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst lista_ lis ta_tmp tmp (appen (append d lista_ lista_tmp tmp (list (list elemen element)) t)) );setq );progn );if
Jak więc widać w powyższych przykładach, zmienia się jedynie warunek, jaki musi być spełnio spe łniony, ny, aby elemen elementt poz pozost ostał ał na liście. cie. Język AutoL AutoLISP ISP dopus dopuszcza zcza stosowanie konstrukcji zwanej lista-funkcja. Polega ona na tym, ż eby dany obiekt zbudować jako listę, a następnie wykonać go jak funkcję. Dzięki temu możemy dynamicznie (w czasie wykonywania wykony wania funkcji) funkcji) zmien zmienia iać jej poszc poszczególn zególnee instru instrukcje. kcje. Lista-funkcja pozwala więc na dowolną modyfikacj modyfikację kodu funkcji. Jest to bardzo silna konstrukcja, należy ją jednak stosowa ć bardzo ostrożnie, aby nie spowodować zamieszania w programie. A oto i program realizuj ą cy cy powyższe założenia. ;*************************************************PROG_046 ;Funkc ;Fu nkcja ja USUN_O USUN_OBIE BIEKTY KTY_2 _2 sluzy sluzy do usuwan usuwania ia wybran wybranej ej grupy grupy ;obiek ;ob iektow tow z listy. listy. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z trzema trzema argume argumenta ntami: mi: ;lista ;li sta_ob _obiek iektow tow - lista lista obiekt obiektow ow do usunie usuniecia cia - liczby liczby ; lub lancuchy, ; np. (2 7 9 ...) ; lub ("c" "mes" "ACAD" ...) ;nazwa ;na zwa_li _listy sty - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe listy listy ; np. "lista_wezlow" ;typ_l ;ty p_list isty y - typ przetw przetwarz arzane anej j listy listy ; 1 - lista typu (1 5 4 12 ...) ; lub ("mes" "cad" "acad" ...) ; 2 - lista typu ((1 ...)(5 ...)(4 ...) ...) ; lub (("mes" ...)("cad" ...) ...) ; ;------------------------------------------------;Przyklady ;Przy klady wywolania wywolania : ; ;np *x1 => ((1 ((1 ((1)(4 )(4))) )))(2 (2 ((5))) ((5)))(3 (3 ((4)(7 ((4)(7)(1 )(10)) 0)))) )) ; (USUN_OBIEKTY_2 '(1 2) "*x1" 2) ; !*x1 => ((3 ((4))(7)(10))) ; ;np *x2 => ((1)(2 ((1)(2)(3 )(3)(4 )(4)(5 )(5)) )) ; (USUN_OBIEKTY_2 '(1 3) "*x2" 2) ; !*x2 => ((2)(4)(5)) ; ;np *x3 => (1 2 3 4) ; (USUN_OBIEKTY_2 '(3) "*x3" 1) ; !*x3 => (1 2 4) ; ;n ;np p *x *x4 4 => (" ("me mes" s" "c "cad ad" " "a "aca cad" d") ) ; (USUN_OBIEKTY_2 '("cad") "*x4" 1) ; !*x4 => ("mes" "acad") ; ;np *x5 => (("mes")("c (("mes")("cad")(" ad")("acad" acad")) )) ; (USUN_OBIEKTY_2 '("mes" "cad") "*x5" 2) ; !*x5 => (("acad"))
21/ E{jbbojb ob mjtubdi
34:
; ;------------------------------------------------; (defun (defu n USUN_OBIEKT USUN_OBIEKTY_2 Y_2 (lista (lista_obie _obiektow ktow nazwa_listy nazwa_listy typ_li typ _listy sty / lista_warun lista_ warunkow kow i warunek warunek lista_instr lista_ instrukcji ukcji lista_tmp lista_tmp wy wyko kona naj j x1 x2 dl dlug ugos osc c x ) (progn ;---------;budowa ;budow a poszczegoln poszczegolnych ych warun warunkow kow ; (s (set etq q i 0) (setq lista_warunk lista_warunkow ow (list)) (list)) (setq lista_warunk lista_warunkow ow (list 'and)) ; (repeat (repea t (length (length lista_obiek lista_obiektow) tow) (progn (setq warunek warune k (list '/= 'x (nth (nth i lista_ lista_obi obiekt ektow) ow) );list );setq ;dopisanie ;dopis anie warunku do listy lista_war lista_warunkow unkow (setq lista_warunkow (append (appe nd lista_warun lista_warunkow kow (list warunek)) warunek)) );setq (s (set etq q i (1 (1+ + i) i)) ) );progn );repeat ;---------;lista instrukcji instrukcji listy-funkc listy-funkcji ji WYKONAJ WYKONAJ ; (setq lista_instrukcji '( (progn (setq lista_tmp (appen (ap pend d lista_ lista_tmp tmp (list (list (nth (nth i (eval (eval x2)))) x2)))) );setq );progn ) );setq ;---------;utworzenie ;utwor zenie listy-funkcj listy-funkcji i WYKONAJ WYKONAJ ; (setq WYKONAJ WYKONA J (list '(/) (append '(if)
351
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (list lista_warun lista_warunkow) kow) lista_instrukcji );append );list );setq ;---------;ustalenie ;ustal enie zmiennych zmiennych poczatkowych poczatkowych ;
(setq x1 nazwa_ nazwa_listy listy x2 (r (rea ead d x1 x1) ) dlugos dlu gosc c (lengt (length h (eval (eval x2)) x2)) lista_tmp lista_ tmp nil i 0 );setq ;---------;wejsc ;we jscie ie w petle petle repeat repeat ;przetwarzan ;przet warzanie ie kolejnych kolejnych eleme elementow ntow listy ; (repeat (repea t dlugosc dlugosc (progn (i (if f (= ty typ_ p_li list sty y 1) (s (set etq q x (n (nth th i (e (eva val l x2 x2)) ))) ) (s (set etq q x (c (car ar (nth (nth i (e (eva val l x2 x2)) )))) )) ;e ;els lse e );if (WYKONAJ)
(s (set etq q i (+ i 1) 1)) ) );progn );repeat ;---------;zwrot zmodyfikowa zmodyfikowanej nej listy ; (set (se t (read (read x1) lista_ lista_tmp tmp) ) ;---------(princ) ;---------);progn );USUN_OBIEKTY_2 ; ;*************************************************KONIEC
Omówmy teraz wyróżnione linie i bloki programu. W
bloku tym, przegl ą daj dają c w pętli repeat poszczególne elementy do usunięcia,
umieszczone w argumencie wywołania funkcji lista_obiektow, tworzymy zmienną lista_warunkow lista_warunkow. Jest to lista warunków, jakie musi spełnić dany element, aby nie został usunięty z listy. Przykładowo, dla argumentu lista_obiektow = (1 3 7), zmienna lista_warunkow przybierze postać: (a (and nd (/ (/= = x 1) 1)(/ (/= = x 3) 3)(/ (/= = x 7) 7)) )
21/ E{jbbojb ob mjtubdi
352
bloku bloku tym tym,, two tworzy rzymy my lis listtę instrukcji listy-funkcj listy-funkcjii WYKONAJ. Zmie Zmienna nna lista_instrukcji będzie miała postać:
W
( (progn (setq lista_tmp (appen (ap pend d lista_ lista_tmp tmp (list (list (nth (nth i (eval (eval x2)))) x2)))) );setq );progn )
Dodatkowe Dodatk owe naw nawias iasy y na pocz począ tku t ku i końcu zmi zmienn ennej ej okażą się konieczne konieczne do prawidłowej prawi dłowej budow budowy y listylisty-funkcj funkcjii WYKONAJ, gdy zmien zmienna na lista_instrukcji podana będzie jako jeden z argumentów funkcji append. bloku tym, wykorzystuj ą c utworzone wcześniej listy lista_warunkow i lista_ instrukcji, oraz wykorzystują c funkcje setq, list oraz append, tworzymy naszą listę-funkcję WYKONAJ. Dla powyższych założeń, lista ta będzie miała postać:
W
( (/) (i (if f (a (and nd (/= x 1) 1)(/ (/= = x 3) 3)(/ (/= = x 7) 7)) ) (progn (setq lista_tmp (appen (ap pend d lista_ lista_tmp tmp (list (list (nth (nth i (eval (eval x2)))) x2)))) ) ) ) )
blok bloku u tym usta ustala lamy my wart warto ości pocz począ tkowe tkowe dla funkcj funkcji: i: pod zmi zmienn enną x1 podstawiamy łańcuch z nazwą listy listy — np. "lista_1" ; zmienna x2 jest symbolem oznaczają cym cym nazwę listy — np. LISTA_1; ewalu ewaluacja acja zmiennej x2 daje listę, a więc można obliczyć jej długość i podstawić ją pod zmienną dlugosc; lista pomocnicza lista_tmp jest na razie listą pust pustą ; licznik pętli repeat (zmienna i) ustawiony zostaje na 0.
W
w pętlę repeat i roz rozpoc poczyn zynamy amy prz przetw etwarz arzani aniee listy listy głó główne wnejj (podanej (podan ej w argum argumencie encie nazwa_listy). Pętlę repeat wykonujemy tyle razy, ile wynosi wartość zmiennej dlugosc.
Wchod odzi zimy my Wch
bloku tym badamy, czy mamy do czynienia z list ą zwykł zwykłą czy czy zagnieżdżoną . Jeśli list listaa jest jest list listą zwykłą , pod pod zm zmie ienn nną x zostaje zostaje podstawiony podstawiony jej kolejny kolejny
W
element (o indeksie i). Jeśli podlisty. lista jest listą zagnie zagnieżdżoną , pod zmienną x zostaje podstawiona głowa kolejnej Wywołujemy
liste-funkcje WYKONAJ. Wywołanie to jest identyczne z wywołaniem łaniem dow dowoln olnej ej funkcj funkcji. i. Lis Listata-funk funkcja cja WYKONAJ spraw sprawdz dza, a, cz czy y dany dany elemen elementt ma być usunięty z listy. Jeśli nie nie,, elemen elementt jest jest dop dopisy isywan wany y na lis listtę pomocniczą lista_tmp lista_tmp.
Zwiększamy
wartość zmiennej i o 1,umożliwiają c tym samym pobranie i sprawdzenie kolejnego elementu z listy.
353
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Będą c
już poza pętlą repeat, korzystają c z instrukcji przypisania set, podstawiamy zawarto zawartość listy pomoc pomocnicze niczejj lista_tmp pod na nazw zwę listy przeka przekazanej zanej w zmiennej x1 (jest to również nazwa listy przekazana w argumencie wywołania funkcji nazwa_listy).
21/4/4/ Vtvxbojf fmf fmfnfoux nfoux mjtu mjtuz z p qpebozdi qpebozdi ovnfsbdi )jo )joefltbdi* efltbdi* Załóżmy, ż e mamy następują cą list listę (mogą to to być np. wartości atrybutów bloku): (1 10 1 3 –7). Chcemy usunąć z listy atrybut o indeksie 0 (zerowy element listy). W efekcie końcowym powinn powinniiśmy otrzym otrzymaać listę: (1 (10 0 1 3 –7). –7). Gdyb Gdyby y je jedn dnak ak do te tego go ce celu lu zastosować funkcje omówione powyżej, w efekcie końcowym dostaniemy listę: (10 3 –7) — gdyż funkcja usunie z listy wszystkie elementy o warto ści 1. Jak więc widać, czasem czase m może być potrzebna potrzebna funkcj funkcja, a, usuwa usuwajją ca ca eleme element/ele nt/elementy menty listy o podany podanych ch numerach numera ch (inde (indeksach ksach). ). Poniżej zaprezentowano wydruk funkcji realizują cej cej powyższe założenia. ;*************************************************PROG_047 ;Funkc ;Fu nkcja ja USUN_O USUN_OBIE BIEKTY KTY_N _N sluzy sluzy do usuwan usuwania ia z listy listy obiekt obiektow ow ;o podany podanych ch numerach numerach (indek (indeksach) sach). . ;P ;Pie ierw rwsz szy y el elem emen ent t na li lisc scie ie ma nu nume mer r 0. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z dwoma dwoma argume argumenta ntami: mi: ;numer ;nu mery_o y_obie biekto ktow w - lista lista z numera numerami mi (indek (indeksam sami) i) ; obiektow do usuniecia ; np. (0 1 2 5 7) ;nazwa ;na zwa_li _listy sty - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe listy listy ; np. "lista_elementow" ; ;Przyklady ;Przy klady wywolania wywolania funkcji: funkcji: ; ;n ;np. p. dane1 dane1 => (1 (10 0 20 30 40 50 60 70 80 90 100) 100) ; (USUN_OBIEKTY_N '(0 1 2 3 4) "dane1") ; !dane1 => (60 70 80 90 100) ; ;n ;np. p. da dane ne2 2 => (" ("A" A" "B "B" " "C "C" " "D "D" " "E "E" " "F "F" " "G "G" " "H "H") ") ; (USUN_OBIEKTY_N '(2 3 4 5) "dane2") ; !dane2 => ("A" "B" "G" "H") ; ;------------------------------------------------; (defun (defu n USUN_OBIEKT USUN_OBIEKTY_N Y_N (numer (numery_obi y_obiektow ektow nazwa_listy nazwa_listy / x1 x2 dl dlug ugos osc c li list sta_ a_tm tmp p i ob obie iekt kt ) (progn ;---------;ustalenie ;ustal enie zmiennych zmiennych poczatkowych poczatkowych ; (setq x1 nazwa_ nazwa_listy listy x2 (r (rea ead d x1 x1) )
21/ E{jbbojb ob mjtubdi dlugosc dlugos c (lengt (length h (eval (eval x2)) x2)) lista_tmp lista_ tmp nil i 0 );setq ;---------;wejsc ;we jscie ie w petle petle repeat repeat ;usuwanie ;usuwa nie wskazanych wskazanych obiektow obiektow ;
354
(repeat dlugosc (repeat dlugosc (progn (s (set etq q ob obie iekt kt (n (nth th i (e (eva val l x2 x2)) ))) ) (if (not (not (membe (member r i numery numery_ob _obiek iektow tow)) )) (progn (setq lista_ lis ta_tmp tmp (ap (appen pend d lista_ lista_tmp tmp (li (list st obiekt obiekt)) )) );setq );progn );if (s (set etq q i (1 (1+ + i) i)) ) );progn );repeat ;---------;zwrot zmodyfikowa zmodyfikowanej nej listy ; (set (se t (read (read x1) lista_ lista_tmp tmp) ) ;---------(princ) ;---------);progn );USUN_OBIEKTY_N ; ;------------------------------------------------;*************************************************KONIEC
Omówmy teraz wyróżnione bloki i linie programu. blok bloku u tym tym us usta tala lamy my wa warto rtości pocz począ tkowe tkowe dla fun funkcj kcji: i: pod zmi zmienn enną x1 podstawiamy łańcuch z nazwą listy listy — np. "lista_1" ; zmienna x2 jest symbolem oznaczają cym cym nazwę listy — np. LISTA_1; ewalu ewaluacja acja zmiennej x2 daje listę, a więc można obliczyć jej długość i podstawić ją pod zmienną dlugosc; lista pomocnicza lista_tmp jest na razie listą pust pustą ; licznik pętli repeat (zmienna i) ustawiony zostaje na 0.
W
w pętlę repeat i roz rozpoc poczyn zynamy amy prz przetw etwarz arzani aniee listy listy głó główne wnejj (podanej (podan ej w argum argumencie encie nazwa_listy). Pętlę repeat wykonujemy tyle razy, ile wynosi wartość zmiennej dlugosc.
Wch Wchod odzi zimy my
Pod
zmienną obiekt obiekt podstawiamy podstawiamy element listy o indeksie i .
czy indeks elementu znajduje się na liście indeksów przeznaczonych do usunięcia z listy.
Sprawdzamy, Jeśli
element o podanym indeksie ma pozostać na liście, jest on dopisywany do listy pomocniczej lista_tmp.
355
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Zwiększamy
wartość zmiennej i o 1, umożliwiają c tym samym pobra pobranie nie i sprawdzenie kolejnego elementu z listy.
Będą c
już poz poza pętlą repeat, korz korzys ysta tajją c z in inst struk rukcj cjii przyp przypis isan ania ia set, podstawiamy zawartość listy pomocniczej lista_tmp pod nazwę listy przekazanej w zmiennej x1 (jest to również nazwa listy przekazana w argumencie wywołania funkcji nazwa_listy).
Standardowo AutoCAD wydanie 12 wyposażony jest w funkcję AutoLISPu zdefiniowaną w w systemie ADS — (acad_strlsort list ). Funkcja powoduje uporzą dkowanie dkowanie listy łańcuc cuchów hów teksto tekstowyc wych h w porz porzą dku dku alfabetycz alfabetycznym. nym. Argume Argument nt list zawiera zawiera łańcuchy tekstowe, które mają zostać uporzą dkowane. dkowane. Funkcja acad_strlsort zwraca listę tych samych łańcuchów, ale uporzą dkowanych dkowanych w kolejności alfabetycznej. Przykładowo, Przykł adowo, jeśli zmi zmienn ennaa x1 oznacza oznacza następują cą listę: (" ("c c" "a "a" " "d "d" " "c "cad ad" " "marek" "marek " "acad") "acad"), wówczas wywołanie Command: (setq (setq x1 (ac (acad_ ad_str strlso lsort rt x1) x1)) )↵
zwróci listę w postaci ("a" ("a" "a "aca cad" d" "c "c" " "c "cad ad" " "d "d" " "m "mar arek ek") "). Rozwią zanie zanie powyższe wykazuje jednak pewne braki w zakre zakresie sie stosowania stosowania funkc funkcji ji podlegać tylko listy zawierają ce c e łańcuchy alfanumeacad_strlsort. Sortowaniu mogą podlega ryczne. Nie mogą to to być również listy zagnieżdżone — np. (("c")("a")("d")). Poniżej przedstawiono wydruk programu rozszerzają cego cego zakres sortowanych danych. Dane mogą być wprowadzane na listę w postaci numerycznej lub łańcuchowej, dopuszczalne szcza lne jest również stosowanie stosowanie list zagnie zagnieżdżonych. Uproszczony Uproszczony algorytm algorytm sorto sorto-wania jest następują ccy: y: 1. Two Tworzo rzona na jest lista pomo pomocni cnicza cza,, do której której będziemy dodawać elementy z listy głównej. 2. Jeśli elem elemen entt z list listy y głów główne nejj jest jest mnie mniejs jszy zy od zero zerowe wego go el elem emen entu tu li list sty y pomocniczej, jest on umieszczany na pocz ą tku tku listy pomocniczej. 3. Jeśli elem elemen entt z list listy y głów główne nejj jest jest większy kszy od osta ostatn tnie iego go el elem emen entu tu li list sty y pomocniczej, jest on umieszczany na ko ńcu listy pomocniczej. 4. Jeśli elem elemen entt z list listy y głów główne nejj jest jest większ kszy y od pie pierws rwszeg zego o elemen elementu tu lis listy ty pomocnicze pomoc niczej, j, ale mniejszy od ostatn ostatniego iego elementu listy pomocn pomocniczej iczej,, wywoływana jest funkcja pomocnicza, która umieszcza go w odpowiednim miejscu w ś rodku listy pomocniczej. 5. Po przetworzeniu przetworzeniu wszyst wszystkich kich elemen elementów tów listy głównej, lista pomoc pomocnicza nicza zawiera zawiera elementy posortowane w kolejności wzrastają cej. cej.
21/ E{jbbojb ob mjtubdi
356
A oto i program realizuj ą cy cy powyższe zadanie. ;*************************************************PROG_048 ;Funkc ;Fu nkcja ja SORTUJ SORTUJ_LI _LISTE STE slu sluzy zy do sortow sortowani ania a listy listy ;sortu ;so rtuje je liste liste liczb liczb lub lan lancuc cuchow how w porzad porzadku ku rosnac rosnacym. ym. ; ;Funkc ;Fu nkcja ja wywoly wywolywan wana a jest jest z dwoma dwoma argume argumenta ntami mi : ;nazwa ;na zwa_li _listy sty - lancuc lancuch h okresl okreslaja ajacy cy nazwe nazwe listy listy ; np np. . y "l "lis ista ta_ _we wezl zlow ow" "anej ;typ_l ;ty p_list isty typ sortow sor towane j listy listy ; 1 - l is ista ty typu (1 (1 3 8 2 4 7 . .. ..) ; lub ("c" "a" "d" "cad" ...) ; 2 - li list sta a ty typu pu ((1 ((1 .. ...) .)(3 (3 ...) ...)(8 (8 ...) ...)(2 (2 ...) ...)(4 (4 ...) ...) ...) ...) ; lub (("c" ...)("a" ...)("d" ...)("cad" ...) ...) ; ;------------------------------------------------;Przyklady ;Przy klady wywolania wywolania : ;n ;np p li list sta_ a_we wezl zlow ow => (3 7 2 0 -5 10 -8 -8) ) ; (S (SOR ORTU TUJ_ J_LI LIST STE E "lis "lista ta_w _wez ezlo low" w" 1) 1) ; !lista_wezlow => (-8 (-8 -5 0 2 3 7 10) 10) ;np lista_ lista_wez wezlow low => ((3 5 7)(7)( 7)(7)(2 2 0 1)(0)( 1)(0)(-5) -5)(10 (10)) )) ; (S (SOR ORTU TUJ_ J_LI LIST STE E "lis "lista ta_w _wez ezlo low" w" 2) 2) ; !l !lis ista ta_w _wez ezlo low w => ((-5)( ((-5)(0) 0)(2 (2 0 1)(3 5 7)(7) 7)(7)(1 (10) 0)) ) ;n ;np p *x *x1 1 => (" ("c" c" "a "a" " "d "d" " "c "cad ad" " "m "mar arek ek" " "a "aca cad" d") ) ; (S (SOR ORTU TUJ_ J_LI LIST STE E "*x "*x1" 1" 1) ; !* !*x1 x1 => ("a" ("a" "aca "acad" d" "c" "c" "cad" "cad" "d" "d" "mare "marek" k") ) ;np *x2 => (("c" (("c" 1)("a" 1)("a")(" )("d" d" "f")(" "f")("aca acad" d" -8)("m -8)("mare arek") k")) ) ; (S (SOR ORTU TUJ_ J_LI LIST STE E "*x "*x2" 2" 2) ; !* !*x2 x2 => (( (("a "a") ")(" ("ac acad ad" " -8 -8)( )("c "c" " 1)(" 1)("d" d" "f")(" "f")("ma mare rek" k")) )) ; ;------------------------------------------------; (defun (defu n SORTUJ_LIST SORTUJ_LISTE E (nazwa_list (nazwa_listy y typ_listy typ_listy / nowa_lista_ nowa_l ista_2 2 j jeszcze1 jeszcze1 element_1 element_1 x1 x2 x3 no nowa wa_l _lis ista ta_1 _1 x4 x5 dl dlug ugos osc c i el elem emen ent t x ) (progn ;==================================== ;definicje ;defin icje funkcji funkcji pomocniczyc pomocniczych h ; ;-----------------------------------;funkc ;fu nkcja ja pomocn pomocnicz icza, a, gdy ele elemen ment t nalezy nalezy umiesc umiescic ic w sr srod odku ku li list sty y ; (defun FUN (defun FUNKCJ KCJA_1 A_1 () (progn ;---------(setq nowa_lista_2 nowa_l ista_2 (list) j 0 ;li licz czni nik k petli petli jeszcz jes zcze1 e1 T );setq ;----------
357
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (w (whi hile le je jesz szcz cze1 e1
;d ;dop opok oki i T - pr prze zetw twar arza zamy my li list ste e ; nowa_lista_1
(progn (setq (se tq elemen element_1 t_1 (nth (nth j nowa_l nowa_list ista_1 a_1)) )) (i (if f (= ty typ_ p_li list sty y 1) (setq (se tq x1 elemen element_1 t_1) ) (s (set etq q x1 (car eleme element nt_1 _1)) )) ;e ;els lse e );if (if (< x x1) (progn (setq jeszcze1 jeszcz e1 nil x2 (list) (list) x3 (list) (list) );setq (repea (re peat t j (progn (setq x2 (a (app ppen end d x2 (l (lis ist t (c (car ar nowa_lista_1))) nowa_lista_ nowa_l ista_1 1 (cdr nowa_lista_ nowa_lista_1) 1) );setq );progn );repe );r epeat at j (setq x2 (appen (append d x2 (list (list elemen element)) t)) x3 nowa_l nowa_lista_ ista_1 1 pend nowa_l now a_list ista_2 a_2 (appen (ap d x2 x3) nowa_lista_1 nowa_l ista_1 nowa_lista_2 nowa_lista_2 );setq );progn );if (s (set etq q j (+ j 1) 1)) ) );progn );while );whil e jeszcze1 jeszcze1 ;---------(princ) ;---------);progn );FUNKCJA_1 ; ;-----------------------------------; ;koniec ;konie c definicji definicji funkcji funkcji pomocniczyc pomocniczych h ;==================================== ;definicja ;defin icja funkcji funkcji glownej glownej ; (setq x4 nazwa_ nazwa_listy listy x5 (r (rea ead d x4 x4) ) dlugos dlu gosc c (lengt (length h (eval (eval _x2)) _x2)) i 0 nowa_lista_ nowa_l ista_1 1 (list) );setq ;----------
21/ E{jbbojb ob mjtubdi ;sortowanie listy ;sortowanie ; (repeat (repea t dlugosc dlugosc (progn (s (set etq q el elem emen ent t (n (nth th i (e (eva val l x5 x5)) ))) ) (i (if f (= ty typ_ p_li list sty y 1) (setq (se tq x elemen element) t) (s (set etq q x (c (car ar eleme element nt)) )) ;e ;els lse e
358
);if (if (= i 0) (progn (setq nowa_lista_ nowa_ lista_1 1 (append (append nowa_lista_ nowa_lista_1 1 (list element)) );setq );progn );if (if (= i 1) (progn (setq (se tq elemen element_1 t_1 (nth (nth 0 nowa_l nowa_list ista_1 a_1)) )) (i (if f (= ty typ_ p_li list sty y 1) (setq (se tq x1 elemen element_1 t_1) ) (s (set etq q x1 (car eleme element nt_1 _1)) )) ;e ;els lse e );if (if (< x x1) (setq (se tq nowa_l nowa_list ista_1 a_1 (cons (cons elemen element t
nowa_lista_1)) (s (set etq q ;e ;els lse e nowa_lista_1 (append (appen d nowa_lista_ nowa_lista_1 1 (list element)) element)) );setq );if );progn );if (if (> i 1) (progn (setq x1 (nt (nth h 0 nowa_l nowa_list ista_1 a_1) ) x2 (last nowa_lista_ nowa_lista_1) 1) );setq (i (if f (= ty typ_ p_li list sty y 1) (progn (setq x1 x1 x2 x2 );setq );progn (p (pro rogn gn ;e ;els lse e (setq x1 (c (car ar x1 x1) ) x2 (c (car ar x2 x2) ) );setq );progn );if
359
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (cond (( ((< < x x1 x1) ) ;u ;umi mies esc c na pocza poczatk tku u li list sty y (setq (se tq nowa_l nowa_list ista_1 a_1 (cons (cons elemen element t nowa_lista_1)) ) (( ((> > x x2 x2) ) ;u ;umi mies esc c na koncu koncu listy listy (setq nowa_lista_1 (append (appen d nowa_lista_ nowa_lista_1 1 (list element)) element)) );setq ) (T (FUNKC (FUNKCJA JA_1 _1)) )) ;u ;umi mies esc c w sr srod odku ku li list sty y );cond );progn );if (s (set etq q i (+ i 1) 1)) ) );progn );repeat ;---------;zwrot posortowane posortowanej j listy ; (set (se t (read (read x4) nowa_l nowa_list ista_1 a_1) ) ;---------(princ) );progn );SORTUJ_LISTE
; ;------------------------------------------------; ;*************************************************KONIEC
Rozbudujm Rozbud ujmy y teraz teraz nas naszz algory algorytm tm sor sortow towani ania, a, baz bazuj ują c na zazn zaznac aczo zony nych ch li lini niac ach h i blokach programu. Pobierz
kolejny element listy i podstaw go pod zmienną element element .
Jeśli jest
to lista zwykła, pod zmienną x x podstaw element listy.
Jeśli
jest jest to list listaa za zagn gnie ieżdżona ona,, pob pobier ierzz gło głow wę eleme element ntu u i pods podsta taw w ją pod zmienną x x . przetw przetwarz arzamy amy zer zerowy owy elemen elementt listy, listy, umi umieeść zmienną element na liście pomocniczej nowa_lista_1.
Gdy
Gdy • •
•
przetwarzamy pierwszy element listy
pod zmienną element_1 element_1 podstaw zerowy element listy pod zmienną x1 podstaw element lub głowę elementu (w zależności od tego, czy jest to lista zwykła czy zagnie żdżona) jeśli element listy głównej x jest mniejs mniejszy zy od elementu listy pomoc pomocniczej niczej x1, wstaw element listy głównej na pocz ą tek tek listy pomocniczej, w przeciwnym razie wstaw go na koniec listy pomocniczej nowa_lista_1
21/ E{jbbojb ob mjtubdi Gdy
35:
przetwarzamy kolejne elementy listy
•
pod zmienną x1 x1 podstaw zerowy element listy pomocniczej nowa_lista_1
•
pod zmienną x2 x2 podstaw ostatni element listy pomocniczej nowa_lista_1
•
w zależności od tego, czy przetwarzamy list ę zwykłą czy czy zagnieżdżoną , pod zmienne x1 i x2 podstaw wartości elementów lub ich głowy
•
jeśli eleme element nt listy główne głównejj x jest mniejs mniejszy zy od elementu listy pomocn pomocniczej iczej x1, ws wsta taw w ele eleme ment nt list listy y głów główn nej na pocz począ ttek ek li list sty y pomo pomocn cnic icze zejj nowa_lista_1
•
jeśli element listy głównej x jest większy od elementu listy pomocniczej x1, wstaw staw eleme lement nt list listy y głów główne nejj na koni konieec li lissty pomo pomoccnicz niczej ej nowa_lista_1
•
jeśli elemen elementt lis listy ty głó główne wnejj x jest jest większ kszy y od zer zerowe owego go elemen elementu tu lis listy ty pomocn pom ocnicz iczej, ej, a mni mniejs ejszy zy od ost ostatn atnieg iego o elemen elementu tu lis listy ty pom pomocn ocnicz iczej, ej, wywołaj funkcję pomocniczą FUNKCJA_1 FUNKCJA_1, która umieści go w odpowiednim miejscu listy pomocniczej nowa_lista_1.
Omówmy teraz algorytm działania funkcji pomocniczej FUNKCJA_1. Zadaniem Zadani em funkcj funkcjii jest jest roz rozbic bicie ie lis listy ty pom pomocn ocnicz iczej ej nowa_lista_1 na dwi dwiee pod podlis listy, ty, między które które zos zostan tanie ie wst wstawi awiony ony sor sortow towany any elemen element. t. Pod zmi zmienn enną x zawiera zawiera się element eleme nt listy głównej, pod zmien zmienn ną x1 x1 zawiera się kolejny element z listy pomocniczej lub jego głowa. Dopóki element z listy główne głównejj jest mniejs mniejszy zy od eleme elementu ntu z listy pomocniczej, przetwarzamy elementy listy pomocniczej. Lista x2 powiększa się o kolejny element, eleme nt, natomiast natomiast lista nowa_lista_1 zostaj zostajee skr skróco ócona na o gło głow wę (pierwszy (pierwszy elemen elementt li list sty) y).. Gdy Gdy elem elemen entt z list listy y głów główne nejj jest jest rów równy ny lu lub b większy kszy od el elem emen entu tu z li list sty y pomocniczej pomocn iczej,, kończymy przetwarzani przetwarzanie. e. Lista nowa_lista_1 został zostałaa roz rozbit bitaa na dwi dwiee podlisty: zmienna x2 jest listą zawieraj zawierają cą elementy elementy mniejsze od elementu sortowanego, zmienna x3 jest listą zawierają cą elementy równe lub większe od elementu sortowanego. Wystarczy teraz połą czy czyć listę x2, zmienną x (element podlegają cy cy sortowaniu) oraz listę x3, aby otrzym otrzymaać listę posortowanych elementów.
Na koniec omawiania działań na listach, należy wspomnieć o jeszcze jednej ważnej liście — liście opisu elementów rysunkowej bazy danych AutoCADa. AutoCAD, podobnie jak inne programy prog ramy graficzn graficznee posługu posługuje je się grafik ą ą wektorową . Rysun Rysunek ek tw tworz orzon ony y jes jestt więc z określony lonych ch elem elementó entów, w, takich jak: lini linia, a, wie wieloli lolinia, nia, łuk, teks tekstt itd. itd.,, któr któree z kole koleii można łą czy czyć w oddzieln oddzielnee grupy grupy zwa zwane ne blok blokami. ami. Informac Informacje je o pos poszcze zczególn gólnych ych elem elementa entach ch (zwanych (zwa nych tak że en enty tycj cjam amii od an ang. g. en enti tity ty)) pr prze zech chow owyw ywan anee są w baz bazie ie rys rysunk unkowe owejj AutoCADa.. Znajomość struktury i porzą dku AutoCADa dku zapisu tych info informac rmacji ji jes jestt bardzo bardzo ważna i niezbędn dnaa podcz podczas as pisa pisania nia program programów ów w AutoLISPie AutoLISPie lub w ADSie ADSie.. Pozwa Pozwala la bowiem
361
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst tworzyć procedu procedury ry wykonu wykonujją ccee czyn czynno ności ni niem emo ożli liwe we lub lub bard bardzo zo tr trud udne ne do zrealizowania za pomocą standardowych standardowych komend edytora graficznego. S ą one one poza tym szybsze i bardziej efektywne.
221/6/2/ 1/6/2/ Eptuq YG Eptuq ep mjtuz EYG E Pozn Poznaw awan anie ie struk struktu tury ry rysu rysunk nkow owej ej bazy bazy dany danych ch,, a konk konkre retn tnie ie st stru ruktu ktury ry opis opisu u poszczególnych elementów rysunkowych rozpoczniemy od przykładu linii biegną cej cej od punktu pun ktu o wsp współr ółrzzędny dnych ch 1,1 1,1,1 ,1 do pun punktu ktu o wsp współr ółrzzędny dnych ch 5,1 5,10,0 0,0.. Pow Powy yższą linię rysujemy za pomocą nast następują cej cej sekwencji komend: Command: _line↵ From Fro m point: point: 1,1,1↵ To poi point: nt: 5,10,0↵ To poi point: nt: Command:
↵
Być mo że zauważyłeś znak podkreślenia "_" przed komendą LINE. LINE. Znak ten realizuje obsługę j ęzyków narodowych. Jeśli program pisany w AutoLISPie ma być u żywany we współpracy z narodowymi wersjami AutoCADa, standardowe polecenia i słowa kluczowe AutoCA AutoCADa Da będą automatyczni automatyczniee tłumac tłumaczone, zone, jeśli zostan zostaną poprzedzone poprzedzone znaki znakiem em podkreślenia "_". Obsługa Obsług a języków narodowych narodowych została została wprow wprowadzona adzona w wersji wersji 12 AutoCADa. AutoCADa. Oznacza to, ż e programy wykorzystują ce ce ten chwyt nie będą si si ę wykonywały na wcześniejszych wersjach AutoCADa (dotyczy to zarówno wersji angielskiej, jak również wersji narodowych).
Wróćmy jednak do opisu elementu rysunkowego typu linia. Każdy element rysunku posiadaa swój numer ident posiad identyfikac yfikacyjny, yjny, za pomocą którego którego z poziomu AutoLISPu można uzyskać pozostałe dane charakteryzują ce ce ten obiekt. Numer identyfikacyjny elementu możemy uzyskać za pomocą funkcji AutoLISPu entlast. Funkcja ta zwraca nazw ę elementu, który jest ostatnim niewymazanym elementem głównym w rysunkowej bazie danych. Funkcja ta jest cz ęsto wykorzystywana w celu uzyskania nazwy nowego elementu, który właśnie został dodany z u życiem funkcji command. Element ten nie musi być widoczny na ekranie ani należeć do warstwy odblokowanej. Tak więc, jeśli element rysunkowy typu linia jest ostatnim elementem w bazie danych, wówczas wywołanie: Command: (entlast)↵ Command:
może zwrócić np.: . Numer identyfikacyjny elementu jest typu ENAME. Dostęp do danych o elemencie umożliwia nam funkcja entget, której parametrem parame trem jest wyżej opisany opisany numer identyfikac identyfikacyjny. yjny. Funkc Funkcja ja entget zwraca zwraca listę danych w formacie DXF (ang. Drawing eXchange Format). Przykładowo, dla naszej linii lista DXF może wyglą da dać następują cco: o:
21/ E{jbbojb ob mjtubdi
362
Command: (entget (entla (entlast)) st))↵ (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(1 (10 0 1. 1.0 0 1. 1.0 0 1. 1.0) 0)(1 (11 1 5. 5.0 0 10 10.0 .0 0. 0.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command:
Elementami listy DXF są podlisty podlisty zawierają ce ce wielkości charakteryzują ce ce dany obiekt. Pierwszym elementem jest podlista zawierają ca c a parę kropkową (–1 . ) ą t, określają cą .rodz rodzaj ajwszy dane da nejj elem liśtciepary DXF. . opko Drugim Dru gim ele mentem tem par pary y kro kropko wej jest jes wielkość charakteryzują ccaa dany dany elemen elementt rys rysunk unkowy owy.. W prz przypa ypadku dku kodu –1 jest jest to numer identyfikacyjny entycji, kod 0 oznacza nazwę entycji — "LINE", kod 8 oznacza nazwę warstwy, na której leży dany obiekt — "0", kod 10 oznacza współrzędne punktu począ tkoweg tkowego o lini linii, i, kod 11 oznacza współr współrzzędne punktu punktu końcow cowego ego lin linii, ii, kod 210 oznacza kierunek pogrubiania elementu.
Szczegółowa lista opisu kodów grup DXF znajduje si ę w dodatku E.
Lista DXF opisu Lista opisu elemen elementów tów skł składa ada się z dwó dwóch ch rod rodzaj zajów ów „po „podli dlist” st” — kro kropko pkowej wej zawierają cej c ej dwa elemen elementy ty oraz oraz zwykłe zwykłejj zaw zawier ieraj ają ccej ej dwa dwa lu lub b więcej eleme elementów. ntów. Przykładem listy kropkowej jest lista opisu warstwy elementu — (8 . "0"), przykładem listy zwykłej jest lista opisu współrz ędnych punktu począ tkowego tkowego linii — (10 1.0 1.0 1.0). Niektóre z kodów, jeśli nie występują na liście DXF, przyjmują wartości domyślne. Dotyczy to w szczególności numeru koloru elementu oraz nazwy rodzaju linii, jak ąą został narysowany dany element. Gdyby powy ższa linia została narysowana kolorem innym niż kolor przyporzą dkowany dkowany do warstwy, wówczas kod koloru b ędzie obecny na liście DXF. Zilustrujmy to poniższym przykładem: Command: _color↵ New entity entity col color or : : 1↵ Command: _line↵ From Fro m point: point: 1,1,1↵ To poi point: nt: 5,10,0↵ To poi point: nt:
↵
Command: _color↵ Ne New w en enti tity ty co colo lor r )>: : _bylayer↵ Command: (entget (entla (entlast)) st))↵ (62 2 . (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(6 1) 1)(1 (10 0 1. 1.0 0 1. 1.0 0 1. 1.0) 0)(1 (11 1 5. 5.0 0 10 10.0 .0 0. 0.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command:
W prz przykł ykładz adzie ie tym tym,, przed przed nar naryso ysowan waniem iem lin linii, ii, zmieni zmieniamy amy kol kolor or now nowo o rys rysowa owanyc nych h elementów eleme ntów na czerw czerwony. ony. Następnie rysujemy naszą lini linię, po czym wracamy do koloru przyporzą dkowan dkowanego ego do war warstw stwy. y. W opisie opisie elemen elementu tu pojawi pojawiaa się dodatkowa dodatkowa para kropkowa z kodem 62, określają cym cym numer koloru, jakim został narysowany element.
363
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Poniżej zamieszczono procedury uzyskiwania list DXF dla elementów typu CIRCLE, ARC i 3DFACE. Dodatkowo przyjęto założenie, ż e elementy rysowane są kolorem kolorem i typem linii przynależnym do warstwy. Command: _circle↵ 3P/2P/TTR/< 3P/2P /TTR/: point>: 2,2,0↵ Diameter/: 1↵ Command: (entget (entla (entlast)) st))↵ (( ((-1 -1 . En Enti tity ty na name me: : 60 6000 0000 0044 44>) >)(0 (0 . "C "CIR IRCL CLE" E")( )(8 8 . "0 "0") ")(1 (10 0 2. 2.0 0 2. 2.0 0 0. 0.0) 0)(4 (40 0 . 1. 1.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: Command: _arc↵ Center/: 10,1↵ Center/End/ Cente r/End/: _c↵ Center: 5,1↵ Angle/Lengt Angle /Length h of chord/: 5,5↵ Command: (entget (entla (entlast)) st))↵ (( ((-1 -1 . En Enti tity ty na name me: : 60 6000 0000 0066 66>) >)(0 (0 . "A "ARC RC") ")(8 (8 . "0 "0") ")(1 (10 0 5. 5.0 0 1. 1.0 0 0. 0.0) 0)(4 (40 0 . 5. 5.0) 0)(5 (50 0 . 0. 0.0) 0)(5 (51 1 . 1. 1.57 5708 08)( )(21 210 0 0. 0.0 0 0.0 0.0 1. 1.0) 0)) ) Command: Command: _3dface↵ First point: 1,1↵ Second Secon d point: 1,5↵ Third point: 5,5↵ Fourth point: 5,1↵ Fourth Third point:
↵
Command: (entget (entla (entlast)) st))↵ (( ((-1 -1 . En Enti tity ty na name me: : 60 6000 0000 0088 88>) >)(0 (0 . "3 "3DF DFAC ACE" E")( )(8 8 . "0 "0") ")(1 (10 0 1. 1.0 0 1. 1.0 0 1. 1.0) 0)(1 (11 1 1. 1.0 0 5. 5.0 0 0. 0.0) 0)(1 (12 2 5. 5.0 0 5. 5.0 0 0. 0.0) 0)(1 (13 3 5. 5.0 0 1. 1.0 0 0. 0.0) 0)(7 (70 0 . 0) 0)) ) Command: Command: _3dface↵ First point: 7,7↵ Second Secon d point: _i 7,8 7,8↵ Third point: _i 8,8 8,8↵ Fourth Fourt h point: 8,7↵ Third point:
↵
Command: (entget (entla (entlast)) st))↵ (( ((-1 -1 . En Enti tity ty na name me: : 60 6000 0000 00aa aa>) >)(0 (0 . "3 "3DF DFAC ACE" E")( )(8 8 . "0 "0") ")(1 (10 0 7. 7.0 0 7. 7.0 0 0. 0.0) 0)(1 (11 1 7. 7.0 0 8. 8.0 0 0. 0.0) 0)(1 (12 2 8. 8.0 0 8. 8.0 0 0. 0.0) 0)(1 (13 3 8. 8.0 0 7. 7.0 0 0. 0.0) 0)(7 (70 0 . 6) 6)) ) Command:
Przeglą d daj ają c listy DXF poszczególnych elementów zwróciłe ś mo że uwagę, ż e znaczenie kodów DXF nie jest jednoznaczne. Niektóre z nich np. 10, 11, 12, 13, 40 opisują różne, czasem nie mają ce c e ze sobą nic wspólnego cechy obiekt obiektu. u. Zależy to od typu opisywanego elementu.
21/ E{jbbojb ob mjtubdi
364
W przypadku okręgu kod 10 określa środek okręgu, kod 40 oznacza promień okr ęgu. W przypadku łuku kod 10 oznacza ś rodek łuku, kod 40 oznacza promień łuku, kod 50 oznacza orientację punktu począ tkowego tkowego łuku (w radianach), kod 51 oznacza orientację punktu końcowego łuku (w radianach). Łuk bie biegnie gnie zaw zawsze sze prz przeci eciwni wnie e do ruchu ruchu wsk wskazó azówek wek zegara zegara.. Wsp Współr ółrz zędne punktu począ ttkoweg kowego o łuku wyzna wyznacza czamy my w opa oparci rciu u o kod 50 50,, wsp współr ółrz zędne punktu końcowego łuku wyznaczamy w oparciu o kod 51. 51. Jest to ważne dla dowolnej metody definicji łuku.
W przypadku obiektu typu 3DFACE kod 10 oznacza współrzędne pierwszego wierzchołka, kod 11 drugiego, kod 12 trzeciego a kod 13 współrzędne czwartego wierzchołka (jeżeli wprowadzone zostały tylko trzy wierzchołki, ten jest równy trzeciemu). Kod 70 jest natomiast wska źnikiem oznaczają cym, cym, który bok płasz płaszczyz czyzny ny ma być niewidoczny: 1 — pierwszy, 2 — drugi, 4 — trzeci, 8 — czwarty. Warto ścią standardow standardową jest jest 0 — wszystkie boki są widoczne. Wygaszenie kilku boków da w wyniku sum ę odpowiadają cych cych im cyfr. Jak wspomniałe wspomniałem m wcześniej, informacje o eleme elementach ntach rysunkowych rysunkowych umies umieszczan zczanee są w bazie danych AutoCADa w kolejności ich rysowania. Dostęp do nich posiadamy dzięki standa standardo rdowym wym funkcj funkcjom om AutoLI AutoLISPu SPu (są to m. in in.. funk funkcj cjee entget i entsel). Jednak że funk funkcj cjee te udos udosttępniają jedyni jedyniee naz nazwy wy entycj entycjii głó główny wnych. ch. Obiekt Obiekty y typ typu u
ą IN INSER SERT Tą ce (b loki ki z atry atrybu buta tami mi)) or oraz azo atrybutach POLY POLYLI LINE NE (pol (polil ilin inie ie) ) posi posiad adaj aj subentycje zawieraj c(blo e informacje odpowiednio bloku oraz kolejnych wierzchołkach wielolinii. Bloki mogą nie nie posiadać zdefiniowanych atrybutów, o czym informuje kod 66. Przyjmuje on wartość 0, gdy blok ich nie posiada oraz 1 gdy posiada. Subentycje umieszczane są w bazie danych zaraz za entycjami głównymi. Maj ą c numer (nazwę) entycji głównej, można do nich dotrzeć za pomocą funkcji (entnext [ename]), która zwraca nazwę elementu umieszczonego w bazie po entycji o numerze ename. W ten sposób można krok po kroku odczyt odczytywa ywać nazwy subentycji bloku czy wielolinii. Dzi ęki tak takiem iemu u zorgan zorganizo izowan waniu iu rys rysunk unkowe owejj baz bazy y danych danych ilość zdefiniowanych zdefiniowanych atrybu atrybutów tów w bloku bloku ora orazz wie wierzc rzchoł hołków ków wie wielol lolini iniii może być dowolna. dowolna. Każdą grupę subentycji zamyka element typu SEQEND zawierają cy cy numer entycji głównej (wskazany przez kod –2), do której ona należy. Przedstawiony Przedstawion y powyżej spos sposób ób post postępow powani aniaa prz przeeśle ledz dzim imy y na el elem emen enci ciee ty typu pu POLYLINE, który składa się z jednego odcinka biegną cego cego od punktu o współrzędnych 1,1 do punktu o współr współrzzędnych 5,5. Command: _pline↵ From point: From point: 1,1↵ Arc/Close/Halfwidth/Length/Undo/Width/: 5,5↵ Arc/Close/Halfwidth/Length/Undo/Width/: Command:
↵
Skoro wielolinia została już narysowana, pokażę teraz, jak z poziomu linii komend przechodzić przez jej poszczególne wierzchołki.
365
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst
•
Opis entycji głównej uzyskujemy wykorzystuj ą c wcześniej poznaną konstrukcj konstrukcję. Command: (setq (setq x (entge (entget t (en (entla tlast) st))) ))↵ ((-1 . )(0 )(0 . "POLYL "POLYLINE INE")( ")(8 8 . "0 "0") ")(6 (66 6 . 1) 1)(1 (10 0 0. 0.0 0 0. 0.0 0 0. 0.0) 0)(7 (70 0 . 0) 0)(4 (40 0 . 0. 0.0) 0)(4 (41 1 . 0. 0.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)(7 (71 1 0) 0)(7 (72 2 0) 0)(7 (73 3 0) 0)(7 (74 4 0) 0)(7 (75 5 0) 0)) ) Command:
•
Przechodzimy do opisu pierwszej subentycji. Kod 66 o wartości 1 oznacza, ż e wielolinia posiada wierzchołki. Aby otrzyma ć listy DXF poszczególnych wierzchołków, posłużymy się znowu funkcją entget entget. Jej argument argumentem em nie będzie jednak funkc funkcja ja entlast, gdyż zwraca zwraca ona naz nazw wę elementu głównego, my zaś chcemy uzyskać nazwę elementu podrzędnego. Wykorzystamy tutaj wbudowaną funkcję AutoLISPu (entnext [ename]). Jeżeli funkcj fun kcjaa jes jestt wyw wywoły oływan wanaa bez argume argumentó ntów, w, to zwraca zwraca ona naz nazw wę pierwszego niewymazanego elementu z rysunkowej bazy danych. Jeżeli wyrażenie z entnext zawiera argument ename, to funkcja zwraca nazwę pierwszego niewymazanego elementu, który występuje w bazie danych po elemencie wskazywanym przez ten argument. Jeżeli nie ma już następnego elementu rysunkowego, to funkcja zwraca nil. Funkcja entnext zwraca zarówno elementy główne, jak również ich elementy podrzędne. Tak więc, mają c listę DXF entycji głównej podstawioną pod zmienną x, listę DXF następnej podentycji uzyskujemy następują cco: o: Command: (ass (assoc oc –1 x)↵ (–1 . ) ) Command: (cdr (cdr (ass (assoc oc –1 x)) x))↵ : 4,4↵ Diameter/: 2↵ Command: _change↵ Select Selec t objects: objects: 4,6↵ 1 fo foun und d Select Selec t objects: objects:
↵
Properties/ Prope rties/:
↵
Enter circle Enter circle rad radius ius: : 3↵ Command:
W powy powyższy szym m przykł przykładz adzie ie dok dokonu onujją c mo mody dyfik fikac acji ji okr okręgu kome komend ndą CHANGE/ CHANGE POINT mamy możliwość zmiany tylko jego promienia. Command: _line↵ From Fro m point: point: 2,2↵ To poi point: nt: 6,4↵ To poi point: nt:
↵
Command: _change↵ Select Selec t objects: objects: 2,2↵ 1 fo foun und d Select Selec t objects: objects:
↵
Properties/: ↵ No cha change ngeabl able e entity entity sel select ected ed Command:
W powy powyższy szym m przykł przykładz adzie ie próba próba mod modyfik yfikacj acjii lin linii ii komend komendą CHANGE/CHANGE POIN PO INT T kończy czy się komunikatem, że kome komend ndaa ta nie nie może zmi zmieni enić właściwości wybranego elementu.
379
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Dla obydwu entycji mamy mo żliwość zmiany takich parametrów jak: warstwa, kolor, poziom. Umożliwia to komend komenda a CHAN CHANGE/PR GE/PROPER OPERTIES TIES lub komend komenda a CHPROP.
Niedogodności te można usunąć stosują c modyfikację listy DXF elementu. AutoLISP posiada dwie funkcje biblioteczne: entmod i entupd, pozwalają ce ce na dokonanie zmian w li ście DXF elementu. Funkcje te zostaną obecnie obecnie szczegółowo omówione.
21/6/3/2/ Npezgjlbdkb 21/6/3/2/ Npe zgjlbdkb fmf fmfnfouv nfouv x xzlps{ztuboj xzlps{ztubojfn lps{ztubojfn gvoldkj fo founpe unpe Format funkcj funkcjii entmod jest następują ccy: y: (entmod elist ). Fun Funkcj kcjaa ope operuj rujee na arg arguumencie elist , który jest listą w postaci zwracanej przez funkcję entget, i aktualizuje informacje w bazie danych zwią zane zane z elementem, którego nazwa jest okre ślona w tej liście w grupie o kodzie –1. Tak więc podstawowy sposób uaktualniania bazy danych przez AutoLISP polega na wydobywaniu informacji o elemencie przy pomocy funkcji entget, na modyfikowaniu listy definiuj ą cych cych element danych (szczególnie przydatne są tutaj funkcje assoc oraz subst) oraz na aktualizowaniu informacji o elemencie w bazie danych za pomocą funkcji funkcji entmod. Poniższy przykład przykład pokaz pokazuje uje sposó sposób b wykorz wykorzystani ystaniaa funkc funkcji ji entmod do zmi zmiany any promienia okręgu oraz współrzędnych jego środka. Command: _circle↵ 3P/2P/TTR/< 3P/2P /TTR/: point>: 4,4↵ Diameter/: 2↵ Command: (setq (setq lista lista_dxf _dxf (entge (entget t (entla (entlast))) st)))↵ ((-1 ((1 . )(0 )(0 . "CIRCL "CIRCLE") E")(8 (8 . "0")(1 "0")(10 0 4. 4.0 0 4. 4.0 0 0. 0.0) 0)(4 (40 0 . 2. 2.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (setq (setq lis lista_ ta_dxf dxf (su (subst bst (cons (cons 40 3)( 3)(ass assoc oc 40 lista_dxf) lista lista_dxf) lista_dxf)) _dxf))↵ ((-1 ((1 . )(0 )(0 . "CIRCL "CIRCLE") E")(8 (8 . "0")(1 "0")(10 0 4. 4.0 0 4. 4.0 0 0. 0.0) 0)(4 (40 0 . 3) 3)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (set (setq q list lista_ a_dx dxf f (sub (subst st (lis (list t 10 8 4 0)(a 0)(ass ssoc oc 10 lista_ lis ta_dxf dxf) ) lis lista_ ta_dxf dxf)) ))↵ (( ((-1 -1 . )(0 (0 . "C "CIR IRCL CLE" E")( )(8 8 . "0 "0") ")(1 (10 0 8 4 0) 0)(4 (40 0 . 3) 3)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (entmod lista_ lista_dxf) dxf)↵ (( ((-1 -1 . )(0 (0 . "C "CIR IRCL CLE" E")( )(8 8 . "0 "0") ")(1 (10 0 8 4 0) 0)(4 (40 0 . 3) 3)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command:
Zwróć uwagę na sposoby tworzenia list do wymiany na li ście DXF. W przypadku promienia okręgu mamy do czynienia z par ą kropkową , tak więc do utworzenia listy wykorzystujemy funkcję cons. cons. W przypadku współrzędnych środka okręgu mamy ma my do czyn czynie ieni nia a ze zw zwyk ykłłą listą , tak więc do jej jej utwo utworz rzen enia ia możemy wykorzystać funkcję list list..
21/ E{jbbojb ob mjtubdi
37:
Możesz wymienić jednocześnie więcej niż jedną podlistę na liście DXF. Jakkolwiek może wydać się to na począ tku tku skomplikowane, dla porzą dku dku przedstawię sposób postępow powan ania ia — bazuj bazują c na wcześnie niejj utw utworz orzony onym m okręgu wrac wracam amy y do jego jego wymiarów począ tkowych tkowych (tj. promień = 2, współrzędne środka = 4,4). Command: (setq (setq lis lista_ ta_dxf dxf (subst (subst (co (cons ns 40 2)( 2)(ass assoc oc 40 lista_ lis ta_dxf dxf)(s )(subs ubst t (li (list st 10 4 4 0)( 0)(ass assoc oc 10 lis lista_ ta_dxf dxf) ) lista_dxf)))↵ ((-1 ((1 . )(0 )(0 . "CIRCL "CIRCLE") E")(8 (8 . "0")(1 "0")(10 0 4 4 0) 0)(4 (40 0 . 2) 2)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (entmod lista_dxf) lista_dxf)↵ ((-1 . )(0 )(0 . "CIRCL "CIRCLE") E")(8 (8 . "0")(1 "0")(10 0 4. 4.0 0 4. 4.0 0 0. 0.0) 0)(4 (40 0 . 2. 2.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command:
Funkcjaa do wym Funkcj wymian iany y elemen elementu tu na liście cie ma post postaać: (subst newitem newitem oldite olditem m list list ). W prz przypa ypadku dku modyfi modyfikac kacji ji prom promien ienia ia będzie dzie to np. np. (s (sub ubst st (c (con onss 40 2)(a 2)(ass ssoc oc 40 lista_dxf) lista_dxf )).. Szt Sztucz uczka ka polega polega na tym tym,, żeby pod arg argume ument nt list (w nas naszym zym przypa prz ypadku dku jest jest to zmi zmienn ennaa lista_dxf )),, podsta podstawi wić kolejną funkcję subst, w któr któreej wymieniamy następny element na liście. Tak więc zamiast listy (s (sub ubst st (c (con ons s 40 2)(a 2)(ass ssoc oc 40 li list sta_ a_dx dxf) f) lista_dxf) lista_dxf) podstawiamy (subst (cons 40 2) 2)(a (ass ssoc oc 40 li list sta_ a_dx dxf) f)(s (sub ubst st (l (lis ist t 10 4 4 0) 0)(a (ass ssoc oc 10 li list sta_ a_dx dxf) f) lista_dxf)). Zapis ten można rozwijać dalej dokładają c kolejne kody do wymiany, jest on jednak mało czytelny i nie zalecałbym go do stosowania w programach.
Poniższy przykład pokazuje sposób wykorzystania funkcji entmod do zmiany punktu począ tkowego tkowego oraz końcowego linii. Command: _line↵ From Fro m point: point: 1,1↵ To poi point: nt: 3,3↵ To poi point: nt:
↵
Command: (setq (setq lista lista_dxf _dxf (entge (entget t (entla (entlast))) st)))↵ (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(1 (10 0 1. 1.0 0 1. 1.0 0 0. 0.0) 0)(1 (11 1 3. 3.0 0 3. 3.0 0 0. 0.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (set (setq q list lista_ a_dx dxf f (sub (subst st (lis (list t 10 2 2 0)(a 0)(ass ssoc oc 10 lista_dxf) lista lista_dxf) lista_dxf)) _dxf))↵ (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(1 (10 0 2 2 0) 0)(1 (11 1 3. 3.0 0 3. 3.0 0 0. 0.0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (set (setq q list lista_ a_dx dxf f (sub (subst st (lis (list t 11 10 5 0)(a 0)(ass ssoc oc 11 lista_dxf) lista lista_dxf) lista_dxf)) _dxf))↵ (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(1 (10 0 2 2 0) 0)(1 (11 1 10 5 0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command: (entmod lista_ lista_dxf) dxf)↵ (( ((-1 -1 . )(0 (0 . "L "LIN INE" E")( )(8 8 . "0 "0") ")(1 (10 0 2 2 0) 0)(1 (11 1 10 5 0) 0)(2 (210 10 0. 0.0 0 0. 0.0 0 1. 1.0) 0)) ) Command:
381
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst Na koniec omawiania funkcji entmod przedstawię program do modyfikacji wybranych wielkości elementów typu linia, okrą g oraz tekst. Program ten jest przykładem budowy własnych funkcji do zmiany określonych cech na liście DXF. Założenia do programu są nast następują ce: ce: Program działa w pętli, o wyjściu z której decyduje u żytkownik. W poszczególnych cyklach pętli wykonywane są nast następują ce ce czynności: 1. pobr pobran anie ie zb zbio ioru ru ws wska kaza zań z wybr wybran anym ymii prze przezz użytkown ytkownika ika eleme elementami ntami rysunkowymi, 2. w przy przypa padk dku u gdy gdy zb zbió iórr wska wskaza zań je jest st pust pusty, y, wyświetle wietlenie nie odpow odpowiednie iedniego go komunikatu, 3. w przypadku przypadku gdy zbi zbiór ór wsk wskaza azań zawiera elementy (nie jest pusty): •
odczytanie nazwy zerowego elementu w zbiorze wskaza ń,
•
pobranie listy DXF opisują cej cej ten element,
•
pobranie typu elementu (kod 0) z listy DXF,
•
w zale zależności od typ typu u wyb wybran ranego ego elemen elementu tu wyk wykona onanie nie odp odpowi owiedn ednich ich funkcji:
•
•
w przypa przypadku dku elemen elementu tu typ typu u lin linia, ia, umożliwien liwienie ie zmiany zmiany punktu począ tkowego tkowego oraz końcowego linii,
•
w przypadku elementu typu okrą g, g, umożliwienie zmiany środka okręgu oraz jego promienia,
•
w przypadku elementu typu tekst, umożliwienie zmiany wartości łańcucha tekstowego, tekstowego, punktu wstawien wstawienia ia tekst tekstu u oraz wysokości tekstu,
•
w przypa przypadku dku elemen elementu tu inn innego ego typ typu u wyświetle wietlenie nie komuni komunikatu, katu, jakie elementy należy wskazać
sprawdzenie, czy użytkownik chce zakończyć pracę z programem.
Na samym końcu programu znajdują si si ę funkcje i wyra żenia, które zostaną wykonane wykonane automa automatyc tyczni zniee po zał załado adowan waniu iu pro progra gramu. mu. Jest Jest wśród nic nich h fun funkcj kcjaa RYSUJ_ELEca elementy typu linia, okrą g oraz tekst. MENTY, rysują ca A oto i program spełniaj ą cy cy powyższe założenia. ;*************************************************PROG_051 ;Modyfikacj ;Mody fikacja a elementow elementow z wykorzystani wykorzystaniem em funkcji funkcji ENTMOD ; ;------------------------------------------------;Funkcja ;Funk cja rysuja rysujaca ca wybrane wybrane elementy elementy ; (defun (defu n RYSUJ_ELEME RYSUJ_ELEMENTY NTY () (progn ;---------(command
21/ E{jbbojb ob mjtubdi "_zoom" "_zoom " "_wind "_window" ow" "0, "0,0" 0" "12,9" "12,9" "_color" "_colo r" "1" "_line "_l ine" " "1,1" "1,1" "1,2" "1,2" "2,2" "2,2" "2,1" "2,1" "_c" "_c" "_color" "_colo r" "5" "_circ "_c ircle" le" "5,5" "5,5" "2" "_color" "_colo r" "_bylayer" "_bylayer" "_ "_te text xt" " "_ "_j" j" "_ "_c" c" "5 "5,5 ,5" " "0 "0.5 .5" " "0 "0" " "T "Tes est" t" );command ;---------(princ) ;---------);progn );RYSUJ_ELEMENTY ; ;------------------------------------------------;Funkcja ;Funk cja zmieni zmieniajaca ajaca wybrane cechy ;obiek ;ob iektu tu typu typu LINE LINE ; (defun (de fun CHA CHANGE NGE_LI _LINE NE ( / nazwa nazwa pkt_po pkt_pocz cz pkt_ko pkt_konc nc pkt_pocz_ne pkt_po cz_new w pkt_konc_ne pkt_konc_new w ) (progn ;---------;pobranie ;pobra nie odpowiednic odpowiednich h danych danych (setq nazwa naz wa (cdr (cdr (assoc (assoc -1 lista_ lista_dxf dxf)) )) pkt_po pkt _pocz cz (cdr (cdr (assoc (assoc 10 lista_ lista_dxf dxf)) )) pkt_konc pkt_ko nc (cdr (cdr (assoc (assoc 11 lista_ lista_dxf dxf)) )) );setq ;---------;podswietlen ;podsw ietlenie ie wybranej wybranej linii (redra (re draw w nazwa nazwa 3) ;---------;pobranie ;pobra nie wspolrzedny wspolrzednych ch punktu punktu poczatkoweg poczatkowego o (setq pkt_pocz_new (getpoint (getpo int pkt_pocz pkt_pocz (strcat "\nNow "\n Nowy y punkt punkt poczat poczatkow kowy y linii linii ">: : " );strcat );getpoint );setq (if (= pkt_po pkt_pocz_ cz_new new nil nil) ) (setq pkt_pocz_ne pkt_pocz_new w pkt_pocz) pkt_pocz) );if ;---------;pobranie ;pobra nie wspolrzedny wspolrzednych ch punktu punktu koncowego koncowego (setq pkt_konc_new
382
383
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (getpoint pkt_konc (getpoint pkt_konc (strcat "\nNow "\n Nowy y punkt punkt koncow koncowy y linii linii ">: : " );strcat );getpoint );setq (if (= pkt_ko pkt_konc_ nc_new new nil nil) ) (setq pkt_konc_ne pkt_konc_new w pkt_konc) pkt_konc) );if ;---------;modyfikacja ;modyf ikacja linii (setq lista_dxf lista_ dxf (subst (cons 10 pkt_pocz_ne pkt_pocz_new) w) (assoc (as soc 10 lista_ lista_dxf dxf) ) lista_dxf );subst lista_dxf lista_ dxf (subst (cons 11 pkt_konc_ne pkt_konc_new) w) (assoc (as soc 11 lista_ lista_dxf dxf) ) lista_dxf );subst );setq (entmod (entmo d lista_dxf) lista_dxf) (redraw) ;---------(princ) ;---------);progn );CHANGE_LINE ; ;------------------------------------------------;Funkcja ;Funk cja zmieni zmieniajaca ajaca wybrane cechy ;obiek ;ob iektu tu typu typu CIRCLE CIRCLE ; (defun (de fun CHA CHANGE NGE_CI _CIRCL RCLE E ( / nazwa nazwa srodek srodek pro promie mien n srodek_new srodek _new promien_new promien_new ) (progn ;---------;pobranie ;pobra nie odpowiednic odpowiednich h danych danych (setq nazwa naz wa (cdr (cdr (assoc (assoc -1 lista_ lista_dxf dxf)) )) srodek sro dek (cd (cdr r (assoc (assoc 10 lista_ lista_dxf dxf)) )) promie pro mien n (cdr (cdr (assoc (assoc 40 lista_ lista_dxf dxf)) )) );setq ;---------;podswietlen ;podsw ietlenie ie wybranej wybranej linii (redra (re draw w nazwa nazwa 3)
21/ E{jbbojb ob mjtubdi ;---------;pobranie ;pobra nie nowych nowych wspolrzedny wspolrzednych ch srodka (setq srodek_new (getpoint (getpo int srodek (strcat "\nNow "\n Nowy y srodek srodek okr okregu egu ">: : " );strcat );getpoint );setq (if (= srodek srodek_ne _new w nil) nil) (setq srodek_new srodek_new srodek) srodek) );if ;---------;pobranie ;pobra nie nowego nowego promienia promienia (i (ini nitg tget et (+ 2 4) 4)) ) (setq promien_new (getreal (strcat "\nNow "\n Nowy y promie promien n okregu okregu ">: : " );strcat );getreal );setq (if (= promie promien_n n_new ew nil) nil) (setq promien_new promien_new promien) promien) );if ;---------;modyfikacja ;modyf ikacja okregu (setq lista_dxf lista_ dxf (subst (cons (co ns 10 srodek srodek_ne _new) w) (assoc (as soc 10 lista_ lista_dxf dxf) ) lista_dxf );subst lista_dxf lista_ dxf (subst (co (cons ns 40 pro mien_n n_new) ew) (assoc (as soc 40promie lista_ lis ta_dxf dxf) ) lista_dxf );subst );setq (entmod (entmo d lista_dxf) lista_dxf) (redraw) ;---------(princ) ;---------);progn
384
385
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst );CHANGE_CIRCLE ; ;------------------------------------------------;Funkcja ;Funk cja zmieni zmieniajaca ajaca wybrane cechy ;obiek ;ob iektu tu typu typu TEXT TEXT ; (defun (de fun CHA CHANGE NGE_TE _TEXT XT ( / nazwa nazwa tekst tekst pkt_ws pkt_wstaw taw wysoko wysokosc sc tekst_new tekst_ new pkt_wstaw_ne pkt_wstaw_new w wysokosc_new wysokosc_new ) (progn ;---------;pobranie ;pobra nie odpowiednic odpowiednich h danych danych (setq nazwa naz wa (cdr (cdr (assoc (assoc -1 lista_ lista_dxf dxf)) )) tekst tek st (cdr (cdr (assoc (assoc 1 lista_ lista_dxf dxf)) )) pkt_ws pkt _wstaw taw (cdr (cdr (assoc (assoc 10 lista_ lista_dxf dxf)) )) wysoko wys okosc sc (cdr (cdr (assoc (assoc 40 lista_ lista_dxf dxf)) )) );setq ;---------;podswietlen ;podsw ietlenie ie wybranego wybranego tekst tekstu u (redra (re draw w nazwa nazwa 3) ;---------;pobranie ;pobra nie nowego nowego lancucha lancucha tekstu tekstu (setq tekst_new (getstring (getst ring T (strcat "\nNow "\n Nowy y tekst tekst ">: : " );strcat );getstring );setq (i (if f (= te teks kst_ t_ne new w "" "") ) (setq tekst_new tekst) );if ;---------;pobra ;po branie nie nowego nowego pun punktu ktu wstawi wstawieni enia a tekstu tekstu (setq pkt_wstaw_new (getpoint (getpo int pkt_wstaw pkt_wstaw (strcat "\nNow "\n Nowy y punkt punkt wstawi wstawieni enia a tekstu tekstu ">: : " );strcat );getpoint );setq (if (= pkt_ws pkt_wstaw taw_ne _new w nil) nil) (setq pkt_wstaw_n pkt_wstaw_new ew pkt_wstaw) pkt_wstaw)
21/ E{jbbojb ob mjtubdi );if ;---------;pobranie ;pobra nie nowej wysokosci tekstu (i (ini nitg tget et (+ 2 4) 4)) ) (setq wysokosc_new (getreal (strcat "\nNow "\n Nowa a wysoko wysokosc sc tekstu tekstu ">: : " );strcat );getreal );setq (if (= wysoko wysokosc_ sc_new new nil nil) ) (setq wysokosc_ne wysokosc_new w wysokosc) wysokosc) );if ;---------;modyfikacja ;modyf ikacja tekstu (setq lista_dxf lista_ dxf (subst (cons (co ns 1 tekst_ tekst_new new) ) (assoc (as soc 1 lista_ lista_dxf dxf) ) lista_dxf );subst lista_dxf lista_ dxf (subst (cons 10 pkt_wstaw_n pkt_wstaw_new) ew) (assoc (as soc 10 lista_ lista_dxf dxf) ) lista_dxf );subst lista_dxf lista_ dxf (subst (cons 40 wysokosc_ne wysokosc_new) w) (assoc (as soc 40 lista_ lista_dxf dxf) ) lista_dxf );subst );setq (entmod (entmo d lista_dxf) lista_dxf) (redraw) ;---------(princ) ;---------);progn );CHANGE_TEXT ;
386
;------------------------------------------------;Glowna ;Glow na funkcja funkcja programu programu ; (defun (de fun CHA CHANGE NGE_EL _ELEME EMENT NT ( / jeszcz jeszcze e zbior zbior elemen element t lista_ lista_dxf dxf kod_0 kod _0 odp ) (progn ;---------(setq (se tq jeszcz jeszcze e T) (while jeszcze jeszcze
387
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst (progn ;---------;pobra ;po branie nie zbioru zbioru z elemen elementam tami i ; (setq (se tq zbior zbior (ssget (ssget)) )) ;---------;modyfikacj ;modyf ikacja a elementu elementu ; (if zbior zbior (progn (setq elemen ele ment t (ssnam (ssname e zbior zbior 0) lista_dxf lista _dxf (entget (entget element) element) kod_0 kod _0 (cdr (cdr (assoc (assoc 0 lista_ lista_dxf dxf)) )) );setq (cond ((= kod_0 kod_0 "LINE" "LINE") ) (CHANGE_LINE) ) ((= kod_0 kod_0 "CIRCL "CIRCLE") E") (CHANGE_CIRCLE) ) ((= kod_0 kod_0 "TEXT" "TEXT") ) (CHANGE_TEXT) ) (T (princ "\nNal "\n Nalezy ezy wybrac wybrac linie, linie, okr okrag ag lub tek tekst. st." " );princ ) );cond );progn (p (pro rogn gn ;e ;els lse e - ni nie e wy wybr bran ano o za zadn dneg ego o el elem emen entu tu (princ (pr inc "\nPus "\nPusty ty zbior zbior wskaza wskazan." n.") ) );progn );if ;---------;sprawdzeni ;spraw dzenie e czy konczy konczymy my ; (i (ini nitg tget et 1 "T t N n" n") ) (setq (se tq odp (getkw (getkword ord "\nCzy "\nCzy konczy konczymy my [T/N]: [T/N]: ")) (i (if f (o (or r (= od odp p "T "T") ")(= (= od odp p "t "t") ")) ) (progn (setq (se tq jeszcz jeszcze e nil) nil) );progn );if ;---------);progn );while );whil e jeszcze jeszcze ;---------(princ) ;---------);progn );CHANGE_ELEMENT ;
21/ E{jbbojb ob mjtubdi
388
;------------------------------------------------;Ten ;Te n fragme fragment nt progra programu mu zostan zostanie ie wykona wykonany ny ;automatycz ;auto matycznie nie po jego zaladowaniu zaladowaniu ; (setva (se tvar r "cmdec "cmdecho" ho" 0) ;wylac ;wylaczen zenie ie echa komend komend (setva (se tvar r "ucsic "ucsicon" on" 0) ;wylac ;wylaczen zenie ie markera markera ukladu ukladu wspolrzednych (setva (se tvar r "blipm "blipmode ode" " 0) ;wylac ;wylaczen zenie ie znaczn znaczniko ikow w punkto punktow w ; (RYSUJ_ELEMENTY) (CHANGE_ELEMENT) (princ) ;------------------------------------------------;*************************************************KONIEC
Ponieważ najbardzi najbardziej ej rozbudowana rozbudowana jest funkcj funkcjaa do modyfi modyfikacji kacji tekstu (zmieniamy (zmieniamy łańcuch, punkt oraz liczbę rzeczywistą ), ), sposób budowy tego typu funkcji objaśnię na jej przykładzie. blok bloku u tym tym wyko wykorz rzys ystu tujją c list listę DXF DXF elemen elementu tu utw utworz orzon oną w funk funkcj cjii CHANGE_ELEMENT, pobier pobieramy amy nazwę elementu oraz wielkości podlegają ce ce modyfikacji.
W
Wykorzystują c
fu funk nkcj cję AutoLISPu redraw, podświe wietla tlamy my wybran wybrany y tekst. tekst. O tym, jaki element ma by ć przerysowany, decyduje pierwszy argument funkcji nazwa ś (w przypadkufunkcji jest to (aby zmienna ). O pod wietleniu elementu decydujenaszym drugi argument nastą piło piło pod wybranego elementu, świetlenie argument ten musi być równy 3). bloku tym umo żliwiamy użytkownikowi zmianę ła ńcucha tekstu. Argument T użyty yty w funk funkcj cjii getstring, poz pozwal walaa na wpr wprowa owadze dzenie nie tekstu tekstu roz rozdzi dzielo eloneg nego o spacja spa cjami. mi. W nawias nawiasach ach ostryc ostrych h pod podana ana jest jest war warto tość domyślna — pop poprze rzedni dni łańcuch tekstowy.
W
przypadku naciśnięcia samego klawisza ENTER użytkownik wybiera wartość domyślną tekstu. tekstu.
W
Naciśnięcie samego ENTER w odpowiedzi na getstring na getstring zwraca zwraca "".
bloku tym umożliwiamy użytkown ytkownikowi ikowi zmianę punktu wstawienia tekstu. Argument pkt_wstaw użyty w funkcji getpoint powoduje rysowanie ruchomej
W
linii pomocnicze pomocniczej, j, cią gn gną cej c ej się od tego tego pun punktu ktu do pun punktu ktu odp odpowi owiada adajją cego cego aktualnej pozycji krzy ża nitkowego. W nawiasach ostrych podana jest warto ść domyślna — poprzednie współrz ędne punktu wstawienia. Zauważ użycie funkcji rtos do pobran pobrania ia kolejn kolejnych ych współrzędny dnych ch pun punktu ktu — poz pozbyw bywamy amy si ę w ten sposób nawiasów okrą głych. głych.
389
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst przypadku naciśnięcia samego klawisza ENTER, użytkownik wybiera wartość domyślną — — poprzedni punkt wstawienia tekstu.
W
Naciśnięcie samego ENTER w odpowiedzi na getpoint na getpoint zwraca zwraca nil .
W
bloku tym umożliwiamy użytkownikowi zmianę wysokości tekstu. Za pomocą funkcji initget nakładamy warunki począ tkowe tkowe dla funkcji getreal — użytkownik nie może podać wartości zerowej zerowej ani ujemnej, dopuszcz dopuszczone one jest jednak naciśnięcie samego ENTER w celu akceptacji wartości domyślnej. W nawiasach ostrych podana jest wartość domyślna — poprzednia wysokość tekstu. przypa przypadku dku nac naciiśnięcia samego samego kla klawis wisza za ENT ENTER ER użytkown ytkownik ik zaakc zaakceptuje eptuje poprzednią wysoko wysokość tekstu.
W
W
bloku tym dokonujemy zmian na liście DXF opisują cej cej wybrany tekst.
Modyfikujemy
listę DXF opisują cą wybrany wybrany tekst.
21/6/3/3/ Npezgjlbdkb xzlps{ztubojfn Npezgjlbdkb fmfnfouv { xzlps{ztubojfn xzlps{ztub gvoldkj fo founpe unpe j fouv fouvqe qe Przedstawiona powyżdanych ej funkcja y do modyfikowania głównych entmod słu w rysunkowej bazie AutoCADa. Wżczasie modyfikowaniaelementów przy u życiu funkcj funkcjii entmod wierzchołka Polilinii lub atrybutu Bloku, wygl ą d całego elementu złożonego na ekr ekrani aniee nie jes jestt uak uaktua tualni lniany any.. Prz Przykł ykłado adowo, wo, gdyby gdyby nale należało zmodyf zmodyfikowa ikować 100 wierzchołków skomplikowanej polilinii, to każdorazowe przeliczanie i wyświetlanie jej zmieniają cego c ego się wraz wraz ze zmian zmianą każdego wierzchołka wierzchołka wyglą du, du, przebi przebiegało egałoby by w niedopuszcz niedop uszczalnie alnie wolny wolnym m tempie tempie.. Aktua Aktualizacj lizację wyglą du du modyfik modyfikowane owanejj polilinii polilinii lub bloku można więc wymusić dopiero przez użycie funkcji entupd. Funkcja ta ma postać: (entupd ename)
Argumentem Argume ntem funkcji jest nazwa dowolneg dowolnego o jedne jednego go eleme elementu ntu składowego Polilinii lub Bloku — . Nie musi to by ć nazwa elementu głównego — entupd odnajdzie nagłówek. Chociaż funkcja entupd jest przeznaczona dla Polilinii i Bloków z atrybu atrybutam tami, i, to w prakty praktyce ce może być ona wywoływana wywoływana dla dowol dowolnego nego eleme elementu. ntu. W każdym przypadku powoduje ona regenerację elementu na ekranie wraz ze wszystkimi elementami podrzędnymi. Algorytm postępowania przy przetwarzaniu elementów zło żonych przedstawia się wi ęc następują cco: o: while element_pod element_podrz rzędny { — modyfi modyfikac kacja ja elementu elementu podrz podrzędnego, — za zapi pisa sani nie e zm zmia ian n w ba bazi zie e da dany nych ch za po pomo moc cą funkcji entmod , } regene reg enerac racja ja elemen elementu tu za pomoc pomocą funkcji entupd .
21/ E{jbbojb ob mjtubdi
38:
Poniżej przeds przedstaw tawion iony y zos zostan tanie ie pro progra gram m do mod modyfik yfikacj acjii poł poło ożenia wierzchołkó wierzchołków w wielolinii. Założenia do programu są nast następują ce: ce: Program działa w pętli, o wyjściu z której decyduje u żytkownik. W poszczególnych cyklach pętli wykonywane są nast następują ce ce czynności: 1. pobranie pobranie ele elementu mentu za po pomoc mocą funkcji funkcji entsel, 2. w przypadku przypadku g gdy dy nie ws wskazan kazano o ż adnego elementu, wyświetlenie odpowiedniego komunikatu, 3. w przypadku przypadku gd gdy y wskaz wskazano ano ele element: ment: •
pobranie listy DXF opisują cej cej ten element,
•
pobranie typu elementu (kod 0) z listy DXF,
•
w zale zależności od typ typu u wyb wybran ranego ego elemen elementu tu wyk wykona onanie nie odp odpowi owiedn ednich ich funkcji: •
w przypadku przypadku eleme elementu ntu typu wielo wielolinia, linia,pod podświetle wietlenie nie wybra wybranego nego elem elemen entu tu,, pobr pobran anie ie i spra sprawd wdze zeni niee wekt wektor oraa prze przesu suni nięcia wierzchołkó wierz chołków w oraz gdy wektor przesunięcia nie jest zerowy — przesunięcie wszystkich wierzchołków o podany wektor,
•
w przypadku elementu innego typu wyświetlenie komunikatu, jaki element należy wskazać
•
sprawdzenie, czy użytkownik chce zakończyć pracę z programem. Na samym końcu programu znajdują si si ę funkcje i wyra żenia, które zostaną wykonane wykonane automa automatyc tyczni zniee po zał załado adowan waniu iu pro progra gramu. mu. Jest Jest wśród nic nich h fun funkcj kcjaa RYSUJ_ELEMENTY, rysują ca ca elementy typu wielolinia, linia oraz okr ą g g.. A oto i program spełniaj ą cy cy powyższe założenia. ;*************************************************PROG_052 ;Modyfikacj ;Mody fikacja a elementow elementow z wykorzystani wykorzystaniem em ;funkc ;fu nkcji ji ENTMOD ENTMOD i ENTUPD ENTUPD. . ; ;------------------------------------------------;Funkcja ;Funk cja rysuja rysujaca ca wybrane wybrane elementy elementy ; (defun (defu n RYSUJ_ELEME RYSUJ_ELEMENTY NTY () (progn ;---------(command "_zoom "_z oom" " "_wind "_window" ow" "0, "0,0" 0" "12,9" "12,9" "_color" "_colo r" "1" "_line "_l ine" " "3,3" "3,3" "3,4" "3,4" "4,4" "4,4" "4,3" "4,3" "_c" "_c" "_color" "_colo r" "5" "_circ "_c ircle" le" "5,5" "5,5" "2" "_color" "_colo r" "_bylayer" "_bylayer" "_plin "_p line" e" "2,2" "2,2" "2,7" "2,7" "10,7" "10,7" "10,2" "10,2" "_c "_c" " );command ;---------(princ)
391
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst ;---------);progn );RYSUJ_ELEMENTY ; ;------------------------------------------------;Funkc ;Fu nkcja ja przesu przesuwaj wajaca aca wie wielol lolini inie e o zadany zadany wek wektor tor ; (defun (de fun CHA CHANGE NGE_PO _POLYL LYLINE INE ( / nazwa nazwa wektor wektor jes jeszcz zcze_2 e_2 w) (progn ;---------;podswietlen ;podsw ietlenie ie wielolinii wielolinii (setq (se tq nazwa nazwa (cdr (cdr (assoc (assoc -1 lista_ lista_dxf dxf))) ))) (redra (re draw w nazwa nazwa 3) ;---------;pobranie ;pobra nie wektora wektora przesunieci przesuniecia a wierzcholko wierzcholkow w (setq wektor (getpoint (getpoint (strcat "\nPod "\n Podaj aj wektor wektor przesu przesunie niecia cia " "wierzcholko "wierz cholkow w [X,Y,Z]: [X,Y,Z]: " );strcat );getpoint );setq ;---------;sprawdzenie ;spraw dzenie wektora wektora (i (if f (= we wekt ktor or ni nil) l)
(progn (s (set etq q we wekt ktor or '( '(0 0 0 0) 0)) ) );progn (p (pro rogn gn ;e ;els lse e (i (if f (= (c (cad addr dr we wekt ktor or) ) ni nil) l) (progn (setq wektor wek tor (li (list st (car (car wektor wektor) ) (cadr (cadr wektor wektor) ) 0) );setq );progn );if );progn );if ;---------;g ;gdy dy we wekt ktor or /= (0 0 0) ;modyfikacja ;modyf ikacja wielolinii wielolinii (i (if f (n (not ot (e (equ qual al we wekt ktor or '( '(0 0 0 0) 0))) )) (progn (setq jeszcz (setq jeszcze_2 e_2 T) ; (while jeszcze_2 jeszcze_2 (progn (setq lista_dxf lista _dxf (entget (entget (entnext (cdr (cd r (assoc (assoc -1 lista_ lista_dxf dxf)) )) );entnext );entget
21/ E{jbbojb ob mjtubdi
392
);setq (if (/= (cd (cdr r (assoc (assoc 0 lista_ lista_dx dxf)) f)) "SEQEN "SEQEND") D")
(progn (setq w (c (cdr dr (a (ass ssoc oc 10 li list sta_ a_dx dxf) f)) ) w (trans w 0 1) w (l (lis ist t (+ (n (nth th 0 w) w)(n (nth th 0 we wekt ktor or)) )) (+ (n (nth th 1 w) w)(n (nth th 1 we wekt ktor or)) )) (+ (n (nth th 2 w) w)(n (nth th 2 we wekt ktor or)) )) );list w (trans w 1 0) );setq (setq lista_dxf (subst (c (con ons s 10 w) (assoc (as soc 10 lista_ lista_dxf dxf) ) lista_dxf );subst );setq (entmod (entmo d lista_dxf) lista_dxf) );progn (p (pro rogn gn ;e ;els lse e (setq (se tq jeszcz jeszcze_2 e_2 nil) nil) );progn );if );progn );while );whil e jeszcze_2 jeszcze_2 ; (entup (en tupd d (cdr (cdr (assoc (assoc -1 lista_ lista_dxf dxf))) ))) (command (comma nd "_regen") "_regen") );progn );if ;---------);progn );CHANGE_POLYLINE ; ;------------------------------------------------;Glowna ;Glow na funkcja funkcja programu programu ; (defun (de fun CHA CHANGE NGE_EL _ELEME EMENT NT ( / jeszcz jeszcze_1 e_1 ele elemen ment t lista_ lista_dxf dxf kod kod_0 _0 odp ) (progn ;---------(setq (se tq jeszcz jeszcze_1 e_1 T) (while jeszcze_1 jeszcze_1 (progn ;---------;pobranie ;pobra nie elementu elementu ; (setq elemen ele ment t (car (car (entse (entsel l "\nWsk "\nWskaz az wielol wielolini inie: e: "))
393
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst );setq ;---------;modyfikacj ;modyf ikacja a elementu elementu ; (if element element (progn (setq lista_dxf lista _dxf (entget (entget element) element) kod_0 kod _0 (cdr (cdr (assoc (assoc 0 lista_ lista_dxf dxf)) )) );setq (cond ((= kod_0 kod_0 "POLYL "POLYLINE INE") ") (CHANGE_POLYLINE) ) (T (princ "\nNalezy "\nNal ezy wybrac wybrac wielolinie. wielolinie." " );princ ) );cond );progn (p (pro rogn gn ;e ;els lse e - ni nie e wy wybr bran ano o za zadn dneg ego o el elem emen entu tu (princ (prin c "\nNie wskazano zadnego elementu.") elementu.") );progn );if ;---------;sprawdzenie ;sprawdzeni e czy konczy konczymy my ; (i (ini nitg tget et 1 "T t N n" n") ) (setq (se tq odp (getkw (getkword ord "\nCzy "\nCzy konczy konczymy my [T/N]: [T/N]: ")) (i (if f (o (or r (= od odp p "T "T") ")(= (= od odp p "t "t") ")) ) (progn (setq (se tq jeszcz jeszcze_1 e_1 nil) nil) );progn );if ;---------);progn );while );whil e jeszcze_1 jeszcze_1 ;---------(princ) ;---------);progn );CHANGE_ELEMENT ; ;------------------------------------------------;Ten ;Te n fragme fragment nt progra programu mu zostan zostanie ie wykona wykonany ny ;automatycz ;auto matycznie nie po jego zaladowaniu zaladowaniu ; (setva (se tvar r "cmdec "cmdecho" ho" 0) ;wylac ;wylaczen zenie ie echa komend komend (setva (se tvar r "ucsic "ucsicon" on" 0) ;wylac ;wylaczen zenie ie markera markera ukladu ukladu wspolrzednych (setva (se tvar r "blipm "blipmode ode" " 0) ;wylac ;wylaczen zenie ie znaczn znaczniko ikow w punkto punktow w ; (RYSUJ_ELEMENTY) (CHANGE_ELEMENT)
21/ E{jbbojb ob mjtubdi
394
(princ) ;------------------------------------------------;*************************************************KONIEC
Omówmy teraz wyróżnione linie i bloki programu. Wykorzystują c
fun funkcj kcję getpoint, pob pobier ieramy amy wek wektor tor przesu przesuni nięcia wszystkich wszystkich
wierzchołków wielolinii. bloku bloku tym dok dokonu onujem jemy y spr sprawd awdzen zenia ia wek wektor toraa prz przesu esuni nięcia wierzchołków wierzchołków.. Jeśli wekt wektor or jest jest równ równy y nil (naciśnięcie cie same samego go EN ENTER TER w odpo odpowi wied edzi zi na ), ustawiamy jego warto na (0 0 0). Je li wektor nie jest równy getpoint ść ś nil, sprawdzamy dodatkowo, czy wprowadzono wartość współrzędnej Z. Jeśli nie, ustawiamy ją na na 0.
W
czy jakakolwiek ze współrz ędnych wektora przesunięcia jest różna od 0. Jeżeli tak, rozpoczynamy przetwarzanie wcze śniej wskazanej wielolinii.
Sprawdzamy, Wchodzą c
w pętlę while, rozpoczynamy przetwarzanie kolejnych wierzchołków
wielolinii. Pobieramy
listę DXF opisują cą kolejny kolejny element podrz ędny wielolinii.
blo bloku ku tym sprawd sprawdzam zamy, y, czy eleme element nt pod podrz rzędny wie wielol lolini iniii jest jest opi opisem sem jej wierzchołka wierz chołka.. Jeżeli tak, tak, mod modyfik yfikuje ujemy my jego jego wsp współr ółrzzędne, uaktua uaktualniamy lniamy jego listę DXF po czym wykorzystują c funkcję entmod zapisujemy zmiany w bazie
W
danych. Jeśli element podrzędny nie jest opisem kolejnego wierzchołka wielolinii (znaczy to, ż e zostały już przetworzone wszystkie wierzchołki), ustawiamy wartość zmiennej jeszcze_2 na nil, umożliwiają c tym samym wyjście z pętli while funkcji CHANGE_POLYLINE. Wykorzystują c
funkcję entupd, uaktualniamy wyglą d wielolinii na ekranie.
rys rysune unek. k. Jest Jest to kon koniec ieczne zne,, gdyż przesuwają ca c a się wielolinia zostawia ślady swej obecności na innych obiektach.
Regener Regeneruje ujemy my
Rozdział ten zapoznał Cię z najbardziej używanym typem danych w AutoLISPie — listą . Zestaw programów i przykładów omówiony w tym rozdziale powinien wystarczy ć do tworzenia i modyfikacji dowolnie skomplikowanej listy. Szczególn ą uwag uwagę powinieneś poświęcić na dokład dokładne ne zap zapozn oznani aniee się z li list stą DXF opisu opisujją cą rysunkow ą bazę danych danyc h AutoC AutoCADa. ADa. Jej zrozumienie zrozumienie pozwoli na efektywne efektywne wykorzystanie wykorzystanie biblioteki biblioteki standardowych funkcji do obsługi list oraz rysunkowej bazy danych. W następnym rozdziale omówimy działania na łańcuchach.
395
BvupMJTQ — qsbluzd{oz qsbluzd{oz lvst
View more...
Comments