10 Dodatek E Ćwiczenia





Dodatek E

^

Ćwiczenia

Jedne z najbardziej użytecznych sposobów rozszerzania możliwości
AutoCAD-a daje język AutoLISP. AutoLISPjest przystosowaną do potrzeb
AutoCAD-a implementacją języka LISP. Dzięki pisanym w języku AutoLISP
programom, do AutoCAD-a mogą być nawet włączane nowe polecenia. Użyt-
kownik dysponuje prawie takimi samymi możliwościami modyfikowania
AutoCAD-a, jak jego twórcy.

W celu wprowadzenia do zrozumienia podstawowych zasad działania
AutoLISP-u, w rozdziale tym zaprezentowana zostanie procedura przygo-
towania oraz włączenia do AutoCAD-a nowego polecenia użytkowego. Po-
winno to pomóc w wyjaśnieniu, na czym polega praca AutoLISP-u i jak można
wykorzystać praktycznie jego możliwości dla własnych potrzeb. Definiowane tu
polecenie związane jest wprawdzie z potrzebami dotyczącymi projektowania
i urządzania terenów zieleni, ale przedstawione tu podejście do programowania
jest odpowiednie do każdego obszaru zastosowań.

Zakładamy tutaj, że czytelnik jest dość dobrze zaznajomiony z programem
AutoCAD; rozumie się przez to znajomość poleceń AutoCAD-a i ogólnych za-
sad posługiwania się nim. Zakłada się także, że użytkownik ma dostęp do
edytora tekstu, który nadaje się do tworzenia plików tekstowych w kodzie
ASCII. Pokazany zostanie obecnie proces pisania programu; zalecamy równoleg-
łe wprowadzanie przedstawionych wyrażeń do pliku za pomocą edytora tekstu.

W zaprezentowanym przykładzie będą wykorzystane liczne funkcje
AutoLISP-u. Wyczerpujące informacje o każdej z nich można znaleźć
w rozdziale 4 niniejszego podręcznika.

Określenie zamierzonego celu

Naszym celem jest opracowanie nowego polecenia AutoCAD-a, które pozwoli
na narysowanie ścieżki ogrodowej, utwardzonej okrągłymi betonowymi pły-
tami. Zakłada się, że wydanie nowego polecenia będzie inicjowało następu-
jący dialog:

Polecenie: droga

Punkt poczqtkowy drogi: punkt

Punkt końcowy drogi: punkt

Połowa szerokości drogi; liczba

Promień płyty: liczba

Odległości między płytami: liczba

Punkt początkowy {punkt końcowy określają oś symetrii drogi. Następnie po-

Określenie zamierzonego celu 247

Komunikaty błędów

Auto7

o

^

o

ości drogi i promień okrągłych płyt, którymi będzie
^ormacją jest określenie odległości między sąsied-
ie tym zdecydowano się na używanie wymiaru
iści drogi, a nie całą szerokość. Ułatwia to wi-
adzanego wymiaru za pomocą ruchomej linii
t początkowy osi symetrii drogi z punktem
ora.

- użytkowy będzie budowany poczynając od procedur
., tak jak jest to najczęściej praktykowane. W przykładzie
t>otrzebne będzie wyznaczanie kątów. W języku AutoLISP, podo-
^s. w innych językach programowania, miarą kątów są radiany. Wyra-
e w radianach wartości kątów mają wartości z przedziału od zera do 2*n
(PI). Ponieważ zwykle kąty podaje się w stopniach i jest to bardziej zrozu-
miałe dla większości użytkowników, zdefiniowano funkcję realizującą opera-
cję konwersji stopni na radiany. Przy użyciu edytora tekstu należy utworzyć
plik o nazwie droga.lsp i zapisać w nim następujący program:




; Zamiana stopni na radiany

(defun dtr (a)

(*pi (/a 180.0))

Przyp. tłum.: W przedstawionym przykładzie nazwy funkcji i zmiennych
tworzono z myślą o ułatwieniu czytelnikowi zrozumienia znaczenia poszcze-
gólnych wyrażeń. Są one z tego względu dość długie. Jest to formalnie po-
prawne i program działa prawidłowo, ale zalecamy stosowanie raczej nazw
mniej rozbudowanych. Z drugiej strony warto jednak stale pamiętać o po-
trzebie utrzymywania czytelności programu, co ułatwia jego późniejszą edy-
cję. Nazwy nie powinny więc być zbyt abstrakcyjne i nie należy traktować
komentarzy za rzecz zbędną.

Przykład ten prezentuje sposób wykorzystania funkcji defun do zdefiniowa-
nia nowej funkcji o nazwie dtr. Funkcja ta posiada jeden argument a, który
jest miarą kąta w stopniach. Wynikiem wywołania funkcji jest wartość wy-
rażenia:

7t* (a/180.0)

Powyższy zapis, wyrażony w notacji LISP-u, może być odczytany jako ilo-
czyn liczby PI i wartości A podzielonej przez 180.0. Symbol n jest
w AutoLISP-ie wstępnie zdefiniowany przez przypisanie mu warto-
ści 3.14159.... Linia rozpoczynająca się od średnika jest komenta-
rzem- AutoLISP ignoruje tekst od średnika do końca linii.

Po zapisaniu programu w pliku dyskowym, należy uruchomić AutoCAD-a
i zainicjować tworzenie nowego rysunku (nazwa rysunku może być dowolna,
nie będzie on zapisywany do pliku dyskowego). Kiedy AutoCAD zasygnali-
zuje swoją gotowość do pracy zgłoszeniem Polecenie:, należy wczytać fun-
kcję do pamięci:

Polecenie: (load "droga")
AutoLISP wczyta zapisaną w pliku droga.lsp definicję naszej funkcji i po-

248 Rozpoczęcie pracy

Dodatek E

wtórzy na ekranie jej nazwę dtr (zakłada się, że plik droga.lsp znajduje się
na bibliotecznej ścieżce poszukiwań. Od tej pory użycie w niniejszym podrę-
czniku sformułowania uruchomienie AutoCAD-a i wczytanie programu, oz-
naczać będzie opisaną wyżej sekwencję działań.

Można teraz testować działanie funkcji, wywołując ją z różnymi wartościami
argumentu. Zgodnie z definicją radianów, zeru stopni powinno odpowiadać
zero radianów. Sprawdźmy to przez wprowadzenie:

Polecenie: (dtr 0)

Jeżeli w odpowiedzi na zgłoszenie gotowości AutoCAD-a Polecenie; rozpo-
cznie się wprowadzanie tekstu, którego pierwszym znakiem jest lewy na-
wias, to AutoCAD przekaże tę linię AutoLISP-owi w celu ewaluacji wyraże-
nia. W powyższym przypadku wyznaczona zostanie wartość właśnie zdefi-
niowanej funkcji dtr dla argumentu równego zero. Po ewaluacji, AutoCAD
wyświetli otrzymany wynik. Tak więc, wprowadzenie powyższego polecenie
powinno spowodować wygenerowanie wartości:

0,0
Można przetestować, jak funkcja działa dla 180 stopni. Po wprowadzeniu:

Polecenie: (dtr 180)
można zobaczyć odpowiedź:

3.14159

Oznacza to, że 180 stopni odpowiada n radianom i potwierdza zgodność dzia-
łania funkcji z podaną definicją.

W tym momencie należy wyjść z AutoCAD-a (poleceniem REZYGNUJ) i po-
wrócić do wykorzystywanego edytora tekstowego.

Wprowadzanie danych wejściowych

Opracowywane polecenie "droga" będzie wymagało od użytkownika wprowa-
dzenia informacji gdzie drogę narysować, jaka ma być jej szerokość, jak du-
żymi płytami ma być wyłożona i jak blisko siebie mają być one rozmieszczo-
ne. Zdefiniujemy obecnie funkcję, która spowoduje pojawianie się odpowied-
nich pytań, umożliwi wprowadzanie danych oraz wyznaczy różne wartości
liczbowe, które będą używane w dalszej części polecenia.

Do istniejącego już pliku droga.lsp, za pomocą edytora tekstu, należy dodać
podane niżej nowe linie programu (pionowe kreski oznaczają tu nowe linie,
dodawane na każdym kolejnym etapie).

Uwaga: W przypadku wykorzystywania komputera pracującego pod kontrolą
systemu operacyjnego DOS, w celu przejścia z edytora rysunkowego AutoCAD-
a do systemu operacyjnego można skorzystać z polecenia SYSTEM. Tym sa-
mym możliwe jest używanie procesora tekstów w celu edycji pliku droga.lsp bez
potrzeby wychodzenia z AutoCAD-a.

; Zamiana stopni na radiany

(defun dtr (a)

(*pi(/a 180.0))
)

Wprowadzanie danych wejściowych 249

Ćwiczenia

; Wprowadzanie danych określających parametry drogi

(defun gpuser ()

(setq sp (getpoint "\nPunkt początkowy drogi: "))
(setq ep (getpoint "\nPunkt końcowy drogi: "))
(setq hwidth (getdist "\nPołowa szer. drogi:" sp))
(setq trąd (getdist "\nPromień płyty: " sp))
(setq tspac (getdist "\n0dstęp między płytami: " sp))

(setq pangle (angle sp ep))
(setq plength (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki + 90 stopni
(setq angm90 (- pangle (dtr 90))); Kąt ścieżki - 90 stopni
)

Stosowanie wcięć akapitowych, w celu wyróżnienia poszczególnych wyra-
żeń, które składają się na definicje naszych funkcji, nie jest konieczne. Mo-
żliwe jest nawet napisanie całego programu w jednej linii. Jednakże podział
programu na linie i stosowanie akapitów znacznie zwiększa jego czytelność.
Ponadto, w celu poprawnego zbilansowania liczby nawiasów warto, odpo-
wiadające sobie nawiasy otwierające i zamykające wyrażenia główne, pisać
w tej samej kolumnie. Zalecamy również wykonywanie wcięć akapitowych
z wykorzystywaniem spacji, a nie tabulacji. Uniezależnia to wielkość wyko-
nanych wcięć od sesji edycyjnych i stosowanych edytorów.

Zdefiniowana wyżej funkcja nazwana została gpuser. Nie ma ona żadnych
argumentów. Wszystkie niezbędne do obliczeń dane są pobierane w toku dia-
logu z użytkownikiem. Wartości przypisywane są zmiennym AutoLISP-u za
pomocą funkcji setq. Najpierw funkcja setq przypisuje zmiennej sp rezultat
wywołania funkcji getpoint. Funkcja getpoint pobiera współrzędne punktu
wprowadzonego przez użytkownika. Łańcuch znaków tekstowych, ujęty
w znaki cudzysłowu, określa treść zgłoszenia, zawierającego pytanie, które
AutoCAD wyświetli przed wprowadzeniem punktu. Znaki sterujące \n powo-
dują, że pytania będą wypisywane w nowych liniach. Do wczytania wartości
liczbowych połowy szerokości drogi, promienia płyty oraz odległości między
płytami, użyto funkcji getdist. Drugim argumentem funkcji getdist jest
punkt sp, który wskazuje położenie punktu bazowego, względem którego get-
dist określa poszczególne wielkości liniowe. Dzięki temu, jeżeli będą one
określane przez wskazywanie punktów, to wymiary liniowe będą mierzone
względem początkowego punktu drogi. Między punktem tym i punktem
odpowiadającym położeniu kursora, pojawi się na ekranie ruchoma linia po-
mocnicza, umożliwiająca wizualną ocenę wprowadzanej wartości.

Po wprowadzeniu wszystkich danych, określających wymiary drogi, zostaną
obliczone wartości szeregu zmiennych, które będą później często w progra-
mie używane. Zmienna pangle przyjmuje wartość kąta nachylenia drogi,
mierzonego jako kąt nachylenia odcinka od punktu początkowego do punktu
końcowego. Kąt ten wyznaczony zostaje przy pomocy funkcji angle, której ar-
gumentami są oba punkty określające kąt. Zmienna plength przyjmuje war-
tość równą długości drogi.Długość ta wyznaczona zostaje przy pomocy fun-
kcji distance, której argumentami są również punkty początkowy sp i koń-
cowy ep. Zmienna width określa szerokość drogi, która przyjmuje podwójną
wartość zmiennej hwidth, odpowiadającej z kolei połowie szerokości drogi.
W zmiennych angp90 i angm90 zapamiętane zostają wartości kąta nachy-
lenia drogi powiększone i zmniejszone o 90 stopni (ponieważ AutoLISP okre-

250 Wprowadzanie danych wejściowych

Dodatek E

ślą miary kątowe w radianach, do przeliczenia stopni na radiany użyta zo-
stała zdefiniowana wcześniej funkcja dtr).

Poniższa ilustracja prezentuje sens geometryczny zmiennych występujące
w programie gpuser.




Zaktualizowany program należy zapisać na dysku, a następnie uruchomić
AutoCAD i wczytać program. Można sprawdzić poprawność działania zde-
finiowanej funkcji. Wywołanie funkcji jest następujące:

Polecenie: (gpuser)
Należy wprowadzić następujące odpowiedzi na pojawiające się zgłoszenia:

Punkt początkowy drogi: 80,80
Punkt końcowy drogi: 300,250
Połowa szerokości drogi: 60
Promień płyty: 6
Odstępy między płytami: 3

Po wprowadzeniu danych, program gpuser przypisze wartości wszystkim
zmiennym, a następnie wyświetli ostatnią policzoną wartość (w tym przy-
padku będzie to -0.912908, wartość zmiennej angm90 w radianach). Usta-
lone przez gpuser wartości wszystkich zmiennych można wyświetlić przez
wprowadzanie ich nazw poprzedzonych znakiem wykrzyknika (!). Nakazuje
to AutoCAD-owi wyznaczenie wartości zmiennej i wyświetlenie uzyskanego
wyniku. Po wprowadzeniu poniższych poleceń powinniśmy otrzymać poka-
zane niżej wartości:

Polecenie: !sp
(80.0 80.0 0.0)
Polecenie: !ep
(300.0 250.0 0.0)
Polecenie: !hwidth

Wprowadzanie danych wejściowych 251

Ćwiczenia

60.0

Polecenie: !wicHh

120.0

Polecenie: !trad

6.0

Polecenie: Itspac

3.0

Polecenie: Ipangle

0.657889

Polecenie; iplength

278.029

Polecenie; !angp90

2.22868

Polecenie: !angm90

-0.912908

Należy zauważyć, że zmienne sp oraz ep są zwracane jako punkty 3W; w na-
szym przykładzie współrzędna Z może zostać zignorowana.

Zmienne pangle, anglep90 i anglem90, wyrażają wartości kątów w radia-
nach. Po ich sprawdzeniu, należy wyjść z AutoCAD-a i wrócić do edycji pliku
droga.isp.

Kontur drogi

Po uzgodnieniu lokalizacji drogi można już narysować jej kontur. Do pliku
droga.isp należy dodać kolejne linie programu, zaznaczone pionową kreską.

; Zamiana stopni na radiany

(defun dtr (a)

(*pi (/a 180.0))
)

; Wprowadzanie danych określających parametry drogi

(defun gpuser ()

(setq sp (getpoint "\nPunkt początkowy drogi: "))
(setq ep (getpoint "\nPunkt końcowy drogi:"))
(setq hwidth (getdist "\nPołowa szer. drogi:" sp))
(setq trąd (getdist "\nPromień płyty: " sp))
(setq tspac (getdist "\n0dstęp między płytami:" sp))

. (setq pangle (angle sp ep))
(setq plength (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki + 90 stopni
(setq angm90 (- pangle (dtr 90))) ; Kąt ścieżki - 90 stopni

252 Kontur drogi

Dodatek E

; Rysowanie konturu drogi

(defun drawout ()
(command "_pline"

(setq p (polar sp angm90 hwidth))
(setq p (polar p pangle plength))
(setq p (polar p angp90 width))
(polar p (+ pangle (dtr 180)) plength)
"close"

Dodane linie programu definiują funkcję o nazwie drawout. Wykorzystując
otrzymane przy pomocy funkcji gpuser wartości określające punkt począt-
kowy, kąt nachylenia i długość drogi, funkcja rysuje kontur drogi z użyciem
polilinii. Do przekazania do programu AutoCAD nazwy polecenia PLINIA
i danych z AutoLISP-u, wykorzystana została funkcja command. Funkcja
command może mieć dowolną ilość argumentów, z których każdy jest prze-
kazywany do AutoCAD-a. W tym przypadku do AutoCAD-a jest przesyłane
polecenie PLINIA, polecenie to jest wydawane i następnie przekazywane
jest położenie czterech rogów obszaru zajmowanego przez drogę ogrodową.
Każdy punkt narożnikowy wyznaczany jest za pomocą funkcji polar i zapa-
miętany w zmiennej roboczej p. Pierwszym argumentem funkcji polar jest
punkt, drugim i trzecim są odpowiednio kąt i odległość. Funkcja zwraca wy-
nik, którym jest punkt oddalony od pierwszego o podaną odległość i kąt.
W naszym przypadku, cztery punkty wyznaczające obrys konturu drogi zo-
stały wyliczone względem jej punktu początkowego sp. Koniec działania po-
lecenia PLINIA wymuszony jest łańcuchem tekstowym _close, (opcja za-
mknij polecenia PLINIA), który powoduje narysowanie czwartej krawędzi
drogi i powrót do zgłoszenia Polecenie:, oznaczającego gotowość AutoCAD-a
do przyjmowania dalszych poleceń.

W celu przetestowania utworzonej funkcji, po zapisaniu ostatniej, zaktuali-
zowanej wersji programu w pliku droga.lsp, można uruchomić AutoCAD
i podobnie jak poprzednio, wczytać program napisany właśnie w języku
LISP. Należy w tym celu uaktywnić funkcję pozwalającą na wprowadzenie
danych drogi:

Polecenie: (gpuser)

i wprowadzić te same co przedtem wartości liczbowe. W celu sprawdzenia
działania nowej funkcji drawout, należy ją wywołać przez wprowadzenie jej
nazwy:

Polecenie: (drawout)

Funkcja ta przekazuje do AutoCAD-a polecenia powodujące rysowanie kon-
turu drogi, który pojawia się na ekranie monitora. Po obejrzeniu rysunku
można wprowadzić polecenie REZYGNUJ i przerwać pracę z AutoCAD-em
bez zapisywania rysunku.

Rysowanie płyt

Po opracowaniu i przetestowaniu funkcji służącej do wprowadzania danych,
oraz funkcji powodującej rysowanie konturu drogi, można przystąpić do wy-
kładania jej okrągłymi płytami. Wymaga to wykonania pewnych obliczeń

Rysowanie ptyt 253

Komunikaty błędów

'laniu edytora tekstów, zapisany w pliku droga.lsp
o kolejne funkcje, wyróżnione poniżej pionową

Autr




try drogi

-iiKowy drogi: "))
. Końcowy drogi: "))
inPołowa szer. drogi:" sp))
^tAnProm\eń płyty:" sp))
letdist "\n0dstęp między płytami:" sp))

pangle (angie sp ep))
setq plength (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki + 90 stopni
(setq angm90 (- pangle (dtr 90))) ; Kąt ścieżki - 90 stopni

; Rysowanie konturu drogi

(defun drawout ()
(command "pline"

(setq p (polar sp angm90 hwidth))
(setq p (polar p pangle plength))
(setq p (polar p angp90 width))
(polar p (+ pangle (dtr 180)) plength)
"close"

Rozmieszczenie jednego rzędu płyt w poprzek ścieżki,

w odpowiedniej odległości wzdłuż osi drogi od punktu początkowego

i z ewentualnym przesunięciem poprzecznym (przesuwany będzie co 2-gi rząd)

(defun drow (pd offset)

(setq pfirst (polar sp pangle pd))

(setq pctiie (polar pfirst angp90 offset))

(setq p1tile pctiie)

(while (< (distance pfirst p1tile) (- hwidth trąd))

(command "_circle" p1tile trąd)

(setq p1tile (polar p1tile angp90 (+ tspac trąd trąd)))

)

(setq p1tile (polar pctiie angm90 (+ tspac trąd trąd)))

(while (< (distance pfirst p1tile) (- hwidth trąd))

(command "_circle" p1tile trąd)

(setq p1tile (polar p1tile angm90 (+ tspac trąd trąd)))

)

254 Rysowanie ptyt

Dodatek E

; Rysowanie rzędu ptyt

(defun drawtiies ()

(setq pdist (+ trąd tspac))

(setq off 0.0)

(while (<= pdist (- plength trąd))

(drow pdist off)

(setq pdist (+ pdist (* (+ tspac trąd trąd) (sin (dtr 60)))))

(if (= off 0.0)

(setq off (* (+ tspac trąd trąd) (cos (dtr 60))))

(setq off 0.0)

W celu zrozumienia zasad działania tych funkcji pomocna będzie przedsta-
wiona ilustracja. Funkcja drow rysuje jeden rząd płyt w odpowiedniej odle-
głości wzdłuż osi drogi względem punktu początkowego, którą określa pier-
wszy argument. Drugi argument określa natomiast przesunięcie środków
płyt w kierunku prostopadłym do osi drogi. W celu lepszego pokrycia powie-
rzchni oraz uzyskania przyjemniejszego dla oka wzoru, wprowadzono po-
przeczne przesunięcie płyt w co drugim rzędzie.




Funkcja drow znajduje położenie środka pierwszej płyty w rzędzie, używając
funkcji polar, która przesuwa płytę wzdłuż kierunku drogi o odległość poda-
ną jako pierwszy argument. Następnie funkcja polar jest wykorzystywana
ponownie, tym razem do przesunięcia płyty prostopadle do kierunku drogi,
odpowiednio do wartości drugiego z argumentów funkcji drow. Do rysowa-
nia kolejnych okręgów, aż do momentu dojścia do brzegu drogi, wykorzysta-
na jest następnie funkcja while. Funkcja setq, wywoływana po zakończeniu

Rysowanie płyt 255

Ćwiczenia

pętli while, powoduje przejście do punktu wyznaczającego położenie kolejnej
płyty, której środek jest lokalizowany z przeciwnej strony środka płyty na-
rysowanej w danym rzędzie w pierwszej kolejności, w odległości od niego równej
sumie dwóch promieni płyty i jednego odstępu między sąsiednimi płytami.

W drugiej pętli while rysowane są następnie okręgi w tym samym rzędzie,
lecz w kierunku przeciwnym, aż do dojścia do drugiego brzegu drogi.

Funkcja drawtiies powtarza wywołanie funkcji drow, aż do całkowitego wy-
pełnienia konturu drogi rzędami płyt. Pętla while każdorazowo sprawdza
czy rząd płyt, który ma być narysowany, nie przekroczy granicy wyznaczonej
konturem tym samym steruje wywołaniami funkcji drawtiies. Płyty z są-
siednich rzędów są rozmieszczone tak, że ich środki leżą w wierzchołkach
trójkątów równobocznych co pokazano na rysunku. Bok takiego trójkąta ma
długość równą sumie dwóch promieni płyt i odległości między płytami. Z za-
leżności trygonometrycznych można zatem wyznaczyć odległość między rzę-
dami; odległość liczona wzdłuż osi drogi jest równa iloczynowi sinusa 60 sto-
pni i długości boku trójkąta. Przesunięcie poprzeczne środków płyt w sąsied-
nich rzędach jest równe iloczynowi cosinusa 60 stopni i tej długości.

W celu uzyskania poprzecznego przesunięcia sąsiednich rzędów, zastosowa-
no w podprogramie drawtiies funkcję if. Należy zwrócić uwagę na sposób jej
wykorzystania, if sprawdza pierwszy argument i jeżeli określony w nim wa-
runek jest spełniony, to wyliczane jest wyrażenie podane jako drugi argu-
ment. W przeciwnym przypadku wyliczane jest wyrażenie podane jako trze-
ci argument. W naszym przypadku, jeżeli zmienna OFF ma wartość zero, to
przypisuje się jej wartość równą iloczynowi odległości między środkami płyt
i kosinusa kąta 60 stopni. Jeżeli natomiast OFF ma wartość różną od zera,
to przypisywaną jej wartością jest zero. W ten sposób uzyskuje się zgodne
z naszym zamierzeniem cykliczne przesuwanie co drugiego rzędu płyt w kie-
runku poprzecznym względem osi drogi.

W celu przetestowania funkcji należy zapisać plik na dysku, uruchomić Au-
toCAD i wczytać program. Następnie można wywołać program.

Polecenie: (gpuser)
i wprowadzić dane takie same jak poprzednio. Następne polecenie:

Polecenie: (drawout)
spowoduje narysowanie konturu drogi. W końcu wprowadzając:

Polecenie: (drawtiies)
uzyska się wypełnienie konturu drogi płytami.

256 Rysowanie płyt

Dodatek E

Dodanie nowego polecenia do AutoCAD-a

W rozdziale tym przedstawiono sposób utworzenia nowego polecenia
AutoCAD-a wykorzystującego napisane funkcje (podprogramy). Jeżeli
w AutoLISP-ie zdefiniowano funkcję, której nazwa ma postać C:XXX,
to wprowadzając XXX po zgłoszeniu gotowości Polecenie: można tę fun-
kcję wywołać. XXXnie może być nazwą żadnego wewnętrznego polecenia Au-
toCAD-a. Zatem w celu zakończenia procesu dodawania polecenia DROGA,
należy zdefiniować funkcję C: DROGA. Jej zadaniem jest umożliwienie ko-
rzystania z dodatkowego polecenia do rysowania drogi ogrodowej przez
zwykłe wprowadzenie w dowolnym momencie jego nazwy, po uprzednim
wczytaniu pliku droga.lsp do pamięci komputera.

Przy użyciu edytora tekstu należy dodać zaznaczone linie do pliku droga.lsp,
a następnie uruchomić AutoCAD i wczytać program.

; Zamiana stopni na radiany

(defun dtr (a)

(*pi (/a 180.0))
)

; Wprowadzanie danych określających parametry drogi

(defun gpuser ()

(setq sp (getpoint "\nnPunkt początkowy drogi:"))
(setq ep (getpoint "\nPunkt końcowy drogi; "))
(setq hwidth (getdist "\nPołowa szerokości drogi:" sp))
(setq trąd (getdist "\nPromień płyty:" sp ))
(setq tspac (getdist "\n0dstęp między płytami:" sp))

(setq pangle (angle sp ep))
(setq plenght (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki +90 stopni
(setq angm90 (- pangle (dtr 90))) ; Kąt ścieżki -90 stopni
)

; Rysowanie konturu drogi

(defun drawout ()
(command "pline"

(setq p (polar sp angm90 hwidth))
(setq p (polar p pangle plength))
(setq p (polar p angp90 width))
(polar p (+ pangle (dtr 180)) plength)
"close"

Dodanie nowego polecenia do AutoCAD-a 257

Ćwiczenia

; Rozmieszczenie jednego rzędu płyt w poprzek ścieżki, w odpowiedniej
; odległości wzdłuż osi drogi od punktu początkowego i z ewentualnym
; przesunięciem poprzecznym (przesuwany będzie co drugi rząd

(defun drow (pd offset)
(setg pfirst (polar sp pangle pd))
(setq pctiie (polar pfirst angp90 offset))
(setq p1tile pctiie)
(while (< (distance pfirst p1tile) (- hwidth trąd))

(command "circie" p1tile trąd)

(setq p1tile (polar p1tile angp90 (+ tspac trąd trąd)))

)

(setq p1tile (polar pctiie angm90 (+ tspac trąd trąd)))

(while (< (distance pfirst p1tile) (- hwidth trąd))

(command "circie" p1tile trąd)

(setq p1tile (polar p1tile angm90 (+ tspac trąd trąd)))

)
)

; Rysowanie rzędów płyt

(defun drawtiies ()
(setq pdist (+ trąd tspac))
(setq off 0.0)
(while (<= pdist (- plength trąd))
(drow pdist off)

(setq pdist (+ pdist (* (+ tspac trąd trąd) (sin (dtr 60)))))
(if (= off 0.0)

(setq off (* (+ tspac trąd trąd) (cos (dtr 60))))
(setg
)
)
)

; Definicja polecenia realizującego wywołania kolejnych funkcji

(defun C:DROGA ()

(gpuser)

(drawout)

(drawtiies)
)

258 Dodanie nowego polecenia do AutoCAD-a

Dodatek E

W wyniku dodania funkcji o nazwie C: DROGA, polecenie DROGA zostało
dodane do AutoCAD-a. Jego działanie można przetestować przez wprowa-
dzenie:

Polecenie: droga

Punkt poczqtkowy drogi: 80,80

Punkt końcowy drogi: 300,250

Potowa szerokości drogi: 60

Promień płyty: 6

Odstęp między płytami: 3

Obraz uzyskany na ekranie komputera powinien odpowiadać przedstawio-
nemu na kolejnym rysunku.




Dodanie nowego polecenia do AutoCAD-a 259

Ćwiczenia

Usprawnienie działania polecenia

W czasie wykonywania polecenia DROGA, w obszarze komunikatów poja-
wia się echo wszystkich wykonywanych poleceń, a na ekranie pojawiają się
znaczniki wybieranych punktów. Po zakończeniu sprawdzania poprawności
działania polecenia i po wprowadzaniu ewentualnych korekt, efekty te moż-
na zlikwidować. Polecenie utworzone w AutoLISP-ie będzie dzięki temu wy-
konywane tak samo, jak standardowe polecenia AutoCAD-a. W tym celu do
pliku droga.lsp należy dodać zaznaczone linie:

; Zamiana stopni na radiany

(defun dtr (a)

(*pi (/a 180.0))
)

; Wprowadzanie danych określających parametry drogi

(defun gpuser ()

(setq sp (getpoint "\nPunkt początkowy drogi: "))
(setq ep (getpoint "\nPunkt końcowy drogi: "))
(setq hwidth (getdist "\nPołowa szer. drogi: " sp))
(setq trąd (getdist "\nPromień płyty: " sp))
(setq tspac (getdist "\n0dstęp między płytami:" sp))

(setq pangle (angle sp ep))
(setq plength (distance sp ep))
(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki + 90 stopni
(setq angm90 (- pangle (dtr 90))) ; Kąt ścieżki - 90 stopni
)

; Rysowanie konturu drogi

(defun drawout ()
(command "pline"

(setq p (polar sp angm90 hwidth))
(setq p (polar p pangle plength))
(setq p (polar p angp90 width))
(polar p (+ pangle (dtr 180)) plength)
"close"
)

; Rozmieszczenie jednego rzędu płyt w poprzek ścieżki,

; w odpowiedniej odległości wzdłuż osi drogi od punktu początkowego

; i z ewentualnym przesunięciem poprzecznym (przesuwany będzie co 2-gi rząd)

(defun d rów (pd offset)

(setq pfirst (polar sp pangle pd))
(setq pctiie (polar pfirst angp90 offset))
(setq p1tile pctiie)

260 Usprawnienie działania polecenia

Dodatek E

(while (< (distance pfirst p1tile) (- hwidth trąd))

(command "_circle" p1tile trąd)

(setq p1tile (polar p1tile angp90 (+ tspac trąd trąd)))

)

(setq p1tile (polar pctiie angm90 (+ tspac trąd trad)))R (while (< (distance pfirst
p1tile) (- hwidth trąd))

(command "_circle" p1tile trąd)

(setq p1tile (polar p1tile angm90 (+ tspac trąd trąd)))

)
)

; Rysowanie rzędu płyt

(defun drawtiies ()

(setq pdist (+ trąd tspac))

(setq off 0.0)

(while (<= pdist (- plength trąd))

(drow pdist off)

(setq pdist (+ pdist (* (+ tspac trąd trąd) (sin (dtr 60)))))

(if (= off 0.0)

(setq off (* (+ tspac trąd trąd) (cos (dtr 60))))
(setq off 0.0)

)

)
)

; Definicja polecenia realizującego wywołania kolejnych funkcji

(defun C: DROGA ()

(setq sblip (getvar "blipmode"))

(setq scmde (getvar "cmdecho"))

(setvar "blipmode" 0)

(setvar "cmdecho" 0)

(drawout)

(drawtiie)

(setvar "blipmode" sblip)

(setvar "cmdecho" scmde)

(princ)
)

Do odczytania bieżących wartości zmiennych systemowych AutoCAD-a
BLIPMODE i CMDECHO, wykorzystano tu funkcję getvar. Uzyskane war-
tości zmiennych systemowych są czasowo przechowywane jako wartości spe-
cjalnie w tym celu utworzonych zmiennych sblip i scmde; odpowiednie war-
tości nadano im za pomocą wywołań funkcji setq. W celu zlikwidowania zna-
czników i efektów echa, należy nadać zmiennym systemowym BLIPMODE
i CMDECHO wartość zero. Do tego celu wykorzystano funkcję setvar. Za-
równo echo, jak i znaczniki, są wyłączane już po wprowadzeniu danych
w funkcji gpuser (przy wczytywaniu danych były one potrzebne).

Gdy droga jest już narysowana, obu tym zmiennym systemowym należy
przypisać ich wartości wyjściowe; użyto do tego celu funkcji setvar.

Dodanie na końcu wywołania funkcji princ pozwala na ciche (niezauważal-
ne) zakończenie funkcji C: DROGA. Funkcje AutoLISP-u zawsze zwracają
wartość ostatniego wywołania funkcji. W powyższym przykładzie, gdyby nie
dodano wywołania funkcji princ, zwracana byłaby wartość l lub 0.

Usprawnienie działania polecenia 261

Ćwiczenia

Aby przetestować działanie programu, należy zapisać zaktualizowany plik
tekstowy na dysku, następnie uruchomić AutoCAD i wczytać program do pa-
mięci. Można wtedy wypróbować działanie polecenia DROGA w kilku wa-
riantach, wprowadzając dane za pomocą urządzenia wskazującego lub z kla-
wiatury.

Dodanie okien dialogowych

Specjalny język programowania okien dialogowych (Dialogue Control Lan-
guage) pozwala na wyposażenie napisanego w AutoLISP-ie programu użyt-
kownika w zdefiniowane przez niego okna dialogowe.

Zdefiniowane poprzednio nowe polecenie DROGA akceptuje dane podawane
w linii poleceń. Można łatwo wyposażyć to polecenie w interfejs z oknami
dialogowymi, wykorzystując w tym celu specjalne przeznaczone do tego fun-
kcje, opisane w części "Funkcje programowalnych okien dialogowych" w roz-
dziale 3 oraz tworząc plik .dcl, zawierający opis okna dialogowego w języku
DCL. AutoLISP-owe funkcje do programowania okien dialogowych oraz ję-
zyk DCL są szczegółowo opisane w rozdziale 9 podręcznika AutoCAD Pod-
ręcznik Adaptacyjny.

Okna dialogowe są bardzo przydatne, jeśli chcemy dać użytkownikowi pro-
gramu możliwość wyboru spośród kilku opcji, definiowania rozmiarów
i określania ilości, przed podjęciem ostatecznej decyzji o wykonaniu polece-
nia. W obecnym stanie nasz program posiada bardzo niewiele opcji, w któ-
rych można zastosować okna dialogowe. Można dodać teraz kilka nowych
możliwości.

Dodatkową możliwością funkcji C: DROGA, może być określanie przez użyt-
kownikowa kształtu płyt chodnikowych na ścieżce oraz dodanie także fun-
kcji obsługi błędów.

Należy zacząć od skopiowania ostatniej wersji pliku droga.lsp do innego pli-
ku, o nazwie dddroga.lsp (większość dostarczonych z AutoCAD-em progra-
mów, prowadzących konwersację z użytkownikiem za pomocą okien dialogo-
wych, noszą nazwy postaci ddxxx.lsp). Utworzymy także nowy plik dddro-
ga.dcl, zawierający opis okna dialogowego w języku DCL.

Plik dddroga.dcl - opis w języku DCL

Okno dialogowe, które teraz utworzymy, będzie zawierało dwa ekranowe
przyciski sekwencyjne (po wybraniu jednego, automatycznie anulowany jest
wybór drugiego, podobnie jak w zestawie przełączników radiowych do zmia-
ny zakresu), służące do wybrania kształtu płyt chodnikowych: koła lub wie-
loboku. Będzie zawierało także trzy okienka edycyjne, przeznaczone do
wprowadzania wartości liczbowych: promienia płyty, odległości między pły-
tami i liczby boków (pole ta będzie dostępne tylko wtedy, gdy wybrany będzie
przycisk sekwencyjny Wielobok).

Bez zagłębiania się zbyt głęboko w szczegóły działania mechanizmu DCL
i związanych z tym funkcji AutoLISP-u, zostaną pokazane kolejne kroki,
które trzeba wykonać aby do funkcji C:DROGA dodać proste okno dialogowe.
Poniższy kod powinien zostać umieszczony w pliku dddroga.dcl: jest to więc
zawartość pliku DCL.

262 Dodanie okien dialogowych

Dodatek E

/* DDDROGA.DCL - plik DCL dla DDDROGA.LSP */

gp_box1 : dialog {

label = "Ogród Ścieżka Płyta Specyfikacje";

: boxed_radio_row {
label = "Kształt płyty";

: radio_button {

label = "Wielobok";

mnemonic = "W";

key = "gp_poly";

}
: radio_button {

label = "Koło";

mnemonic = "K";

key = "gp_circ";

value = "1";

}

}

: edit_box {

label = "Promień płyty";

mnemonic = "P";

key = "gpJrad";

edit_width = 6;

}

: edit_box {

label = "Odstęp między płytami";

mnemonic = "O";

key ="gp"spac";

edit_width = 6;

}

: edit_box {

label = "Ilość boków";

mnemonic = "l";

key = "gp_side";

edit_width = 4;

}

: rów {

: spacer { width = 1;}

: button {

label = "OK";

key = "accept";

width = 8;

fixed_width = true;

}
: button {

label = "Anuluj";

is_cancel = true;

key = "cancel";

width = 8;

fixed_width = true;

}
: spacer { width = 1;}

}

Dodanie okien dialogowych 263

Ćwiczenia

Funkcje dla okien dialogowych w AutoUSP-ie - dddrogCLisp

Teraz, kiedy już został utworzony plik DCL, można wpisać dodatkowe linie
do pliku AutoLISP-u dddroga.lsp, utworzonego z pliku droga.isp.

Podobnie jak w przypadku pliku DCL, nie będzie szczegółowych objaśnień
dotyczących działania poszczególnych funkcji. Nazwy funkcji wskazują na
ich przeznaczenie. Funkcja set_dialog robi dokładnie to, co podpowiada jej
nazwa: wczytuje dialog. Funkcja set_tile przypisuje wartość wstępną dla wy-
branego wycinka (każdy przycisk, pole edycyjne i podobne elementy okien są
nazywane wycinkiem) zgodnie z wartością podanego łańcucha ALFA-
NUMERYCZNEGO, a action_tile definiuje działanie, jakie ma być podjęte
po uaktywnieniu przycisku (edycja, wybór, naciśnięcie i podobne).

Nowe linie kodu, tak jak dotychczas, są oznaczone przez znak pionowej kre-
ski " |". Niektóre stare linie muszą być zablokowane znakiem komentarza,
lub usunięte z nowego pliku. Linie te są wyróżnione przez druk pogru-
biony i oznakowane przez dwa średniki na początku linii (;;) oraz uwa-
gą ;<-USUNĄĆ na końcu.

;;; DDROGA.LSP - stara dobra ścieżka ogrodowa z nowym skrętem.
; Zamiana stopni na radiany

(defun dtr (a)

(*pi (/a 180.0))
)

; Wprowadzanie danych określających parametry drogi

(defun gpuser ()

(setq sp (getpoint "\nPunkt początkowy drogi: "))

(setq ep (getpoint sp "\nPunkt końcowy drogi: "));
(setq hwidth (getdist "\nPołowa szer. drogi:" sp))
; ; (setq trąd (getdist "\nPromień płyty: " sp)) ;<- USUNĄĆ
; ; (setq tspac (getdist "\n0dstęp między płytami: " sp));<- USUNĄĆ

(setq pangle (angle sp ep))

(setq plength (distance sp ep))

(setq width (* 2 hwidth))

(setq angp90 (+ pangle (dtr 90))) ; Kąt ścieżki + 90 stopni

(setq angm90 (- pangle (dtr 90))) ; Kąt ścieżki - 90 stopni
)

; Rysowanie konturu drogi

(defun drawout ()
.(command "pline"

(setq p (polar sp angm90 hwidth))
(setq p (polar p pangle plength))
(setq p (polar p angp90 width))
(polar p (+ pangle (dtr 180)) plength)
"_close"

264 Dodanie okien dialogowych

Dodatek E

; Wywołanie okna dialogowego w celu określenia parametrów kafelka

(defun gp_dialog ()
(setq tshape "Koło"

trąd 0.5

tspac 0.1

tsides 8)

(setq dcIJd (load_dialog "dddroga.dcl"))
(if (not (new_dialog "gp_box1" dcl_id))(exit))
(set_tile "gpJrad" "0.5")
(set_tile "gp_spac" "0.1")
(modeJile "gp_side" 1)
(setJile "gp_side" "8")
(actionJile "gp_circ"

"(setq tshape \"Koło\")(mode_tile \"gp_side\" 1)")
(action_tile "gp_poly"

"(setq tshape \"Wielobok\")(mode_tile \"gp_side\" 0)")
(actionJile "anuluj" "(done_dialog)(setq gperr\"\")(exit)")
(actionJile "zaakceptuj"
(strcat

"(progn (setq trąd (atof (getJile \"gpJrad\")))"

"(setq tspac (atof (getJile \"gp_spac\")))"

"(setq tsides (atoi (getJile \"gp_side\")))"

"(done_dialog))"
)
)

(start_dialog)
(unload_dialog dcIJd)
(if (= tshape "Koło")

(defun gpJile () (command "_Circle" p1tile trąd))
(defun gpJile () (command "_Polygon" tsides p1tile ""trąd))

; Definiowanie procedury obsługi błędów

(defun gp_err (msg)
(setq *error* olderr)
(if (not gperr)

(princ (strcat "\nBłąd rysowania ścieżki ogrodowej: "msg))
(princ gperr)

)

(if sblip (setvar "blipmode" sblip))
(if scmde (setvar "cmdecho" scmde))
(princ)
)

; Rozmieszczenie jednego rzędu płyt w poprzek ścieżki,

; w odpowiedniej odległości wzdłuż osi drogi od punktu początkowego

; i z ewentualnym przesunięciem poprzecznym (przesuwany będzie co 2-gi rząd)

(defun d rów (pd offset)

(setvar "snapang" pangle)
(setq pfirst (polar sp pangle pd))
(setq pctiie (polar pfirst angp90 offset))

Dodanie okien dialogowych 265

(setq p1tile pctiie)
(while (< (distance pfirst p1tile) (- hwidth trąd))

(gp-tiie)

(command "circie" p1tile trąd) ;<-USUNĄĆ

(setq p1tile (polar p1tile angp90 (+ tspac trąd trąd)))

)

(setq p1tile (polar pctiie angm90 (+ tspac trąd trąd)))

(while (< (distance pfirst p1tile) (- hwidth trąd))

(gpJile)

(command "circie" p1tile trąd) ;<-USUNĄĆ

(setq p1tile (polar p1tile angm90 (+ tspac trąd trąd)))

; Rysowanie rzędu płyt

(defun drawtiies ()

(setq pdist (+ trąd tspac))

(setq off 0.0)

(while (<= pdist (- plength trąd))

(drow pdist off)

(setq pdist (+ pdist (* (+ tspac trąd trąd) (sin (dtr 60)))))

(if (= off 0.0)

(setq off (* (+ tspac trąd trąd) (cos (dtr 60))))

(setq off 0.0)

; Wykonanie polecenia, wywołujące wchodzące w jego skład funkcje

(defun C:DDPATH ()
(setq olderr *error*

*error* gp_err

sblip nil

scmde nil

gperr nil
)

(gpuser)

(setq sblip (getvar "blipmode"))

(setq scmde (getvar "cmdecho"))

(setq sang (getvar "snapang"))

(setvar "blipmode" 0)

(setvar "cmdecho" 0)

(drawout)

(gp_dialog)

(drawtiies)

(setvar "blipmode" sblip)

(setvar "cmdecho" scmde)

(setvar "snapang" sang)

(setq *error* olderr)

(princ)

Dodanie okien dialogowych

Dodatek E

; Wyświetlenie komunikatu po wczytaniu

(princ "\nWczytano DDDROGA.LSP. W celu wywołania napisz DDDROGA.")
(princ)

Podsumowanie

Należy zwrócić uwagę na to, jak szybko udało się nam dodać do AutoCAD-a
nowe polecenie. Aby tego dokonać, w wielu innych systemach CAD niezbęd-
ny byłby dostęp do wersji źródłowych oprogramowania i duże doświadczenie
programisty. Otwarta architektura AutoCAD-a daje użytkownikowi możli-
wości, jakie większość firm opracowywujących systemy CAD rezerwuje wy-
łącznie dla siebie.

Podany przykład można traktować jako pierwszy krok na drodze do pozna-
nia AutoLISP-u. Następne próby mogą polegać na modyfikacji i rozszerze-
niu polecenia DROGA. Przykładowo, można spróbować rysować płyty
w kształcie kwadratu lub sześciokąta. Ambitniejszym zadaniem jest zdefi-
niowanie nowego polecenia tak, aby po wprowadzeniu punktu, traktowane-
go jako punkt środkowy pewnego obszaru, i pola powierzchni, rysowany był
wypełniony płytami kwadrat o tej powierzchni.

Aby dokładnie zrozumieć zasadę działania polecenia DROGA, należałoby po-
wracać do niego w miarę poznawania treści pozostałych rozdziałów podrę-
cznika. Przedstawione tu zostały jedynie bardzo pobieżne opisy działania
funkcji i sposobu ich wykorzystywania. W celu doskonalenia znajomości ję-
zyka AutoLISP i lepszego wykorzystania jego dużych możliwości, należy sta-
le wprawiać się w pisaniu różnorodnych programów.

Zastosowanie AutoLISP-u do rozwiązywania określonych specjalistycznych
zadań stanowi następny, wyższy poziom wykorzystywania AutoCAD-a. Sto-
sując język AutoLISP do tworzenia programów pomocniczych i automatyza-
cji powtarzalnych zadań kreślarskich oraz projektowych, można znacznie
poprawić efektywność pracy.




y;!--, *'. - ^'-.AK DaEBiĘr^E Ó^B^KOWO-^J

Podsumowanie 267

Wyszukiwarka

Podobne podstrony:
Access 10 PL cwiczenia praktyczne cwac10
PowerPoint 10 PL cwiczenia cwpp21
Excel 10 PL cwiczenia praktyczne cwex10
Word 10 PL cwiczenia praktyczne cwwo10
Excel 07 10 PL cwiczenia zaawansowane czex21
STOMATOLOGIA DZIECIĘCA, ĆWICZENIE 9, 10 05 2013

więcej podobnych podstron