Visual Lisp

126
Proiectare parametrizată asistată de calculator 2

Transcript of Visual Lisp

Page 1: Visual Lisp

Proiectare parametrizată asistată de calculator

2

Page 2: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

3

CCAAPPIITTOOLLUULL 11

MEDIUL VISUAL LISP

1.1 Aspecte generale privitoare la mediul Visual LISP AutoLISP este un dialect al limbajului LISP, conceput special pentru

editorul de desenare AutoCAD. LISP este o abreviere de la LISt Processing (sau LISt Programming) şi este

specializat în prelucrarea listelor. Este un limbaj de programare de nivel înalt bine cunoscut pentru aplicaţiile sale în domeniile de vârf, cum ar fi: sisteme expert, inteligenţă artificială şi baze de cunoştinţe [ 1, 3, 4, 5, 6, 7] .

Prima implementare a limbajului LISP datează din anii 1950. Astăzi, pe plan mondial, există mai multe dialecte ale acestuia, cum ar fi: Common Lisp, FranzLisp, MuLisp, XLisp etc [1, 4 ,5].

Încă de la primele versiuni de AutoCAD (versiunea 2.1 1980), limbajul AutoLISP s-a constituit într-un standard de dezvoltare a aplicaţiilor ce rulează sub AutoCAD [3].

AutoLISP-ul posedă facilităţi deosebite care atrag atât programatorii profesionişti cât şi pe cei ocazionali.

Principalele caracteristici ale limbajului sunt [1, 7]: AutoLISP are o filozofie simplă şi uşor de înţeles; are o sintaxă simplă şi riguroasă; mecanismul de evaluare a liniilor de program este uşor de înţeles aşa cum este şi sintaxa pentru definirea expresiilor utilizate în acestea;

limbajul de programare este de tip interpretor, rezultatele obţinute pot fi vizualizate interactiv în cadrul editorului de desenare AutoCAD;

este un limbaj funcţional deoarece în cadrul programelor pot fi definite numai subprograme de tip funcţie;

AutoLISP-ul este perfect compatibil cu AutoCAD-ul fără a fi necesare alte programe de interfaţare;

programatorul poate să scrie uşor funcţii structurate şi le poate combina pentru a crea programe complexe;

conţine un set puternic de funcţii grafice specializate; programele scrise în AutoLISP pot reprezenta noi funcţii definite de programator, sau noi comenzi AutoCAD;

oferă o serie de facilităţi (funcţii) suplimentare faţă de limbajul LISP clasic, care uşurează munca programatorului;

AutoLISP-ul permite iteraţii şi recursivitate; funcţiile definite de programatori pot utiliza funcţiile standard, condiţionale şi repetitive, şi pot fi definite astfel încât să se poată apela pe ele însele.

Page 3: Visual Lisp

Proiectare parametrizată asistată de calculator

4

Începând cu anul 2000, pachetul AutoCAD a inclus mediul Visual LISP (VLISP) care se constituie în următoarea generaţie de LISP pentru sistemul AutoCAD[3]. VLISP este un mediu integrat de dezvoltare a aplicaţiilor (Integrated Development Environment - IDE) care are o serie de facilităţi pentru editarea, compilarea, testarea, rularea şi depanarea programelor AutoLISP şi casetelor de dialog. Pentru AutoCAD Release 14, Visual LISP este un mediu de sine stătător, dezvoltat în limbajul C, iar pentru folosirea acestuia trebuie încărcată aplicaţia aferentă în AutoCAD.

Până la înglobarea VLISP-ului în AutoCAD, dezvoltarea programelor AutoLISP se realiza prin scrierea codului sursă în diverse editoare de texte externe, încărcarea lui în AutoCAD şi apoi lansarea în execuţie a aplicaţiilor. Depanarea programelor mari, cu multe subprograme, era deosebit de anevoioasă obligând programatorul să facă diverse artificii pentru corectarea erorilor.

Mediul VLSIP, prin componentele ce le înglobează, elimină neajunsurile semnalate mai sus, permiţând o depanare uşoară a programelor. Principalele caracteristici ale acestuia sunt următoarele [3]:

editarea programelor se realizează prin intermediul unui editor propriu care utilizează culori diferite la scrierea categoriilor de simboluri AutoLISP sau DCL şi are facilităţi de control (căutare, împerechere) a parantezelor;

rearanjarea programelor în pagină poate fi uşor realizată astfel încât acestea să devină lizibile;

realizează verificarea sintaxei programelor prin recunoaşterea construcţiilor incorecte, argumentelor greşite la apelarea diverselor funcţii etc.;

compilarea fişierelor conduce la mărirea vitezei de rulare a aplicaţiei şi la mărirea gradului de securitate a programelor;

permite lucrul cu proiecte care de regulă conţin mai multe fişiere; la compilarea acestora, fişierele sunt înglobate într-un singur modul;

depanarea aplicaţiilor permite, printre altele, rularea pas cu pas a acestora în timp ce pe ecran pot fi afişate rezultatele într-o fereastră desen AutoCAD, oprirea rulării programelor în punctele dorite şi cercetarea valorilor anumitor simboluri în cursul execuţiei;

accesul la valorile simbolurilor (date AutoLISP, entităţi AutoCAD) şi expresiilor se realizează prin ferestre de tip Watch;

înlocuieşte fereastra text a AutoCAD-ului cu fereastra Visual LISP Console care furnizează şi o serie de facilităţi suplimentare la tastarea expresiilor simbolice;

oferă asistenţă prin sistemul de Help implementat care este de tip context sensitive.

Page 4: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

5

În concluzie, Visual LISP-ul este un mediu foarte puternic, prin intermediul lui se poate îmbunătăţi modul de lucru în AutoCAD, particularizând sistemul de proiectare în funcţie de cerinţele utilizatorului.

1.2 Lansarea în execuţie a mediului Visual LISP

Visual LISP ca mediu interactiv de dezvoltare a aplicaţiilor AutoLISP, rulează separat de restul AutoCAD-ului într-o serie de ferestre proprii. Acesta are trăsăturile specifice unei aplicaţii care rulează sub sistemul de operare Windows. Pentru lansarea în execuţie a VLISP-ului, mai întâi se lansează AutoCAD-ul şi apoi se alege comanda Visual LISP Editor din submeniul AutoLISP poziţionat în submeniul Tools al AutoCAD-ului (figura 1.1a), sau se tastează în zona prompter-ului Command: comanda vlisp sau vlide (figura 1.1b). După lansarea în execuţie, pe ecran apare mediul VLISP, prezentat în figura 1.2, care are o configuraţia de ferestre în funcţie de la ultima rulare a acestuia.

a) Accesare din meniul desfăşurător al AutoCAD-ului.

b) Accesare din zona prompter-ului Command: .

Fig. 1.1 Lansarea în execuţie a VLISP-ului.

Page 5: Visual Lisp

Proiectare parametrizată asistată de calculator

6

Fig. 1.2 Componentele mediului VLISP.

Men

iul

desfăş

urăt

or

Pict

ogra

me

Fere

astr

a Bu

ild

Fere

stre

de

edita

re

a pr

ogra

mel

o

Lini

a de

st

are

Fere

astr

a

Fere

astra

Vi

sual

LI

SP

Page 6: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

7

1.3 Componentele mediului Visual LISP

La prima lansare a VLISP-ului, pe ecran pot fi identificate următoarele componente: meniul desfăşurător aflat pe a doua linie a mediului, mai multe grupuri de butoane (toolbars-uri) plasate de regulă pe următoarele linii ale mediului, o linie de stare (Status Bar), fereastra consolă (Visual LISP Console Window) şi o fereastră denumită Trace. În timpul utilizării mediului, la compilarea programelor, pe ecran apare şi fereastra Build Output.

Meniul desfăşurător conţine mai multe submeniuri în care sunt plasate comenzile mediului care pot fi lansate în execuţie de către utilizator. Sunt 9 submeniuri: File, Edit, Search, View, Project, Debug, Tools, Window şi Help.

Comenzile pot fi lansate în execuţie şi de pe liniile de pictograme poziţionate, de regulă, imediat sub meniul desfăşurător. Există 5 grupuri de pictograme: Standard, Search, Tools, Debug, şi View care reprezintă grupuri funcţionale de comenzi VLISP.

Linia de stare este plasată pe ultima linie a mediului şi afişează informaţii despre locul în care se găseşte cursorul în mediul VLISP.

Fereastra Visual LISP Console este utilizată atât pentru tastarea expresiilor simbolice AutoLISP ca şi în zona prompter-ului Command: al AutoCAD-ului, cât şi pentru afişarea mesajelor funcţiilor AutoLISP princ, print etc. Tot în această fereastră sunt afişate diverse mesaje la rularea şi depanarea programelor.

Fereastra Trace, la prima lansare a mediului, este minimizată. Aici se afişează mesaje de informare a utilizatorului asupra versiunii de Visual LISP şi eventualele erori ce apar la lansarea în execuţie a VLISP-ului. În plus, această fereastră, poate să conţină o serie de informaţii referitoare la interacţiunea mediului VLISP cu AutoCAD-ul, starea subprogramelor apelate şi starea stivei.

Fereastra Build Output conţine mesajele ce apar la: verificarea sintactică a programelor AutoLISP, compilarea fişierelor sursă, compilarea proiectelor şi compilarea aplicaţiilor independente.

1.3.1 Fereastra Visual LISP Console

În fereastra Visual LISP Console se pot introduce şi evalua expresii simbolice AutoLISP ca şi în zona prompter-ului Command: al AutoCAD-ului. Există însă câteva diferenţe între cele două ferestre. De exemplu, pentru a afla valoarea atribuită unui simbol, pe prompter-ul Command: se tastează semnul de exclamare (!) şi numele simbolului iar în fereastra Visual LISP Console se tastează direct numele simbolului. Prompter-ul ferestrei Visual LISP Console este _$.

Principalele facilităţi oferite de fereastra Visual LISP Console sunt [3]:

Page 7: Visual Lisp

Proiectare parametrizată asistată de calculator

8

evaluarea expresiilor AutoLISP şi afişarea imediat a valorilor returnate de acestea;

afişarea mesajelor la rularea programelor; introducerea expresiilor AutoLISP scrise pe mai multe linii (trecerea la

linia următoare se realizează prin apăsarea combinaţiei Ctrl-Enter); evaluarea mai multor expresii simbolice în acelaşi timp; copierea şi transferarea textelor între ferestrele de editare şi fereastra

Visual LISP Console; repetarea comenzilor anterior introduse (se tastează Tab sau Shift Tab

pentru parcurgerea într-un sens sau altul istoricul de comenzi introduse); renunţarea la textul curent introdus apăsându-se tasta ESC; apăsându-se combinaţia Shift-F10 sau butonul din dreapta mouse-ului, se

afişează meniul contextual al ferestrei Visual LISP Console care conţine comenzi specifice de editare, depanare, inspectare a simbolurilor etc.;

se poate memora activitatea desfăşurată în fereastră într-un fişier cu extensia LOG, ulterior acest fişier poate fi reîncărcat în mediu şi comenzile salvate sunt automat executate.

Page 8: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

9

CCAAPPIITTOOLLUULL 22

LLIIMMBBAAJJUULL AAUUTTOOLLIISSPP

2.1 Aspecte generale privitoare la limbajul AutoLISP AutoLISP-ul, ca parte integrantă a mediului AutoCAD, este un limbaj de programare de nivel înalt, conceput special pentru editorul AutoCAD-ului. Utilizând limbajul AutoLISP, se pot scrie macroprograme şi funcţii utilizate în aplicaţii grafice care rulează sub AutoCAD [1, 2, 3, 4, 5]. Până la AutoCAD R14, pentru editarea programelor AutoLISP se utilizau diverse editoare de texte, începând cu AutoCAD2000, pentru editarea, testarea şi depanarea programelor se utilizează mediul Visual LISP (prezentat în capitolul 1 al acestei lucrări).

Acest capitol vă familiarizează cu cunoştinţele necesare programării în AutoLISP, explică structura şi sintaxa limbajului, prezintă funcţiile predefinite ale limbajului utilizate cu precădere în domeniul proiectării mecanice parametrizate, precum şi relaţia acestuia cu mediul AutoCAD. Exemplele prezentate în acest capitol, pot fi tastate în zona prompter-ului Command: al AutoCAD-ului sau în fereastra Visual LISP Console a mediului VLISP. Aplicaţiile mai mari se tastează în ferestrele de editare ale Visual LISP-ului, se salvează pe disc şi apoi se încarcă în AutoCAD. AutoLISP-ul este o extensie standard a AutoCAD-ului, fiind disponibil de la primele versiuni de AutoCAD. Interpretorul de AutoLISP este încărcat automat la deschiderea oricărei sesiuni de lucru cu AutoCAD-ul. Este disponibil numai în editorul de desenare al AutoCAD-ului. Interpretorul aşteaptă introducerea pe prompter-ul Command: a unei expresii simbolice care apoi este evaluată. Interpretorul AutoLISP nu face diferenţiere între expresiile scrise cu caractere mici sau mari (cu excepţia şirurilor de caractere). Sistemul de calcul utilizat trebuie să permită din punct de vedere hardware instalarea şi rularea AutoCAD-ului pentru a se putea utiliza AutoLISP-ul şi în mod implicit Visual LISP-ul.

2.2 Expresii simbolice

Expresiile simbolice sunt elementele de bază ale programelor scrise în AutoLISP, ele fiind formate din obiecte AutoLISP (simboluri, liste, atomi, funcţii etc.) separate de cel puţin un spaţiu. O expresie simbolică este precizată între paranteze rotunde (orice paranteză deschisă trebuie închisă) şi are ca prim

Page 9: Visual Lisp

Proiectare parametrizată asistată de calculator

10

obiect un nume de funcţie AutoLISP. Acesta este motivul pentru care orice expresie simbolică returnează întotdeauna o valoare. Exemplu: (+ 4 5)→ 9 În momentul în care AutoCAD-ul întâlneşte o expresie simbolică (o paranteză rotundă deschisă tastată pe prompter-ul Command:), predă controlul AutoLISP-ului care evaluează expresia şi îi returnează rezultatul. Exemplu:

Fig. 2.1 Ilustrarea mecanismului de predare a controlului din

AutoCAD în AutoLISP. Un alt caracter care predă din AutoCAD, din zona prompter-ului Command:, controlul AutoLISP-ului este caracterul semn de exclamare (!), denumit şi bang. Acesta forţează evaluarea unei expresii simbolice sau evaluarea unui simbol. A doua modalitate de predare a controlului, permite interogarea (aflarea valorii atribuite) pe prompter-ul Command: a diverselor simboluri AutoLISP. Exemple: 1. Pe lângă alte simboluri predefinite, în AutoLISP există predefinit şi simbolul pi în care este memorată valoarea numărului π. Dacă se tastează pe prompter-ul Command: expresia: Command: !pi 3.14159. atunci se obţine valoarea acestuia. 2. Dacă simbolului a i-a fost atribuită valoarea 4.5 prin expresia (setq a 4.5) Command: (setq a 4.5) atunci avem: Command: !a 4.5

Command: (+ 1 2)

AutoCAD AutoLISP 3

3

(+ 1 2)

Page 10: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

11

Observaţie: În fereastra Visual LISP Console a mediului Visual LISP, valorile atribuite diverselor simboluri, se obţin prin tastarea numelui simbolului fără ca acesta să fie precedat de caracterul special semn de exclamare. Expresiile simbolice pot fi utilizate şi ca răspunsuri la cereri ale AutoCAD-ului, adică pe alte promptere decât Command: . Exemple: 1. Dacă se doreşte trasarea unui cerc cu centrul în punctul 30,30 şi de rază 2* π atunci se tastează: Command: Circle Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:30,30 Specify radius of circle or [Diameter]: (* 2 pi) 2. Dacă simbolului p1 i se atribuie o listă cu elementele 100 şi 100 prin expresia: Command: (setq p1 (list 100 100)) (100 100) atunci se poate scrie: Command: Circle Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:!p1 Specify radius of circle or [Diameter]: D Specify diameter of circle: (/ 156.41 3.12) Pe ecran se observă că a fost trasat un cerc cu centrul în punctul p1 (de coordonate 100,100) şi de un diametru rezultat în urma evaluării expresiei 156.41/3.12.

Se observă că în acest ultim exemplu au fost utilizate cele două modalităţi de predare a controlului (din AutoCAD) AutoLISP-ului.

2.3 Tipuri de date în AutoLISP În AutoLISP se întâlnesc două tipuri de date şi anume atomi şi liste. Atomii sunt date primare care respectă proprietatea de indivizibilitate, iar listele sunt date complexe care sunt compuse din atomi şi/sau liste. Spre deosebire de atomi, listele pot fi descompuse în elementele componente. Regula generală care caracterizează cele două tipuri de date este următoarea: tot ce este atom nu este listă şi invers, tot ce este listă nu este atom. În continuare se prezintă cele două tipuri de date:

atomii sunt reprezentaţi în sintaxele funcţiilor prin <atom>, pot fi: numerici reprezentaţi în sintaxe prin <nr>, sunt de două feluri:

Page 11: Visual Lisp

Proiectare parametrizată asistată de calculator

12

- întregi, sunt toate numerele care nu conţin punct zecimal; intervalul de valori utilizat de AutoLISP este -2 147 483 648 . . +2 147 483 647, exemple: 12, 137, -443; - reali, sunt reprezentate în dublă precizie cu 14 cifre semnificative exemplu 23.45, 12e34 (12*1034);

şiruri de caractere reprezentate în sintaxe prin <şir>, sunt delimitate de ghilimele, de exemplu ”AutoCAD” ”\nIntrod. Punctul P1:”;

simboluri reprezentate în sintaxe sub forma <simbol>, acestea pot fi variabile şi statice, cele variabile sunt identificatori (nume) de variabile şi funcţii, definite de programator, reprezentate prin şiruri de caractere fără ghilimele, primul caracter fiind de regulă o literă (dar nu în mod obligatoriu); cele statice desemnează funcţii AutoLISP standard (se observă că în acest limbaj de programare până şi funcţiile predefinite sunt considerate ca tip de date - atomi), de exemplu: -, +, *, /, SETQ, GETINT, ENTNEXT, etc;

nume de entităţi, acestea sunt asociate entităţilor generate în AutoCAD, sunt de forma <Entity name: xxxxxxx>, iar în sintaxe se utilizează <nume_ent>;

mulţimi de selecţie, au forma <Selection set: xxx> şi sunt de fapt colecţii de nume de entităţi (a nu fi confundate cu listele), în sintaxe se utilizează <m_sel>;

descriptori de fişier sunt de forma <df> şi sunt utilizaţi pentru gestionarea fişierelor text din AutoLISP.

listele, reprezentate în sintaxe prin <1ista>, sunt de două feluri: liste normale şi liste speciale.

Listele normale au următoarea sintaxă generală: (<elem1> <elem2> ..... <elemn>)

unde: <elem1>, <elem2>,..... <elemn> sunt elementele ce compun o listă (pot fi atomi şi/sau liste), ele trebuind să fie separate de cel puţin un spaţiu.

Reamintim că dacă pe prima poziţie a unei liste se găseşte o funcţie AutoLISP (standard sau definită de programator), atunci aceasta se numeşte expresie simbolică şi este un caz particular de listă. Exemple: (1 2 3) (a b c) (1 2 3 (4 6) 56)

(+ 90 (* 56.78 (/ 89 4.1) 23) 10) (* x y (+ z t) a b)

Există în AutoLISP şi liste speciale, denumite perechi cu punct reprezentate <pp>, au forma generală (<e1> . <e2>). Acestea, după cum se

Page 12: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

13

poate observa, conţin două elemente separate de un punct, şi sunt utilizate de regulă la reprezentarea listelor asociate entităţilor AutoCAD. Numărul de elementele al listelor se determină cu ajutorul unei funcţii specializate dar şi prin numărare. Exemple: (x y) are 2 elemente (2 atomi), (+ 10 20) are 3 elemente (3 atomi), (+ (* 45 67) (+ 34 89.0) 67) are 4 elemente (2 atomi şi 2 liste),

(+ 90 (* 56.78 (/ 89 4.1) 23) 10 (- 10.23 5.67) ) are 5 elemente (3 atomi şi 2 liste).

Este predefinit şi un simbol special, denumit nil, care este atât atom cât şi listă, fiind singurul care nu se satisface regula enunţată mai sus. Reprezentarea lui nil ca listă este ( ), adică lista vidă cu zero elemente. Prin nil se înţelege în AutoLISP fals, nimic, nul. Observaţii: 1. Numele unui identificator utilizat în AutoLISP, nu poate să conţină următoarele caractere (, ), ’, ”, ., ; şi nu poate fi format numai din caractere de tip cifră. Caracterele utilizate la scrierea identificatorilor pot fi mari sau mici deoarece limbajul nu este de tip case sensitive. 2. Dacă un întreg depăşeşte intervalul alocat (-2147483648 .. +2147483647) atunci acesta este transformat automat în real. 3. Comentariile în AutoLISP sunt scrise după caracterul ; .

2.4 Evaluarea expresiilor AutoLISP Evaluarea este mecanismul prin care AutoLISP-ul determină valoarea unui atom sau a unei expresii simbolice.

2.4.1 Evaluarea atomilor Atomii de tip întreg, real, şir de caractere şi nume de funcţii sunt evaluaţi prin valoarea lor. Spre exemplu, atomul întreg 10 va fi evaluat prin valoarea 10, atomul real 1.3 va fi evaluat prin valoarea 1.3 şi atomul de tip şir de caractere ”ACAD” va fi evaluat prin valoarea ”ACAD”. Pentru exemplificarea acestui lucru, se tastează în AutoCAD !10, !1.3, !”ACAD” iar în VLISP (în fereastra Visual LISP Console) direct atomii respectivi.

Page 13: Visual Lisp

Proiectare parametrizată asistată de calculator

14

Simbolul se evaluează prin valoarea lui curentă (ultima valoare atribuită) sau prin nil (atomul nul) în cazul în care acesta nu are atribuită o valoare. Se pot atribui valori anumitor simboluri cu ajutorul funcţiei setq sau set. Sintaxă:

(SETQ <simbol1> <expresie1> [ <simbol2> <expresie2>... ]) Această funcţie atribuie simbolurilor <simbol1>,<simbol2>, ....<simboln>, valorile rezultate în urma evaluării expresiilor simbolice <expresie1>, <expresie2>... <expresien>. Pe lângă aceste acţiuni, funcţia returnează valoarea ultimei atribuiri. Exemple: 1. Dacă în zona prompter-ului Command: se tastează expresia: (setq x 3.4 z 2 text ”AutoCAD”) atunci se atribuie variabilelor x, z şi text valorile indicate. Iar dacă în continuare se tastează în AutoCAD !x !z !text iar în VLISP (în Visual LISP Console) direct numele variabilelor respective atunci se vor obţin valorile curente ale simbolurilor x, z şi text. 2. Dacă se doreşte atribuirea unor valori rezultate în urma evaluării unor expresii simbolice atunci se poate considera următorul exemplu: (setq a (* x (+ 5 z)) b (* z pi) p1 (list a b (+ a b z)) ) în urma tastării expresiei de mai sus, a primeşte valoarea expresiei x*(5+z), b valoare a lui z* π iar p1 va fi o listă formată din trei elemente.

Simbolurile protejate la atribuire (în principal simbolurile standard, nil, T, pause şi acele simboluri protejate de utilizator în VLISP) care apar ca argumente impare la apelarea funcţiei setq, generează mesaje de genul celor din figura 2.2.

Fig. 2.2 Mesajul afişat la încercarea de atribuire a simbolului protejat pi.

Page 14: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

15

Dacă în zona prompter-ului Command: se tastează expresia (setq pi 123) atunci pe ecran apare mesajul implicit din figura 2.2 care întreabă utilizatorul dacă se introduce o buclă de întrerupere. Dacă se răspunde cu No simbolul protejat îşi modifică valoarea, iar dacă se răspunde cu Yes atunci este generată în VLISP o buclă de întrerupere (ca şi în cazul depanării programelor în VLISP). Dacă se iese din buclă cu comenzile Reset to Top Level sau Quit to Current Level atunci simbolul nu-şi modifică valoarea, iar dacă se iese cu Continue atunci simbolul îşi modifică valoarea.

Pentru a preciza ce să răspundă AutoLISP-ul (ce mesaj să afişeze) la încercarea de modificare a simbolurilor protejate, se apelează comanda Tools/ Environment Options/General Options din meniul mediului Visual LISP. De regulă utilizatorul setează afişarea unei erori. Observaţie: Pentru atribuirea valorilor se poate utiliza şi funcţia set care este prezentă la finalul prezentului subcapitol.

2.4.2 Evaluarea expresiilor simbolice (listelor) Pentru ca o listă să poată fi evaluată, trebuie ca aceasta să fie o expresie simbolică, adică primul element să fie numele unei funcţii AutoLISP. 2.4.2.1 Funcţii aritmetice predefinite În AutoLISP există o serie de funcţii matematice predefinite care permit efectuarea diverselor calcule matematice. Faţă de alte limbaje de programare, cel pe care îl prezentăm în lucrarea de faţă, tratează toate operaţiile aritmetice ca funcţii. Deci vom vorbi despre funcţia şi nu operaţia de: adunare, scădere, înmulţire, împărţire, etc. Funcţia de adunare ”+” Sintaxă:

(+ [ <nr1> ... <nrn> ]) Returnează suma tuturor simbolurilor numerice indicate ca argumente. Exemple: (+ 2 3 4)→9 (+ 2 1.0)→3.0 (+ 3)→3 (+)→0

Page 15: Visual Lisp

Proiectare parametrizată asistată de calculator

16

Se observă că dacă toate argumentele sunt întregi, atunci rezultatul este un întreg, iar dacă cel puţin un argument este un real, atunci rezultatul este un real. Dacă funcţiei nu i se indică argumente, atunci este returnată valoarea 0. Funcţia de scădere ”-” Sintaxă:

(- [ <nr1> ... <nrn> ]) Returnează diferenţa iterativă a simbolurilor numerice date ca argumente, adică din primul argument se scade suma celorlalte. Exemple: (- 10 3 4)→3 (- 2 1.0)→1.0 (- 2 )→ -2 (-)→0 Se observă că dacă toate argumentele sunt întregi, atunci rezultatul este un întreg, iar dacă cel puţin un argument este un real, atunci rezultatul este un real. Dacă funcţiei nu i se indică argumente, atunci este returnată valoarea 0. Funcţia de înmulţire ”*” Sintaxă:

(* [ <nr1> ... <nrn> ]) Funcţia returnează produsul simbolurilor de tip numeric date ca argumente. Exemple: (* 10 3 2)→60 (* 2 4.0)→8.0 (* 2)→2 Se observă că dacă toate argumentele sunt întregi, atunci rezultatul este un întreg, iar dacă cel puţin un argument este un real, atunci rezultatul este un real. Dacă funcţiei nu i se indică argumente, atunci este returnată valoarea 0. Funcţia de împărţire ”/” Sintaxă:

(/ [ <nr1> ... <nrn> ])

Page 16: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

17

Funcţia returnează împărţirea iterativă a simbolurilor numerice date ca argumente, adică se împarte primul argument la produsul celorlalte. Exemple: (/ 1 2)→0 (/ 1 2.0)→0.5 (/ 2 2 4.0)→0.25 (/ 4.0)→4.0 Se observă că dacă toate numerele sunt întregi, atunci rezultatul este întreg (împărţire întreagă), iar dacă cel puţin un argument este un real, atunci rezultatul este real (împărţire reală). Funcţia de împărţire trebuie utilizată cu atenţie deoarece pot să apară rezultate eronate (dacă toate argumentele sunt întregi, în loc de împărţire reală se efectuează o împărţire întreagă). Dacă funcţiei nu i se indică argumente, atunci este returnată valoarea 0. Funcţia 1+ Sintaxă:

(1+ <nr>) Funcţia returnează valoarea argumentului incrementată cu o unitate. Tipul rezultatului este identic cu al argumentului (întreg sau real). Exemple: (1+ 4)→5 (1+ 100.0)→101.0 Funcţia 1- Sintaxă:

(1- <nr>) Funcţia 1- returnează valoarea argumentului decrementată cu o unitate. Tipul rezultatului este identic cu al argumentului (întreg sau real). Exemple: (1- 4)→3 (1- 100.0)→99.0 Funcţia ABS Sintaxă:

(ABS <nr>)

Page 17: Visual Lisp

Proiectare parametrizată asistată de calculator

18

Funcţia abs returnează valoarea absolută (modulul) a argumentului. Tipul rezultatului este identic cu cel al argumentului. Exemple: (abs 100)→100 (abs -78.23)→78.23 Funcţia EXP Sintaxă:

(EXP <nr>) Exp returnează valoarea expresiei e la puterea <nr>, unde e este baza logaritmului natural (2.71828). Tipul rezultatului este real. Exemple: (exp 1)→2.71828 (exp -0.4)→0.67032 (exp (exp 1))→ 15.1543 ;returnează ee

Funcţia LOG Sintaxă:

(LOG <nr>) Funcţia log returnează valoarea logaritmului natural din argumentul <nr>. Rezultatul returnat este un număr real dacă argumentul este pozitiv. Exemple: (log 1.22)→0.198851 (log (exp 1))→1.0 Funcţia EXPT Sintaxă:

(EXPT <nr1> <nr2>) Funcţia returnează valoarea argumentului <nr1> la puterea <nr2>. Tipul rezultatului returnat este real dacă cel puţin un argument este real, sau întreg dacă ambele argumente sunt întregi. Exemple:

Page 18: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

19

(expt 3 2)→9 (expt 3.0 3)→27.0

(expt (exp 1) pi)→23.1407 ;returnează epi Funcţia SQRT Sintaxă:

(SQRT <nr> ) Sqrt returnează valoarea radicalului din argumentul <nr>. Tipul rezultatului returnat este întotdeauna real. Argumentul trebuie să fie pozitiv. Exemple: (sqrt 9)→3.0 (sqrt 2)→1.41421 Funcţia REM Sintaxă:

(REM [ <nr1> ... <nrn> ]) Funcţia rem returnează restul împărţirii lui <nr1> la <nr2> dacă sunt indicate două argumente. Dacă sunt date mai multe argumente, atunci se efectuează împărţirea repetată fiind returnat restul ultimei împărţiri. Tipul rezultatului returnat este real dacă cel puţin un argument este real, sau întreg dacă ambele argumente sunt întregi. În situaţia în care se indică un singur argument, rem returnează valoarea acestuia, iar dacă nu sunt date argumente se returnează 0. Exemple: (rem 9 4)→1 (rem 20 6.0)→2.0

(rem 26 7 2)→1

Funcţia FIX Sintaxă:

(FIX <nr>) Funcţia converteşte argumentul real <nr> la un întreg prin trunchiere. Dacă argumentul este întreg, funcţia returnează valoarea acestuia.

Page 19: Visual Lisp

Proiectare parametrizată asistată de calculator

20

Exemple: (fix 9.4)→9 (fix 20.6)→20 (fix 10)→10 Funcţia FLOAT Sintaxă:

(FLOAT <nr>) Float converteşte argumentul întreg <nr> la un real. Dacă argumentul este real, funcţia returnează valoarea acestuia. Exemple: (float 9)→9.0 (float 20)→20.0 (float 2.3)→2.3 Funcţia MAX Sintaxă:

(MAX [ <nr1> .... <nrn> ]) Funcţia max returnează argumentul cu valoarea cea mai mare din şirul de argumente. Dacă cel puţin un argument este real, atunci funcţia returnează o valoare de tip real, în caz contrar returnează un întreg. În situaţia în care se nu sunt indicate argumente, funcţia returnează valoarea 0. Exemple: (max -23 3 1.0 8 9)→9.0 (max 20 21 0 30)→30 (max)→0 Funcţia MIN Sintaxă:

(MIN [ <nr1> .... <nrn> ]) Funcţia min returnează argumentul cu valoarea cea mai mică din şirul de argumente. Dacă cel puţin un argument este real, atunci funcţia returnează o valoare de tip real, în caz contrar returnează o valoare întreagă. În situaţia în care se nu sunt date argumente, funcţia returnează valoarea 0.

Page 20: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

21

Exemple: (min -23 3 1.0 8 9)→-23.0 (min 20 21 0 30)→0 (min)→0 Funcţia GCD Sintaxă:

(GCD <intreg1> <intreg2>) Funcţia returnează cel mai mare divizor comun al numerelor indicate ca argumente, <intreg1>şi <intreg2>. Argumentele trebuie să fie de tip întreg, iar rezultatul este tot un întreg. Exemple: (gcd 81 57)→ 3 (gcd 12 28)→ 4 2.4.2.2 Funcţii trigonometrice predefinite Funcţia SIN Sintaxă:

(SIN <unghi>) Această funcţie returnează valoarea sinusului din argumentul <unghi> ca un număr real. Se consideră că unghiul dat ca argument funcţiei sin, se indică în radiani. Exemple: (sin (/ pi 2))→1.0 (sin (/ pi 6))→0.5 Funcţia COS Sintaxă:

(COS <unghi>) Funcţia cos returnează valoarea cosinusului de <unghi> ca un real. Se consideră că unghiul se indică în radiani. Exemple:

Page 21: Visual Lisp

Proiectare parametrizată asistată de calculator

22

(cos (/ pi 2))→0.0 (cos (/ pi 3))→0.5 Funcţia ATAN Sintaxă:

(ATAN <nr1> [ <nr2> ]) Dacă <nr2> nu este indicat ca argument, funcţia returnează valoarea arctangentei de <nr1> în radiani. Argumentul <nr1> poate să fie negativ, iar

intervalul de valori al rezultatului este −

π π2 2

, .

Exemple: (atan 0.5)→0.463648 (atan 1.0)→0.785398 (atan -1.0)→ -0.785398 Dacă ambele argumente există, funcţia returnează, în radiani, valoarea expresiei matematice atan (nr1/nr2). Dacă argumentul <nr2> are valoarea zero,

atunci rezultatul va fi ± π2

în funcţie de semnul lui <nr1>.

Exemple: (atan 2.0 3.0)→0.463648 (atan 2.0 -3.0)→2.55359 (atan -2.0 -3.0)→ -2.55359 (atan -0.5 0.0)→ -1.5708 (atan 0.5 0.0)→ 1.5708 2.4.2.3 Funcţii de gestionare a simbolurilor Funcţia QUOTE Sintaxă:

(QUOTE <expr>) Funcţia returnează argumentul <expr> neevaluat, îngheţând practic mecanismul de evaluare a expresiilor simbolice conţinute de argument. Se utilizează de regulă pentru formarea listelor cu valori iniţiale cunoscute. Există o formă abreviată a funcţiei şi anume caracterului apostrof (’ ).

Page 22: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

23

Exemple: (quote a) → a (quote (sin (/ pi 3)))→ (sin (/ pi 3)) (quote (a b c d))→ (a b c d) (quote (1 2 3))→ (1 2 3) expresiile de mai sus sunt echivalente cu: ’a → a ’(sin (/ pi 3))→ (sin (/ pi 3)) ’(a b c d)→ (a b c d) ’ (1 2 3)→ (1 2 3) Observaţie: Abrevierea funcţiei nu poate fi utilizată ca primă funcţie pe prompter-ul Command: al AutoCAD-ului deoarece aceasta nu predă controlul AutoLISP-ului, dar poate fi utilizată în VLISP (fereastra Visual LISP Console). Următorul exemplu nu este valid: Command:’(sin (/ pi 3)) şi AutoCAD-ul va furniza un mesaj de eroare, dar este corect astfel: Command: (setq ex ’(sin (/ pi 3))) iar dacă se tastează: Command:!ex → (sin (/ pi 3))) se observă că simbolul ex are atribuită valoarea neevaluată a argumentului. Observaţie: Ambele exemple de mai sus pot fi tastate în fereastra Visual LISP Console fără a fi semnalate erori. Funcţia EVAL Sintaxă:

(EVAL <expr>)

Returnează rezultatul evaluării expresiei simbolice <expr>. Exemple: Dacă se consideră următoarele atribuiri: (setq x ”AutoLisp”) (setq y ’x) (setq b ’(sqrt 4.0)) atunci sunt valide următoarele expresii simbolice:

Page 23: Visual Lisp

Proiectare parametrizată asistată de calculator

24

(eval 3.0) →3.0 (eval (sin (/ pi 6)))→ 0.5 (eval b)→ 2.0 (eval x) →”AutoLisp” (eval y) →”AutoLisp” Funcţia APPLY Sintaxă:

(APPLY ’<funcţie> <listă>) Apply aplică funcţia <funcţie> pe argumentele existente în <listă> şi returnează valoarea rezultată în urma evaluării. Exemple: (apply ’+ ’(1 2 3))→ 6 (apply ’strcat ’(”Exemplu ” ”apply”)) → ”Exemplu apply”. Apply poate fi utilizată atât pe funcţii standard cât şi pe cele definite de programator. Funcţia TYPE Sintaxă:

(TYPE <articol>) Această funcţie returnează tipul argumentului <articol>. În AutoLISP există variantele de rezultat prezentate în tabelul 2.1. Exemple: Considerându-se următoarele atribuiri: (setq i 45 r 34.3 s ”AUTOCAD” l ’(1 2 3) f (open ”DATE.TXT” ”w”) ) se obţin, aplicând TYPE pe fiecare simbol definit mai sus, următoarele rezultate: (type ’i) → SYM (type i) → INT (type r) → REAL (type s) → STR (type l) → LIST (type f) → FILE

Page 24: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

25

(type getreal) → SUBR (type nil) → nil

Tabelul 2.1 Rezultatul returnat Explicaţie

REAL pentru un argument numeric de tip real INT pentru un argument numeric de tip întreg STR pentru un argument de tip şir de caractere LIST pentru un argument de tip listă FILE pentru un argument de tip descriptor de fişier SYM pentru un simbol AutoLISP SUBR pentru o funcţie standard a AutoLISP-ului sau

definită de programator şi încărcată din fişiere FAS sau VLX sau definită de programator direct pe prompter-ul Command:

USUBR pentru o funcţie AutoLISP definită de programator sau încărcată din fişier sursă LISP (LSP)

PICKSET pentru un argument de tip mulţime de selecţie ENAME pentru un argument de tip nume de entitate

EXRXSUBR pentru aplicaţii externe ObjectARX NIL pentru un simbol evaluat prin nil (adică nu are

atribuită o valoare) Funcţia SET Sintaxă:

(SET <simbol> <expr>)

Funcţia set atribuie simbolului notat cu <simbol> valoarea prin care este evaluată expresia <expr>. Spre deosebire de setq, funcţia set acceptă ca prim argument, chiar o expresie care returnează un simbol. Exemple: (set ’x (+ 5 23 (* pi 3))) → 37.4248 (set (read ”y”) 10)→ 10

Prin tastarea expresiilor de mai sus, variabilele x şi y memorează valorile

37.4248 şi respectiv 10. Funcţia READ Sintaxă:

Page 25: Visual Lisp

Proiectare parametrizată asistată de calculator

26

(READ [ <şir> ])

Funcţia read citeşte prima dată AutoLISP (atom, listă, simbol etc) din şirul de caractere dat ca argument şi o converteşte în tipul de dată corespondent. Dacă şirul conţine spaţii atunci se preia doar prima dată (sub şirul de până la primul spaţiu) din acesta. Listele pot să conţină spaţii. Exemple:

(read "a")→A (read "b c d")→B (read "78")→78 (read "7.5")→7.5 (read "(a b c)") → (A B C) (read "Visual LISP”)→ VISUAL (set (read "a") 10) ;simbolul a va avea valoarea 10 (read "(+ (exp 3) (* pi 2))") → (+ (exp 3) (* pi 2)) (eval (read "(+ (exp 3) (* pi 2))")) → 26.3687

Funcţia ATOMS-FAMILY Sintaxă:

(ATOMS-FAMILY <format> [ <lista-simboluri> ])

Funcţia atoms-family returnează o listă cu simbolurile curent definite în AutoCAD. Argumentul <format> este un întreg şi precizează modul în care se indică lista returnată astfel: pentru valoarea 0 returnează o listă cu numele simbolurilor iar pentru valoarea 1 returnează o listă cu numele simbolurilor date ca şiruri de caractere. Argumentul opţional <lista-simboluri>, reprezintă o listă de şiruri de caractere care reprezintă simboluri ce vor fi căutate de atoms-family. Pentru simbolurile ce nu sunt găsite, în lista rezultat, va fi returnat nil. Exemple: 1. (atoms-family 0) → (VL-CONSP LISPED *MERR* VL-ACAD-DEFUN C:MVSETUP GRCLEAR _AUTOARXLOAD GETANGLE .......) 2. (atoms-family 1) → ("VL-CONSP" "LISPED" "*MERR*" "VL-ACAD-DEFUN" "C:MVSETUP" "GRCLEAR" "_AUTOARXLOAD" .....) 3. (atoms-family 1 '("getint" "getdist" "getx" "gety"))→("GETINT" "GETDIST" nil nil)

Ultimul exemplu verifică dacă simbolurile: getint, getdist, getx şi gety sunt definite. Se observă că simbolurile getx şi gety nu sunt definite deoarece în listă a fost returnată valoarea nil.

Page 26: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

27

2.5 Reprezentarea punctelor AutoCAD în AutoLISP Este cunoscut faptul că AutoCAD-ul foloseşte un sistem cartezian de coordonate pentru a descrie punctele 2D sau 3D în baza de date a desenului. Un punct 3D este o asociere de trei numere reale, fiecare corespunzând distanţei de la originea sistemului de coordonate de-a lungul axelor X,Y şi Z.

Pentru definirea unui punct 3D de coordonate 1,2,3 AutoCAD-ul permite utilizatorului să îl indice prin mai multe metode: coordonate carteziene absolute, coordonate carteziene relative, coordonate polare absolute, coordonate polare relative, moduri OSNAP, filtre etc. Reprezentarea internă (în baza de date a AutoCAD-ului) a oricărui punct, indiferent de metoda prin care a fost descris, se reduce la o asociere de trei numere reale.

AutoLISP-ul interpretează punctele AutoCAD sub forma unor liste de două numere reale dacă punctul este 2D sau trei numere reale dacă punctul este 3D, în care primul element al listei este coordonata X, al doilea este coordonata Y, iar al treilea element, dacă există, reprezintă coordonata Z. Punctul AutoCAD de coordonate 1,2,3 este exprimat în AutoLISP sub forma listei (1.0 2.0 3.0).

Fig. 2.3 Reprezentarea unui punct AutoCAD.

Fig. 2.4 Reprezentarea punctului de coordonate 1.0, 2.0, 3.0 .

Coordonata X

Coordonata Y

Coordonata Z

Coordonata X=1.0

Coordonata Y=2.0

Coordonata Z=3.0

Page 27: Visual Lisp

Proiectare parametrizată asistată de calculator

28

Listele aferente punctelor AutoCAD pot fi generate cu ajutorul funcţiei quote (prin inhibarea mecanismului de evaluare) în cazul în care coordonatele acestora rezultă prin evaluarea unor atomi numerici, sau cu ajutorul funcţiei list în cazul în care coordonatele rezultă în urma evaluării unor expresii simbolice, variabile sau atomi numerici. Funcţia LIST Sintaxă:

(LIST [ <expr1> <expr2>.....<exprn> ]) Funcţia list are ca argument una sau mai multe expresii simbolice şi returnează lista formată din valorile rezultate în urma evaluării expresiilor simbolice. List apelată fără argumente returnează nil. Exemple: (setq a 1 b 2 c 3) (list a b c)→(1 2 3) (list a ’(c d) b)→(1 (c d) 2) ’(1 2 3)⇔(list 1 2 3)

Exemple de generare a punctelor cu ajutorul funcţiei list: (setq p1 (list (+ 1 a) (+ 1 b))) →(2 3)

(setq p2 (list (+ a b c) (* 2 b c) (- a b c))) →(6 12 -4) Exemple de generare a punctelor cu ajutorul funcţiei quote:

(setq p3 ’(100 100))→(100 100) (setq p4 ’(-34 10 19)) →(-34 10 19)

Având definite punctele de mai sus, ele pot fi utilizate la trasarea unor entităţi în AutoCAD care solicită diverse puncte. 1. Exemplu pentru trasarea unei linii între punctele P2 şi P4:

Command: Line Specify first point: !p2 (6 12 -4) Specify next point or [Undo]: !p4

Fig. 2.5 Listă AutoLISP care reprezintă un punct AutoCAD.

(1.0 2.0 3.0) Punctul 3D 1,2,3 ca un obiect AutoLISP

Page 28: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

29

(-34 10 19) Specify next point or [Undo]:

2. Exemplu pentru trasarea unui cerc prin două puncte (P1 şi P3) pe diametru: Command: Circle Specify center point for circle or [3P/2P/Ttr (tan tan radius)]: 2p Specify first end point of circle's diameter: !p1 (2 3) Specify second end point of circle's diameter: !p3 (100 100)

3. Exemplu pentru trasarea unui arc de cerc prin trei puncte (P1, P2 şi P3): Command: Arc ARC Specify start point of arc or [Center]: !p1 (2 3) Specify second point of arc or [Center/End]: !p2 (6 12 -4) Specify end point of arc: !p3 (100 100)

Funcţia APPEND Sintaxă:

(APPEND [ <1ista1>...<1istan> ])

Funcţia returnează lista formată din toate elementele listelor indicate ca argumente (adaugă la elementele listei <lista1> elementele celorlalte liste date ca argument). Append apelată fără argumente returnează nil. Exemple: (setq a 10 b 20 c 30) (setq p1 (list a b c) p2 (list 40 50 60) ) (append p1 p2)→(10 20 30 40 50 60) (append ’( (x) (y)) ’((u) (v)))→ ((x) (y) (u) (v))

Page 29: Visual Lisp

Proiectare parametrizată asistată de calculator

30

2.6 Funcţii de prelucrare a listelor

O listă AutoLISP este reprezentată în memoria calculatorului sub forma unui arbore binar. Orice zonă a arborelui binar care conectează două ramuri poartă numele de nod. Nodul este una din unităţile de bază ale memoriei gestionate de AutoLISP. Vârful unui arbore binar (primul nod al acestuia) poartă denumirea de nod rădăcină. Structura unei liste poate fi descompusă nod după nod pornind de la vârful arborelui (nodul rădăcină). Fiecare nod se descompune în două ramuri reprezentând diferite părţi ale listei: primul element al listei şi restul listei cu primul element eliminat.

Fig. 2.6 Nodul rădăcină şi primele două ramuri ale unei liste oarecare.

Fig. 2.7 Nodul rădăcină şi primele două ramuri ale listei (1.0 2.0 3.0) .

Fig. 2.8 Arborele binar complet al listei (1.0 2.0 3.0) .

listă fără primul element

Nodul rădăcină

primul element al listei

(2.0 3.0)

(1.0 2.0 3.0)

1.0

(2.0 3.0)

(3.0)

1.0

2.0

( ) 3.0

(1.0 2.0 3.0)

Page 30: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

31

Fig. 2.9 Arborele binar al listei (x (y z) t) .

Fig. 2.10 Reprezentarea sub forma car/cdr şi arbore binar al unei liste cu trei atomi.

Spre exemplificare, prima ramificare a listei (1.0 2.0 3.0) se prezintă în figura 2.7. Divizarea listei continuă de-a lungul ramificaţiilor acesteia până când pe ramura din dreapta se obţine lista vidă, adică nil. În AutoLISP, cele două părţi ale unei ramificaţii poartă denumiri speciale. Prima ramură, cea din stânga, este denumită car, iar cea de-a doua (ramura din dreapta) este denumită cdr. Deci primul element al unei liste este elementul car iar lista rezultată în urma îndepărtării primului element este elementul cdr.

(cdr P1)→(y z)

(cdr (cdr P1))→(z)

(car P1)→x

(car (cdr P1))→y

(cdr (cdr (cdr P1)))→( ) lista vidă sau nil

(car (cdr (cdr P1)))→z

P1=(x y z)

(x (y z) t)

x ((y z) t)

(y z) (t)

( )t (z)

y

z ( )

Page 31: Visual Lisp

Proiectare parametrizată asistată de calculator

32

Pe ramura car se obţine un atom sau o listă, pe ramura cdr se găseşte întotdeauna o listă. Arborele binar aferent unei liste compuse din elemente de tip atomi şi liste este reprezentat în figura 2.9. Reprezentarea car şi cdr a unei liste formată din trei elemente de tip atomi, ce a fost atribuită simbolului P1, este prezentată în figura 1.9.

Există două funcţii, car şi cdr, aferente celor două ramuri ale arborelui binar, care permit extragerea elementelor ce compun o listă. Cele două funcţii sunt nedistructive, adică nu alterează elementele conţinute de lista originală. Funcţia CAR Sintaxă:

(CAR <listă>) Funcţia car returnează primul element al listei argument sau nil dacă lista este vidă. Tipul rezultatului poate fi atom sau listă. Funcţia CDR Sintaxă:

(CDR <listă>)

Această funcţie returnează, spre deosebire de funcţia car, lista rezultată prin îndepărtarea primului element al listei indicată ca argument sau nil dacă lista este vidă. În consecinţă rezultatul returnat este întotdeauna listă. Cele două funcţii prezentate mai sus se apelează de regulă repetat (de mai multe ori) în cadrul unei expresii simbolice. Având în vedere acest lucru, pentru a uşura munca programatorului, AutoLISP-ul are predefinite funcţii de forma caadr, caddr, caaddr, cdddr, etc. Aceste funcţii pot înlocui maxim patru apeluri consecutive ale funcţiilor car şi cdr. Exemple: Pentru un punct AutoCAD cu trei coordonate (x y z) definit astfel: (setq x 1 y 2 z 3) (setq p (list x y z))

coordonatele se obţin cu următoarele expresiile simbolice:

(car p)→ 1 ;se obţine coordonata x (car (cdr p))→ 2 ;identic cu expresia (cadr p), se obţine coordonata y (car(cdr(cdr p)))→ 3 ;identic cu expresia (caddr p),se obţine coordonata z

Page 32: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

33

Observaţie: Expresiile (car ’( )) (cdr ’( )) returnează atomul nil. Funcţia LAST Sintaxă:

(LAST <listă>) Funcţia returnează ultimul element al listei argument. Argumentul trebuie să fie diferit de nil iar rezultatul poate fi atom sau listă. Exemple: (last ’(a b c))→c (last ’(a b c (d e f)))→(d e f) Observaţie: Funcţia last pare a fi uşor de utilizat în aflarea ultimei coordonate a unui punct AutoCAD dar, în realitate nu se cunoaşte dacă punctul este reprezentat 2D sau 3D. În concluzie pentru aflarea acesteia, se vor utiliza funcţiile car şi cdr sau funcţiile abreviere ale combinaţiilor acestora. Funcţia LENGTH Sintaxă:

(LENGTH <listă>) Această funcţie returnează un întreg care indică numărul de elemente conţinute de argumentul <listă>. Exemple: (length ’(a b c))→3 (length ’(a b c (d e f)))→4 (length ’( ))→0 Funcţia MEMBER Sintaxă:

(MEMBER <expr> <listă >)

Member caută în argumentul <lista> elementul <expr>; dacă îl găseşte returnează lista formată din elementele plasate după <expr> (inclusiv <expr>). Dacă <expr> nu apare în listă atunci funcţia returnează nil. Exemple:

Page 33: Visual Lisp

Proiectare parametrizată asistată de calculator

34

(member ’c ’(a b c d e)) →(c d e) (member ’p ’(a b c d))→ nil Funcţia NTH Sintaxă:

(NTH <n> <listă>) Funcţia nth returnează elementul de pe poziţia n (n+1 pentru utilizator) din cadrul listei prezente în apelul funcţiei. Numerotarea elementelor se face de la zero, iar dacă <n> este mai mare decât poziţia ultimului element al listei argument, atunci funcţia returnează nil. Rezultatul obţinut este de tip atom sau listă. Exemple: (nth 2 ’(a b c d))→c (nth 0 ’(a b c d ))→a (nth 4 ’(a b c d ))→nil Funcţia REVERSE Sintaxă:

(REVERSE <listă>) Reverse returnează o listă rezultată prin inversarea elementelor argumentului <listă>. Exemple: (reverse ’(a b c d))→(d c b a) (reverse ’((a b) (c d )))→((c d) (a b)) Funcţia SUBST Sintaxă:

(SUBST <e-nou> <e-vechi> <1istă>) Funcţia subst caută în listă apariţia elementului <e-vechi> şi returnează o copie a listei argument cu toate apariţiile lui <e-vechi> substituite cu <e-nou>. Dacă <e-vechi> nu este conţinut de listă, atunci subst returnează lista iniţială neschimbată. Exemple:

Page 34: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

35

(subst 5 1 ’(1 3 5 1 1))→ (5 3 5 5 5) (subst ’b ’a ’(a b c d))→(b b c d) (subst ’a ’t ’(a b c d ))→(a b c d)

AutoLISP-ul este un limbaj de programare care nu alterează originalul. Dacă se consideră următoarele expresii:

(setq note ’(4 7 4 5)) (subst 5 4 note) →(5 7 5 5) atunci se observă că variabila note nu se modifică dar, funcţia subst returnează o listă derivată din elementele conţinute note. Observaţie: Această funcţie se utilizează de regulă, în paralel cu assoc, la prelucrarea listelor asociate entităţilor pentru substituirea listelor sau perechilor cu punct identificate prin chei DXF. Funcţia MAPCAR Sintaxă:

(MAPCAR ’<funcţie> <listă1> <listă2>......<listăn>) Funcţia returnează o listă ca rezultat al evaluării argumentelor <listă1>, <listă2> ...... <listăn> pe care se aplică funcţia <funcţie>. Numărul de argumente de tip listă depinde de natura funcţiei notată cu <funcţie>. Exemple: (mapcar ’+ ’(1 2 3) ’(10 20 30))→ (11 22 33) (setq a 1 b 2 c 3) (mapcar ’1+ (list a b c)) → (2 3 4) Ultima expresie este echivalentă cu expresiile:

(1+ a) (1+ b) (1+ c)

Mapcar poate fi utilizată atât pe funcţii standard cât şi pe cele definite de programator.

Page 35: Visual Lisp

Proiectare parametrizată asistată de calculator

36

2.7 Apelarea comenzilor AutoCAD din AutoLISP Una dintre cele mai importante facilităţi ale AutoLISP-ului constă în faptul că acesta permite apelarea comenzilor AutoCAD în mod direct. Se pot utiliza expresii simbolice ca răspuns la opţiunile comenzilor. Aceste acţiuni pot fi realizate prin intermediul funcţiei predefinite command. Funcţia COMMAND Sintaxă:

(COMMAND [ <argumente> ])

Funcţia command este cea care apelează o comandă AutoCAD dintr-un program AutoLISP şi întotdeauna returnează nil. Ea fiind mijlocul principal de acces din AutoLISP la desenele AutoCAD. Argumentele funcţiei, notate prin <argumente> pot fi:

şiruri de caractere care desemnează comenzi AutoCAD, opţiuni ale unor comenzi, numere reale şi puncte exprimate ca în zona prompter-ului Command: al AutoCAD-ului (se pot indica punctele prin orice modalitate cunoscută în AutoCAD); numere reale sau întregi necesare ca răspuns la anumite opţiuni ale comenzilor AutoCAD; simboluri AutoLISP prin a căror evaluare se obţin valori utilizate ca răspuns la opţiunile comenzilor apelate; expresii simbolice prin a căror evaluare se obţin şiruri de caractere, puncte, reali etc; şirul vid (””) care este echivalentul tastei enter din AutoCAD, apăsată fără a fi precedată de alte date; simbolul special PAUSE, care suspendă temporar comanda AutoLISP şi permite introducerea datelor direct de către utilizator, interactiv în AutoCAD; funcţia apelată fără argumente permite renunţarea la orice comandă AutoCAD, este echivalentă cu apăsarea tastei Esc.

În cazul funcţiei command interesează efectul obţinut, deci nu valoarea returnată de aceasta. Principalul efect al funcţiei este acela de modificare a stării desenului curent. Observaţie: Funcţia command, evaluează fiecare argument pe care îl transmite apoi AutoCAD-ului ca răspuns la prompter-ele succesive pe care acesta le afişează în zona Command:.

Page 36: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

37

Exemple: 1. (command ”line” ”20,20” ”30,30” ”@45<-10” ”c”)

;trasează un triunghi care are definite colţurile ca şi în AutoCAD 2. (setq p1 ’(1 4) p2 ’(23 56)

raza 10) ;se definesc variabilele p1, p2 şi raza (command ”line” p1 p2 ””

”circle” ”2p” p1 p2 ”circle” p2 raza) ;se trasează o linie din p1 până în p2

;un cerc prin 2 puncte p1 şi p2 ;un cerc cu centrul în p2 şi de rază raza

3. (command ”line” ’(1 2 3) ’(30 4 22) ””) ;trasează o linie în spaţiu 4. (command ”line” pause pause pause ”c”)

;trasează un triunghi, pentru fiecare colţ se solicită un punct în AutoCAD (command ”circle” pause 23)

;trasează un cerc de centru dat în AutoCAD şi de rază 23. 5. Pentru a obţine modelul 3D din figura 2.11, se trasează o polilinie plana (cu punct de start 50,50 şi de dimensiuni 100x50) cu colţuri rotunjite (rază 10) care apoi se extrudează cu tapper angle 0. În final se setează direcţia de privire 1,1,1 şi apoi se ascund liniile invizibile aferente modelului 3D generat. (command "pline" "50,50" "@100,0" "@0,50" "@-100,0" "c" )

; trasează polilinia (command "fillet" "t" "t" "r" 10 ;setează raza de racordare şi

"fillet" "p" "l") ;racordează polilinia (command "extrude" "l" "" 75 "") ;extrudează polilinia (command "vpoint" "1,1,1") ;setează direcţia de privire (command "hide") ;ascunde liniile invizibile

Fig. 2.11 Model 3D generat cu AutoLISP-ul.

Page 37: Visual Lisp

Proiectare parametrizată asistată de calculator

38

6. Pentru a obţine modelul 3D din figura 2.12 parametrizat cu simboluri (în care sunt memorate date constante) se generează o polilinie plană cu colţuri rotunjite care se extrudează cu tapper angle care poate fi diferit de 0. În final se setează direcţia de privire 1,1,1 şi apoi ascund liniile invizibile aferente modelului 3D generat. Modelul este generat cu parametrii: lx - lungimea pe x, ly - lungimea pe y, lz - lungimea pe z, r - raza de racordare a poliliniei, u – unghiul de extrudare, p1- punctul de bază al modelului, p3 - punct plasat pe diagonală faţă de p1, p2 şi p4 - puncte plasate pe cealaltă diagonală a poliliniei.

Fig. 2.12 Model 3D parametrizat din AutoLISP.

(setq lx 100 ly 50 lz 75 r 10 u 5 p1 '(50 50) ) ;setare valori parametrii de intrare (setq p3 (list (+ (car p1) lx) (+ (cadr p1) ly)) p2 (list (car p3) (cadr p1)) p4 (list (car p1) (cadr p3)) ) ;calcul puncte caracteristice (command "pline" p1 p2 p3 p4 "c") ;trasează polilinia (command "fillet" "t" "t" "r" r

Page 38: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

39

"fillet" "p" "l") ;setează raza şi racordează polilinia (command "extrude" "l" "" lz u) ;extrudează polilinia (command "vpoint" "1,1,1") ;setează direcţia de privire (command "hide") ;ascunde liniile invizibile

Comenzile lansate în execuţie cu ajutorul funcţiei command, nu sunt afişate pe ecran dacă variabila de sistem AutoCAD CMDECHO (care poate fi accesată prin intermediul funcţiilor setvar şi getvar sau a comenzii AutoCAD SETVAR) este setată pe valoarea zero. Pentru anularea modurilor OSNAP, existente în desenul curent, se pe setează (tot din program) pe valoarea zero variabila OSMODE. Observaţii: 1. Începând cu AutoCAD2002, funcţiile din categoria getxxx pot fi apelate din interiorul funcţiei command. De exemplu: (setvar ”cmdecho” 0) (command ”line”

(setq p1 (getpoint ”\nPunct de start:”)) (setq p2 (getpoint p1 ”\nPunct de final:”)) ””

) 2. O comandă AutoCAD lansată din AutoLISP cu o funcţia command:, poate fi încheiată ulterior cu o altă funcţie command: . De exemplu: (setq pc ’(100 100)) (command ”circle” pc) (setq dia 32.345) (command ”d” dia)

Toate versiunile de AutoCAD acceptă nume de comenzi şi opţiuni în limba engleză, indiferent de versiunea lingvistică disponibilă. Această facilitate permite programatorilor să scrie programe portabile, ce pot fi utilizate în cadrul tuturor versiunilor de AutoCAD, indiferent de limba utilizată, fără a traduce comenzile folosite în cadrul funcţiei command. Pentru a utiliza versiunea în limba engleză a comenzilor şi opţiunilor acestea vor fi precedate de liniuţa de subliniere (”_”) sau de punct liniuţă de subliniere (”._”). În cel de-al doilea caz (”._”) sunt evitate chiar şi redefinirile de comenzi AutoCAD. De exemplu modul în care se apelează comanda LINE în orice versiune lingvistică de AutoCAD este ”._LINE”.

Page 39: Visual Lisp

Proiectare parametrizată asistată de calculator

40

2.8 Funcţii pentru introducerea datelor AutoLISP-ul pune la dispoziţia programatorilor un set de funcţii care întrerup evaluarea unei expresii simbolice şi permit introducerea interactivă a unor date, utilizând metode standard din AutoCAD. Funcţiile din această categorie sunt de forma GETXXX. Majoritatea utilizează un mesaj (şir de caractere) care este afişat înainte de preluarea datei. Acesta poate să conţină următoarele caractere speciale: \n pentru linie nouă (new-line); \e pentru escape; \r pentru return; \t pentru tab; \” pentru caracterul ghilimele (”), în interiorul mesajului; \\ pentru caracterul backslash (\), în interiorul mesajului; \nnn pentru caracterul al cărui cod octal (în baza 8 de numeraţie) este nnn. Observaţie: Caracterele speciale vor fi scrise în mesaje cu caractere mici. Funcţia GETINT Sintaxă:

(GETINT [ <mesaj> ]) Această funcţie aşteaptă introducerea de la tastatură a unei valori întregi, şi returnează valoarea citită. Valorile citite trebuie să se încadreze în intervalul -32768..32767. Argumentul <mesaj> este opţional şi este afişat pe ecran în momentul cererii de introducere a datei. Funcţia nu acceptă să fie introdus de la tastatură, ca răspuns, decât un întreg, în caz contrar afişează pe ecran mesajul Requires an integer value. Exemple: (setq J (getint)) (setq I (getint ”\nIntroduceţi întregul I=”)) ;se afişează în zona prompter-ului Command: mesajul indicat, permiţând introducerea unui întreg de la tastatură şi atribuirea acestuia simbolului I. Funcţia GETREAL Sintaxă:

(GETREAL [ <mesaj> ]) Funcţia getreal permite introducerea de la tastatură a unei valori reale şi returnează valoarea citită. Mesajul este opţional, fiind afişat pe ecran în momentul în care trebuie introdus numărul real.

Page 40: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

41

Funcţia nu acceptă să fie introdus de la tastatură, ca răspuns, decât un întreg sau un real, în caz contrar afişează pe ecran mesajul Requires numeric value. Exemple: (setq r1 (getreal)) (setq r2 (getreal ” \nIntroduceţi raza:”)) Funcţia GETSTRING Sintaxă:

(GETSTRING [ <ind> ] [ <mesaj> ]) Funcţia getstring permite citirea de la tastatură a unui şir de caractere, şi returnează valoarea. Dacă şirul este mai mare decât 132 de caractere atunci sunt returnate numai primele 132 de caractere ale şirului. Dacă în şir apare caracterul backslash (\) atunci acesta este convertit în două caractere de acelaşi fel (\\). Acest lucru este foarte util la indicarea căilor şi a numelor de fişiere. În sintaxa generală a funcţiei, apar doi parametrii opţionali <mesaj> şi <ind>. Dacă <ind> apare şi este diferit de nil, atunci şirul introdus poate să conţină spaţii; şirul va fi preluat în momentul apăsării tastei enter. Argumentul <mesaj> este un şir de caractere opţional şi este afişat ca prompter. Exemple: (setq nume (getstring ”\nIntroduceţi numele:”)) (setq numep (getstring T ”\nIntroduceţi numele şi prenumele:”))

(setq s (getstring T "\nIntroduceţi numele fişierului: ")) Funcţia GETPOINT Sintaxă:

(GETPOINT [ <pb> ] [ <mesaj> ]) Această funcţie permite citirea unui punct introdus printr-una din metodele cunoscute în AutoCAD (de la tastară-coordonate absolute/relative carteziene sau polare, punctare cu mouse-ul, moduri osnap, filtre) şi returnează valoarea citită sub formă de listă. Punctul citit poate fi unul 2D sau 3D dar el va fi întotdeauna returnat ca punct 3D în UCS-ul curent. Mesajul este opţional şi dacă el există atunci este afişat în zona prompter-ului Command: la citirea punctului. Parametrul opţional <pb> este un punct de bază reprezentat în UCS-ul curent ca punct 2D sau 3D. Dacă este indicat se desenează o linie elastică (rubber-band) din acest punct până în punctul de intersecţie al firelor reticulare (cursorului grafic).

Page 41: Visual Lisp

Proiectare parametrizată asistată de calculator

42

Exemple: (setq p (getpoint)) (setq p1 (getpoint ”\nIntroduceţi punctul P1:”)) (setq p2 (getpoint p1 ”\nIntroduceţi punctul P2:”)) Funcţia GETCORNER Sintaxă:

(GETCORNER <pb> [ <mesaj> ])

Funcţia getcorner, ca şi getpoint, citeşte şi returnează un punct în UCS-ul curent. Întotdeauna getcorner, care necesită un punct de bază ca argument, generează un dreptunghi elastic cu primul colţ în <pb> şi un al doilea colţ în punctul de intersecţie al firelor reticulare. Punctul de bază este exprimat conform cu UCS-ul curent şi dacă el este indicat ca punct 3D, atunci coordonata Z este ignorată fiind considerată egală cu elevaţia curentă. Exemplu: (setq p3 (getcorner p2 ”\nIntroduceţi punctul P3:”)) Funcţia GETDIST Sintaxă:

(GETDIST [ <pb> ] [ <mesaj> ])

Funcţia permite utilizatorului să introducă un număr real, un punct sau două puncte. Dacă se indică două puncte sau punct de bază la apelarea funcţiei şi un al doilea punct, atunci Getdist returnează un număr real care este calculat ca distanţă dintre puncte. Se poate specifica o distanţă introducând un real în formatul curent al unităţilor, iar rezultatul returnat este unul de tip real chiar dacă realul a fost indicat de exemplu în inches. Dacă parametrii opţionali <pb> (punctul de bază) şi <mesaj> există, atunci utilizatorul va trebui să indice, la afişarea mesajului, fie un real, fie cel de al doilea punct. Între punctul de bază <pb> şi intersecţia firelor reticulare se trasează vector elastic (rubber-band). Dacă parametrul opţional <pb> lipseşte şi se doreşte definirea realului ca distanţă între două puncte, atunci mesajul este afişat la cererea primului punct, pentru al doilea punct va fi generat automat mesajul ”Second point:”. Punctul de bază este exprimat în UCS-ul curent şi dacă el este indicat ca punct 3D, atunci distanţa este calculată ca distanţă 3D. Dar, dacă anterior a fost apelată funcţia initget cu bitul 64 setat, atunci getdist va ignora coordonata Z la calculul distanţei, obţinându-se în acest caz distanţa 2D.

Page 42: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

43

Exemple: (setq d (getdist)) (setq d1 (getdist p2 ”\nIntroduceţi raza cercului:”)) (setq d2 (getdist p2)) (setq d3 (getdist ”\nIntroduceţi raza cercului:”)) Funcţia GETANGLE Sintaxă:

(GETANGLE [ <pb> ] [ <mesaj> ])

Funcţia permite citirea (introducerea) unui unghi de la tastatură sau dat cu ajutorul mouse-ului şi returnează valoarea citită. Unghiul introdus de la tastatură va fi indicat în formatul curent de reprezentare a unghiurilor, iar unghiul returnat este exprimat în radiani respectând planul de construcţie curent (planul XOY al UCS-ului curent). Această funcţie returnează întotdeauna unghiul în radiani chiar dacă în AutoCAD unităţile curente pentru unghiuri nu sunt radiani. Getangle ţine cont de direcţia curentă a unghiului de zero şi sensul pozitiv curent de măsurare a unghiurilor. Argumentul <mesaj> este un şir de caractere opţional care este afişat la preluarea unghiului, iar <pb> este un punct de bază reprezentat ca punct 2D în UCS-ul curent. Dacă punctul de bază lipseşte atunci se pot preciza două puncte, trasându-se linie elastică între puncte. Exemple: (setq unghi1 (getangle)) (setq unghi2 (getangle ”\nIntroduceti unghiul 2:”)) (setq p1 (getpoint ”\nIntroduceti punctul P1:”)) (setq unghi3 (getangle p1 ”\nIntroduceti unghiul 3:”)) Funcţia GETORIENT Sintaxă:

(GETORIENT [ <pb> ] [ <mesaj> ])

Funcţia getorient lucrează ca şi getangle, dar nu ţine cont de direcţia curentă a unghiului de zero, unghiul va rezulta prin calculul relativ la direcţia unghiului de 0 standard (ora 3 sau Est) şi sensul trigonometric de măsurare a unghiului. Funcţia GETVAR Sintaxă:

(GETVAR <nume_variabilă>)

Page 43: Visual Lisp

Proiectare parametrizată asistată de calculator

44

Returnează valoarea unei variabile de sistem AutoCAD, indicată ca argument sub forma unui şir de caractere. Exemple: (getvar ”DIMASZ”)→ 3 (getvar ”CMDECHO”)→ 1 Funcţia SETVAR Sintaxă:

(SETVAR <nume_variabilă> <valoare>)

Setează variabila de sistem AutoCAD indicată prin nume, ca un şir de caractere, la valoarea dată ca argument. Exemple: (setvar ”DIMASZ” 5)→ 5 (setvar ”CMDECHO” old_cmdecho)→0 Funcţia GETENV Sintaxă:

(GETENV <nume_variabilă>) Funcţia returnează setarea curentă a unei variabile ambientale (de sistem de operare) sub forma unui şir de caractere. Argumentul funcţiei este de asemenea un şir de caractere. Exemple: (getenv ”ACAD”) → ”/acad/support” (getenv ”INEXSIT”) → nil Funcţia INITGET Sintaxă:

(INITGET [ <mod> ] [ <cuvinte_cheie> ])

Această funcţie stabileşte diverse opţiuni pentru funcţiile getxxx (exceptând funcţiile getstring şi getvar) limitând valorile introduse de utilizator. Initget returnează întotdeauna nil şi este valabilă numai pentru următoarea funcţie din categoria getxxx. Argumentul opţional <mod> poate să aibă următoarele valori întregi: 1 = nu permite introducerea nulă (enter), forţând introducerea unei valori valide;

Page 44: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

45

2 = nu permite introducerea valorii egale cu zero; 4 = nu permite introducerea valorilor negative; 8 = nu verifică limitele, chiar dacă sunt setate pe ”on”; 16= nu este utilizat; 32= utilizează linii punctate pentru rubber-band; 64= ignoră coordonata Z pentru puncte 3D (numai pentru getdist). Observaţie: Pentru argumentul <mod> se pot utiliza valori cumulate, cum ar fi 3 (rezultată din 1+2), 7 (rezultată din 1+2+4) etc. Efectul obţinut în acest caz, va însuma efectele modurilor de bază. Dacă utilizatorul nu introduce valori conforme cu modurile date de programator cu ajutorul funcţiei initget, atunci primeşte mesaje de avertizare pe ecran, putând reintroduce valori corecte. De exemplu, raza unui cerc nu trebuie să fie negativă sau zero. Utilizatorul nu trebuie lăsat să iasă din funcţia getreal cu apăsarea numai a tastei enter, deoarece în acest caz, funcţia returnează nil şi nu poate fi acceptată această valoare ca rază. În acest caz expresiile simbolice sunt: (initget (+ 1 2 4)) (setq raza (getreal ”\nIntroduceti raza cercului:”)) sau (setq p1 (getpoint ”\nIntroduceti centrul cercului:”)) (initget (+ 1 2 4)) (setq raza (getdist p1 ”\nIntroduceti raza cercului:”)) Valorile modurilor din sintaxa lui initget, acţionează pe funcţiile AutoLISP conform tabelului 2.2.

Tabelul 2.2 Funcţia Modurile funcţiei INITGET

1 2 4 8 32 64 GETINT

GETREAL GETDIST

GETANGLE GETORIENT GETPOINT

GETCORNER GETKWORD GETSTRING

GETVAR Argumentul opţional <cuvinte_cheie> este reprezentat sub forma unui şir de caractere în care cuvintele cheie sunt separate de spaţii. Forma generală este:

Page 45: Visual Lisp

Proiectare parametrizată asistată de calculator

46

”cheie1 [ ,ABREV1 ] cheie2 [ ,ABREV2 ] ..... cheien [ ,ABREVN ]” în care parametrii opţionali ABREV1 , ABREV2 , ......... ABREVN reprezintă abrevierile cuvintelor cheie (acestea vor fi scrise cu majuscule). O altă modalitate de precizare a abrevierilor constă în scrierea acestora cu majuscule în cuvântul cheie (restul caracterelor vor fi minuscule). Cuvintele cheie sunt citite cu ajutorul funcţiei getkword. Următoarele exemple prezintă cele două modalităţi de indicare a cuvintelor cheie: ”LType LAyer eXit” ”LTYPE,LT LAYER,LA EXIT,X” Utilizatorul poate să tasteze pentru primul cuvânt cheie ltype, ltyp, lty sau lt, dar l este insuficient deoarece există confuzie cu cheia layer. În acest ultim caz, sistemul va solicita din nou un răspuns corect deoarece anteriorul a fost ambiguu. Pentru ultimul cuvânt cheie se tastează doar x. Observaţii: 1. Modurile şi cuvintele cheie stabilite de funcţia initget sunt valabile numai pentru următoarea funcţie getxxx după care acestea sunt automat anulate. Dacă se doreşte activarea aceloraşi moduri şi cuvinte cheie, trebuie repetată expresia simbolică aferentă. 2. Cuvintele cheie se utilizează de regulă atunci când se doreşte selectarea unei opţiuni dintr-o listă de variante posibile. Funcţia GETKWORD Sintaxă:

(GETKWORD [ <mesaj> ])

Funcţia getkword este utilizată pentru introducerea de la tastatură a unui cuvânt cheie şi returnează cuvântul citit sub forma unui şir de caractere. Răspunsul nul, rezultat în urma apăsării doar a tastei enter, are ca efect returnarea atomului nil. Tot nil este returnat şi în cazul în care nu este stabilită lista de cuvinte cheie prin apelul funcţiei initget. Dacă nu se introduce un cuvânt cheie valid, funcţia afişează mesajul Invalid option keyword. Exemple:

1. (initget 1 ”DA,D NU,N”) ;setează cuvintele cheie Da şi Nu fără a permite apăsarea numai a tastei Enter

(setq optiune (getkword ”\nContinuaţi? Da/Nu:”)) ;citeşte unul din cuvintele cheie stabilite anterior 2. (initget 1 ”LType LAyer eXit”)

Page 46: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

47

;setează cuvintele cheie LType, LAyer şi eXit fără a permite apăsarea ;numai a tastei Enter

(setq optiune (getkword ”\Optiune LType/ LAyer/eXit :”)) ;citeşte unul din cuvintele cheie stabilite anterior

3. (initget ”LType LAyer eXit”) ;setează cuvintele cheie LType, LAyer şi eXit

(setq optiune (getkword ”\Optiune LType/ LAyer/<eXit> :”)) ;citeşte unul din cuvintele cheie stabilite anterior sau nil

(if (not optiune) (setq optiune ”eXit”)) ;dacă opţiunea este nil atunci s-a ales opţiunea implicită care este eXit Observaţie: Ultimul exemplu prezintă care sunt expresiile simbolice ce realizează preluarea unei opţiuni implicite.

Exemplu de parametrizare cu variabile: Următoarea secvenţă de program

generează modelul 3D din figura 2.12 parametrizat cu simboluri variabile. Semnificaţia simbolurilor este aceeaşi ca şi în exemplul de la subcapitolul 2.7.

(initget 1) ; nu permite introducere nulă (apăsarea doar a tastei enter) (setq p1 (getpoint "\nPunctul de baza P1:")) ;citeşte punctul de bază (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq lx (getdist p1 "\n Cota lx:")) ; citeşte cota lx (lungimea pe axa x) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq ly (getdist p1 "\n Cota ly:")) ;citeşte cota ly (lungimea pe axa y) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq lz (getdist p1 "\n Cota lz:")) ;citeşte cota lz (lungimea pe axa z) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq r (getdist p1 "\n Raza r:") u (getangle p1 "\n Unghiul de extrudare u:") u (/(* 180 u) pi) ) ;citeşte raza de racordare, unghiul de extrudare şi îl converteşte în grade (setq p3 (list (+ (car p1) lx) (+ (cadr p1) ly)) p2 (list (car p3) (cadr p1)) p4 (list (car p1) (cadr p3)) ); se calculează punctele caracteristice poliliniei

Page 47: Visual Lisp

Proiectare parametrizată asistată de calculator

48

(command "pline" p1 p2 p3 p4 "c") ; se trasează polilinia (command "fillet" "t" "t" "r" r "fillet" "p" "l") ;se setează raza de racordare şi apoi se racordează polilinia (command "extrude" "l" "" lz u) ; se extrudează polilinia (command "vpoint" "1,1,1") ;se setează convenabil direcţia de privire (command "hide") ;se ascund liniile invizibile

2.9 Funcţii de calcul geometric

Funcţiile din această categorie sunt utilizate pentru calcularea anumitor parametri din cadrul unui desen parametrizat, necesari la adăugarea ulterioară a unor noi entităţi. Funcţia DISTANCE Sintaxă:

(DISTANCE <pct1> <pct2>)

Această funcţie returnează distanţa 3D dintre punctele <pct1> şi <pct2>. Exemplu: (setq P1 (getpoint ”\nIntroduceţi P1:”) P2 (getpoint ”\nIntroduceţi P2:”) ) (setq d (distance p1 p2)) Dacă unul din cele două puncte are două coordonate (este un punct 2D) atunci funcţia distance returnează distanţa 2D dintre cele două puncte altfel returnează distanţa 3D. Funcţia INTERS Sintaxă:

(INTERS <pct1> < pct2> <pct3> <pct4> [ <ind> ])

Funcţia inters examinează dacă două linii, determinate de câte două perechi de puncte, se intersectează şi returnează punctul de intersecţie sau nil

Page 48: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

49

dacă ele nu se intersectează. Argumentele <pct1> şi <pct2> sunt punctele ce delimitează primul segment, iar <pct3> şi <pct4> cel de al doilea segment. Toate punctele sunt exprimate relativ la UCS-ul curent. Dacă ele sunt puncte 3D atunci se returnează intersecţia 3D iar dacă un punct este 2D atunci liniile sunt proiectate în planul curent de lucru şi se va returna intersecţia 2D. Parametrul opţional <ind> dacă există şi este nil atunci liniile definite de cele 4 puncte sunt considerate de lungime infinită (drepte). Exemple: (setq p1 ’(1.0 1.0) p2 ’(9.0 9.0)) (setq p3 ’(4.0 1.0) p4 ’(4.0 2.0)) (inters p1 p2 p3 p4)→ nil (inters p1 p2 p3 p4 nil)→ (4.0 4.0) Funcţia OSNAP Sintaxă:

(OSNAP <pct> <mod>)

Funcţia osnap returnează un punct 3D în urma aplicării modurilor osnap, indicate în argumentul <mod> sub forma unui şir de caractere, pe o entitate care trece prin punctul <pct>. În argumentul <mod> se indică între ghilimele, eventual separate de virgulă unul sau mai multe moduri OSNAP. Dacă punctul <pct> nu este plasat pe o entitate atunci funcţia osnap returnează nil. Exemple: (setq p1 (getpoint ”\nIntroduceti un punct de pe o entitate:”)) (setq p2 (osnap p1 ”mid”)) (setq p4 (osnap p1 ”mid, end, centre”)) Funcţia POLAR Sintaxă:

(POLAR <pct> <unghi> <distanta>)

Polar returnează un punct dispus la un anumit <unghi> şi <distanţă> faţă de punctul <pct>. Unghiul este dat în radiani şi este măsurat în sens trigonometric faţă de axa OX a UCS-ului curent. Chiar dacă <pct> este un punct 3D, întotdeauna este respectat planul de construcţie curent. Exemplu:

Page 49: Visual Lisp

Proiectare parametrizată asistată de calculator

50

(polar ’(1 1 3.5) 0.783398 1.414214) → (2.0 2.0 3.5) Funcţia ANGLE Sintaxă:

(ANGLE <pct1> <pct2>)

Angle returnează unghiul format de linia determinată de punctele <pct1> şi <pct2> din planul de construcţie cu axa OX a UCS-ului curent. Unghiul este returnat în radiani şi este măsurat în sens trigonometric. Dacă punctele sunt reprezentate cu 3 coordonate, atunci acestea sunt proiectate în planul XOY al UCS-ului curent. Exemple: (angle ’(1.0 1.0) ’(1.0 4.0)) → 1.5708 (angle ’(6.0 2.3) ’(2.0 2.3))→ 3.14159

2.10 Definirea noilor funcţii AutoLISP În AutoLISP, spre deosebire de alte limbaje de programare, programatorii pot defini numai subprograme de tip funcţie. Noile funcţii definite completează setul de subrutine (funcţii) predefinite. Acestea pot fi definite cu ajutorul funcţiei defun (DEfine FUNction). Funcţia DEFUN Sintaxă:

(DEFUN <nume_functie> ([ pf1 ...pfn ] [/ pl1 ...p1k ]) <expr1>

[ <expr2> .....

<exprm> ] ) În sintaxa funcţiei defun apar următoarele elemente:

<nume_functie> identifică numele funcţiei definite; pf1 ... pfn reprezintă lista parametrilor formali; pl1 ... plk este lista parametrilor locali; <expr1> ... <exprm> sunt expresii simbolice care formează corpul funcţiei.

Page 50: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

51

După cum se poate observa, sintaxa lui defun este puţin diferită de a celorlalte funcţii prezentate până acum. Funcţia are două argumente obligatorii (numele funcţiei şi o expresie simbolică care este corpul funcţiei) şi trei argumente opţionale (lista de parametrii formali, lista de parametrii locali şi cele m-1 expresii simbolice din corpul funcţiei). În cazul în care lipsesc atât parametrii locali cât şi cei formali atunci se va indica lista vidă ( ) în locul lor. Defun returnează întotdeauna numele funcţiei definite. Se observă că parametrii formali sunt separaţi de cei locali prin intermediul caracterului slash (/). Foarte important de reţinut este faptul că înainte şi după slash se lasă cel puţin un spaţiu, în caz contrar, toţi parametrii din listă vor fi consideraţi ca fiind formali. Privitor la numele funcţiei, este important de reţinut că acesta trebuie să fie diferit de numele funcţiilor şi a simbolurilor predefinite, deoarece în acest fel se evită modificarea semnificaţiilor iniţiale a subrutinelor standard. În cazul modificării, acestea rămân inaccesibile până la reiniţializarea AutoLISP-ului, de exemplu începerea unui nou desen. O funcţie definită de programator se apelează ca oricare altă funcţie AutoLISP şi anume:

(nume_functie pa1 ... pan)

în care pa1 ... pan sunt parametri actuali. Legătura dintre parametrii actuali şi cei formali se realizează prin locul ocupat de aceştia în cele două liste. Parametrii de pe acelaşi loc trebuie să fie de acelaşi tip, în caz contrar se afişează un mesaj de eroare. Numărul de parametri formali trebuie să fie egal cu numărul de parametri actuali, în caz contrar la apelarea funcţiei se afişează un mesaj de eroare. După apelarea unei funcţii, va fi returnată valoarea ultimei expresii evaluate în corpul funcţiei. Observaţie: Funcţiile noi definite în versiunile de AutoLISP pentru AutoCAD2000 sau 2002, sunt memorate ca şi subrutine (subprograme) definite de utilizator (USUBR sau SUBR). În versiunile anterioare de AutoLISP, funcţiile definite de programator sunt memorate sub forma unor liste. Din motive de compatibilitate între diversele versiuni de AutoCAD, au fost definite în AutoCAD2000/2002, noile funcţii AutoLISP:

defun-q pentru definirea funcţiei şi memorarea acesteia sub forma unei liste (are aceeaşi sintaxă ca şi defun);

defun-q-lis-ref pentru afişarea structurii funcţiei definite.

Exemple:

Page 51: Visual Lisp

Proiectare parametrizată asistată de calculator

52

1. Să se definească o funcţie AutoLISP care să permită calcularea

expresiei: ( )S x yx y

x y=+⋅

⋅ − . Funcţia va avea doi parametrii formali x, y şi nici

un parametru local. (defun s1 (x y) (/ (* (+ x y) (- x y)) (* x y)) ) Funcţia se apelează fie utilizând expresia (s1 23.0 5), fie (s1 t v) dacă t şi v sunt simboluri de tip întreg sau real, dar cel puţin unul de tip real. Dacă atât t cât şi v sunt întregi atunci se efectuează operaţiile de împărţire şi înmulţire cu întregi, obţinându-se ca rezultat un întreg. În cazul în care se doreşte preluarea valorii returnate de funcţia definită, atunci aceasta se apelează astfel:

(setq val (s1 23.0 5)) sau (setq val (s1 t v)) 2. Să se calculeze aceeaşi relaţie, dar utilizând o funcţie cu un parametru formal şi unul local. (defun s2 (x / y) (setq y (getreal ”\nIntroduceti y:”)) (/ (* (+ x y) (- x y)) (* x y)) ) Funcţia se apelează astfel:

(s2 20) sau (s2 t); (setq val (s2 20)) sau (setq val (s2 t))

3. Să se definească o funcţie AutoLISP care să traseze un cerc, după ce în prealabil utilizatorul a introdus centrul şi raza cercului. (defun cerc (/ centru raza) (initget 1) (setq centru (getpoint ”\nIntroduceti centrul cercului”)) (initget (+ 1 2 4)) (setq raza (getdist centru ”\nIntroduceti raza cercului:”)) (command ”circle” centru raza) (prin1) ;pentru inhibarea valorii returnate la apelarea funcţiei ) Funcţia definită se apelează cu ajutorul expresiei simbolice (cerc). După cum se observă din ultimul exemplu, o funcţie definită de programator poate apela în cadrul corpului ei, comenzi AutoCAD prin

Page 52: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

53

intermediul funcţiei command. Funcţia definită pare a fi o nouă comandă AutoCAD, diferă doar modul de apelare (se apelează între paranteze rotunde ca orice funcţie AutoLISP). Acest impediment este rezolvat dacă la definirea unei noi funcţii în faţa numelui se specifică secvenţa de caractere ”C:”. În acest fel se defineşte complet o nouă comandă AutoCAD, care se apelează din zona prompter-ului Command: al editorului de desenare, prin tastarea numelui funcţiei. Noua comandă este tratată ca orice comandă internă a AutoCAD-ului. În consecinţă, pentru a defini o nouă comandă AutoCAD, se utilizează în sintaxă ca nume al funcţiei definite C:XXX, unde XXX este numele noii comenzi AutoCAD. Observaţii: 1. Dacă se doreşte apelarea din AutoLISP, sau în fereastra Visual LISP Console a mediului VLISP, a unei funcţii de tip comandă AutoCAD (definită de programator), atunci va fi utilizată expresia simbolică (c:nume_functie). Se observă că nu este apelată prin intermediul funcţiei predefinită command. 2. O funcţie care defineşte o nouă comandă AutoCAD poate fi apelată în mod transparent (pe alte promptere decât Command: prin specificarea numelui comenzii respective precedat de caracterul apostrof, de exemplu ’XXX) dacă aceasta nu apelează funcţia AutoLISP command. Exemple: 1. Să se definească o nouă comandă AutoCAD care să permită trasarea unui triunghi oarecare, solicitându-se utilizatorului cele trei puncte care materializează vârfurile acestuia. (defun C:triunghi (/ p1 p2 p3) (initget 1)

(setq p1 (getpoint ”\n Introduceti p1:”)) (initget 1) (setq p2 (getpoint p1 ”\n Introduceti p2:”)) (initget 1) (setq p3 (getpoint p2 ”\n Introduceti p3:”)) (command ”line” p1 p2 p3 ”c”) (prin1) )

Funcţia se apelează ca orice comandă standard a AutoCAD-ului, prin tastarea numelui triunghi în zona prompter-ului Command: .

2. Să se definească o nouă comandă AutoCAD care să permită generarea modelului 3D din figura 2.12 parametrizat cu simboluri variabile. Semnificaţia simbolurilor este aceeaşi ca şi în exemplul de la subcapitolul 2.7. Noua comandă AutoCAD trebuie să aibă ecoul inhibat (nu sunt afişate pe ecran comenzile AutoCAD apelate din program) şi trebuie să funcţioneze corect, atunci când sunt moduri OSNAP curent setate.

Page 53: Visual Lisp

Proiectare parametrizată asistată de calculator

54

(defun c:model3d (/ p1 p2 p3 p4 lx ly lz r u cmd osn) (setq cmd (getvar "cmdecho")) ; se preia valoarea variabilei cmdecho (setvar "cmdecho" 0) ; se inhibă ecoul (setq osn (getvar "osmode")) ;se preia valoarea variabilei osmode (setvar "osmode" 0) ; se inhibă modurile OSNAP curent setate (initget 1) ; nu permite introducere nulă (apăsarea doar a tastei enter) (setq p1 (getpoint "\nPunctul de baza P1:")) ;citeşte punctul de bază (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq lx (getdist p1 "\n Cota lx:")) ;citeşte cota lx (lungimea pe axa x) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq ly (getdist p1 "\n Cota ly:")) ;citeşte cota ly (lungimea pe axa y) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq lz (getdist p1 "\n Cota lz:")) ;citeşte cota lz (lungimea pe axa z) (initget (+ 1 2 4)) ; nu permite introducere nulă sau un număr ≤ 0 (setq r (getdist p1 "\n Raza r:") ;citeşte raza de racordare u (getangle p1 "\n Unghiul de extrudare u:") u (/(* 180 u) pi) ) ;citeşte unghiul de extrudare şi îl converteşte în grade (setq p3 (list (+ (car p1) lx) (+ (cadr p1) ly)) p2 (list (car p3) (cadr p1)) p4 (list (car p1) (cadr p3)) ); se calculează punctele caracteristice poliliniei ce urmează a fi racordată şi apoi extrudată (command "pline" p1 p2 p3 p4 "c") ; se trasează polilinia (command "fillet" "r" r "fillet" "p" "l") ;se setează raza de racordare şi apoi se racordează polilinia (command "extrude" "l" "" lz u) ; se extrudează polilinia (command "vpoint" "1,1,1") ;se setează convenabil direcţia de privire (command "hide") ;se ascund liniile invizibile (setvar "cmdecho" cmd) ; se readuce variabila cmdecho pe valoare iniţială (setvar "osmode" osn) ; se readuce variabila osmode pe valoare iniţială (prin1) ; se inhibă valoarea returnată de funcţie

) Posibilitatea adăugării unor noi comenzi AutoCAD, cu ajutorul funcţiei defun, se constituie într-o facilitate foarte importantă oferită de AutoLISP. Funcţiile pot fi stocate în fişiere care pot fi oricând încărcate în AutoCAD şi lansate în execuţie. Încărcarea fişierelor AutoLISP se realizează cu ajutorul funcţiei load, descrisă în acest subcapitol. Dacă pe disc există fişierul acad.lsp, AutoCAD-ul îl încarcă automat de fiecare dată, la începutul fiecărei sesiuni de lucru. Se poate utiliza această

Page 54: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

55

facilitate pentru a crea o colecţie de funcţii utilitare care sunt întotdeauna la dispoziţia utilizatorului. Pentru ca imediat după intrarea în editorul de desenare al AutoCAD-ului, să fie executate şi anumite acţiuni specifice, prin lansarea automată în execuţie a anumitor funcţii, fişierul acad.lsp trebuie să aibă definită o funcţie specială denumită S::STARTUP. Această funcţie nu are parametrii formali sau actuali şi de regulă, este definită cu defun-q pentru a putea adăuga oricând cu funcţia append cod sursă. Prefixul S:: trebuie considerat de către programatori nume rezervat. Funcţia LOAD Sintaxă:

(LOAD <nume-fişier> [ <mesaj> ])

Funcţia load încarcă un fişier care are, în ordine, una din extensiile VLX, FAS, LSP. Dacă se încarcă un fişier AutoLISP (cu extensia LSP) atunci citirea se face secvenţial, pe măsură ce se citesc expresii, acestea sunt evaluate. Valoarea returnată de funcţie este identică cu valoarea ultimei expresii evaluate. Funcţia are un singur argument obligatoriu de tip şir de caractere care desemnează numele fişierului fără extensie (deoarece extensia implicită este LSP) ce trebuie încărcat. Al doilea argument de tip atom este opţional, şi dacă este indicat, atunci în cazul încărcării fără succes a unui fişier, se va afişa valoarea acestuia în locul mesajului de eroare. De regulă funcţia load este utilizată pentru încărcarea fişierelor din programe AutoLISP. Exemple: (load ”ex1”) (load ”a:\\work\\desen”) (load ”/work/desene/inexist” ”Eroare la incarcare”) Observaţie: Funcţia AutoLISP load este diferită de comanda AutoCAD LOAD. La apelarea funcţiei load, AutoLISP-ul caută fişierul menţionat, mai întâi în subdirectorul curent şi apoi în celelalte subdirectoare pentru care s-au definit în AutoCAD căi de căutare suplimentare prin variabile de sistem (vezi funcţia getenv). Dacă AutoLISP-ul furnizează un mesaj de eroare în timpul încărcării unui fişier, va trebui editat fişierul şi depanat programul. Cele mai multe mesaje indică erori tipice cum ar fi: tastarea eronată a numelor de funcţii sau simboluri, tip sau număr de argumente eronat în apelul funcţiilor, paranteze neînchise, ghilimele neînchise. Cele mai frecvente mesaje de eroare apărute la execuţia funcţiei load sunt prezentate în tabelul 2.3

Page 55: Visual Lisp

Proiectare parametrizată asistată de calculator

56

Tabelul 2.3

Mesaje de eroare Explicaţie

LOAD failed ”Nume-fişier” Numele invocat de funcţia load nu poate fi găsit, sau utilizatorul nu are acces pentru citirea fişierului.

extra right paren on input Au fost întâlnite prea multe paranteze dreapta (închise)

malformed string on input Mesajul se datorează neînchiderii unor ghilimele.

malformed list on input

S-a citit o listă incompletă. De obicei cauza este neînchiderea unor paranteze.

Fig. 2.13 Fereastra prin care se gestionează aplicaţiile încărcate în AutoCAD.

De reţinut este faptul că în versiunile mai noi de AutoCAD (2000, 2002), pentru încărcarea unei aplicaţii (în particular realizată în AutoLISP) se lansează

Page 56: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

57

în execuţie comanda Load Application din submeniul Tools. Pe ecran se prezintă fereastra din figura 2.13 prin care se gestionează aplicaţiile încărcate. Pot fi încărcate în AutoCAD următoarele tipuri de aplicaţii: salvate în fişiere sursă LISP (LSP), compilate în fişiere FAS, independente (VLX), ObjectARX (ARX) şi VisualBasic. Aplicaţiile AutoLISP pot fi încărcate şi din mediul VLISP. Modalităţile de încărcare au fost prezentate în capitolul 1 al acestei lucrări.

2.11 Funcţii condiţionale

În orice limbaj de programare sunt puse la dispoziţia programatorului modalităţi de ramificare a programelor. Programele AutoLISP sunt ramificate pe baza unor expresii test. Expresiile test sunt acele expresii simbolice care pot să returneze una din valorile: true (adevărat) sau false (fals). Ramificarea poate fi simplă sau multiplă, existând câte o funcţie predefinită pentru fiecare variantă: if şi respectiv cond). Cu ajutorul celor două funcţii se testează una sau mai multe expresii simbolice, iar programul va urma ramificaţia adecvată în concordanţă cu rezultatul testării.

2.11.1 Funcţii relaţionale şi de test. Egalităţi şi teste logice În AutoLISP simbolul predefinit T este echivalent cu true (adevărat), iar atomul nil este echivalent cu false (fals). Dacă o expresie AutoLISP, din cadrul unei funcţii condiţionale, returnează nil (false), atunci va fi parcursă ramura de fals. Spre deosebire de alte limbaje de programare, dacă în urma evaluării unei expresii se returnează altceva decât nil, expresia este echivalentă cu T sau true (adevărat). Dacă o expresie test este T, atunci se va continua parcurgerea programului pe ramura de true (adevărat). T şi nil se exclud prin definiţie; dacă o expresie este evaluată prin T atunci ea nu poate fi nil, şi reciproc. Funcţiile ce vor fi prezentate în continuare sunt utilizate cu precădere în expresii test. Funcţia = Sintaxă:

(= <atom1> [ <atom2> ..... <atomn> ]) Aceasta este funcţia relaţională de egalitate. Returnează T dacă toate argumentele, de tip atom, sunt valoric egale, şi nil în caz contrar. Această funcţie se utilizează pentru atomii numerici şi şiruri de caractere. Dacă funcţia are un singur argument se returnează T.

Page 57: Visual Lisp

Proiectare parametrizată asistată de calculator

58

Exemple: (= 1 1.0)→T (= 8 6.23)→ nil (= 1.2 1.2 1.2 1.2)→T (= 3.22 3.21 3.22)→ nil (= ”AutoLISP” ”AutoCAD”)→ nil (= ”Auto” ”Auto”)→T (= ”auto” ”Auto”)→ nil (= 10) →T Funcţia /= Sintaxă:

(/= <atom1> [ <atom2> ..... <atomn> ]) Aceasta este funcţia relaţională de neegalitate (diferit). Returnează T dacă nu există două argumente succesive, de tip atom, valoric diferite, sau nil în cazul în care cel puţin două argumente succesive sunt egale. Şi această funcţie se utilizează pentru atomii numerici şi şiruri de caractere. Dacă funcţia are un singur argument se returnează T. Exemple: (/= 1 1.0)→nil (/= 8 6.23)→T (/= 1.2 1.2 1.2 1.2)→nil (/= 1.2 10 1.2 20)→T (/= 12 10 12 12)→nil (/= 3.22 3.21 3.22)→T (/= ”AutoLISP” ”AutoCAD”)→T (/= ”Auto” ”Auto”)→nil (/= ”a” ”A”)→ T (/= 10) →T Funcţia < Sintaxă:

(< <atom1> [ <atom2> ..... <atomn> ]) Funcţia relaţională ”<” returnează T dacă toate argumentele (de tip atom) respectă valoric relaţia cerută (şir strict crescător), sau nil în caz contrar. În cazul existenţei mai multor argumente se compară atomul curent cu cel din dreapta sa. Această funcţie se utilizează pentru atomii numerici şi şiruri de caractere. Dacă funcţia are un singur argument atunci este returnat T.

Page 58: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

59

Exemple: (< 10 12.0)→T (< 8 6.23 89)→nil (< 1.2 2.2 5.2 12)→T (< ”A” ”D”)→T (< ”AutoLISP”) →T Funcţia <= Sintaxă:

(<= <atom1> [ <atom2> ..... <atomn> ]) Funcţia relaţională ”<=” returnează T dacă toate argumentele (de tip atom) respectă valoric relaţia cerută (şir crescător), sau nil în caz contrar. În cazul existenţei mai multor argumente, se compară atomul curent cu cel din dreapta sa. Dacă funcţia are un singur argument atunci se returnează T. Exemple: (<= 10 12.0)→T (<= 8 23.23 89)→T (<= 1.2 2.2 -1.2 12)→nil (<= ”A” ”A”)→T (<= 12)→T Funcţia > Sintaxă:

(> <atom1> [ <atom2> ..... <atomn> ]) Funcţia relaţională ”>” returnează T dacă toate argumentele respectă valoric relaţia cerută (şir strict descrescător), sau nil în caz contrar. În cazul existenţei mai multor argumente, se compară atomul curent cu cel din dreapta sa. Şi această funcţie se utilizează pentru atomii numerici şi şiruri de caractere. Dacă funcţia are un singur argument atunci se returnează T. Exemple: (> 10 12.0)→nil (> 8 6.23 1.89)→T (> 1.2 2.2 5.2 12)→nil (> ”h” ”a”)→T (> ”ha”)→T

Page 59: Visual Lisp

Proiectare parametrizată asistată de calculator

60

Funcţia >= Sintaxă:

(>= <atom1> [ <atom2> ..... <atomn> ]) Funcţia relaţională ”>=” returnează T dacă toate argumentele (de tip atom) respectă valoric relaţia cerută (şir descrescător), sau nil în caz contrar. În cazul existenţei mai multor argumente se compară atomul curent cu cel din dreapta sa. Dacă funcţia are un singur argument atunci se returnează T şi poate fi utilizată pentru argumente de tip numeric/şir de caractere. Exemple: (>= 10 10.0)→T (>= 8 23.23 89)→nil (>= 1.2 1.2 1.2 1.2)→T (>= ”A” ”A”)→T (>= -5)→T Funcţia EQ Sintaxă:

(EQ <expr1> <expr2>)

Această funcţie determină dacă <expr1> şi <expr2> sunt identice, adică la momentul curent cele două argumente au atribuite acelaşi obiect (de exemplu cu ajutorul funcţiei setq). Eq returnează T dacă cele două expresii sunt identice, sau nil în caz contrar. Este tipic utilizată pentru a determina dacă două liste sunt identice. Exemple: Să considerăm următoarele atribuiri: (setq l1 ’(a b c)) (setq l2 ’(a b c)) (setq l3 l2) dacă utilizăm funcţia eq pe perechi de liste avem: (eq l1 l3)→nil ;deoarece l1 şi l3 nu sunt perfect identice (au fost obţinute prin metode diferite) (eq l3 l2)→T ;deoarece argumentele l3 şi l2 referă aceeaşi listă

;s-a utilizat funcţia setq la obţinerea lui l3 din l2 Funcţia EQUAL Sintaxă:

Page 60: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

61

(EQUAL <expr1> <expr2> [ <eroare> ])

Funcţia equal determină dacă <expr1> şi <expr2> sunt egale, adică dacă cele două argumente sunt evaluate la aceeaşi valoare în marja de eroare dată de argumentul opţional <eroare>. Equal returnează T dacă cele două expresii sunt egale, sau nil în caz contrar. Exemple: Dacă considerăm următoarele atribuiri: (setq l1 ’(a b c)) (setq l2 ’(a b c)) (setq l3 l2) utilizând funcţia equal pe liste avem: (equal l1 l3)→T ;deoarece l1 şi l3 sunt evaluate la acelaşi obiect (equal l3 l2)→T ;deoarece l2 şi l3 sunt exact aceleaşi liste Dacă se compară de exemplu două numere reale (sau două liste de numere reale, ca în cazul punctelor AutoCAD), care ar trebui să fie identice dar ele diferă foarte puţin, datorită faptului că au fost obţinute prin metode diferite, poate fi utilizată funcţia equal deoarece permite, conform sintaxei generale, verificarea egalităţii într-o marjă de eroare stabilită de programator. Exemple: Dacă avem următoarele atribuiri: (setq x 2.222222 y 2.222223) în cazul utilizării funcţiei equal se obţine: (equal y x)→nil (equal y x 0.0000011)→T (equal y x 0.000001)→nil Observaţie: Este foarte important de înţeles diferenţele dintre funcţiile equal, eq şi funcţia =, prezentate în acest subcapitol. Funcţia ATOM Sintaxă:

(ATOM <articol>) Această funcţie returnează nil dacă <articol> este o listă şi T în caz contrar. Argumentul funcţiei poate fi orice obiect AutoLISP. Funcţia se bazează pe faptul că tot ce nu este listă este considerat atom.

Page 61: Visual Lisp

Proiectare parametrizată asistată de calculator

62

Exemple: Pentru atribuirile: (setq lista ’(a b c) l1 ’lista) se obţine: (atom ’lista)→T ;deoarece lista este considerată ca fiind simbol (atom lista)→nil (atom ’l1)→T ;deoarece l1 memorează simbolul lista (atom l1)→T (atom ’(a b c))→nil

(atom getpoint) →T (atom nil)→ T (atom ’())→ T Ultimele două exemple, demonstrează faptul că simbolul nil poate fi atât atom cât şi listă. Funcţia LISTP Sintaxă:

(LISTP <articol>) Funcţia listp returnează T dacă <articol> este o listă sau nil în caz contrar. Argumentul funcţiei poate fi o listă, un atom sau o expresie. Exemple: (listp ’(1 2 3 4 5))→T (listp 1.23)→nil (listp ’x)→nil ;deoarece x este simbol (listp nil)→T ;deoarece nil este atât atom cât şi listă (listp initget) →nil

(listp (setq a '(1 1))) →T ;deoarece expresia simbolică argument este caz particular de listă

Funcţia BOUNDP Sintaxă:

(BOUNDP <simbol>)

Funcţia returnează T dacă <simbol> are o valoare atribuită. Dacă nici o valoare nu este atribuită argumentului, sau îi este atribuit atomul nil, atunci funcţia returnează nil. Exemple: (setq x 2 y nil)

Page 62: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

63

(boundp ’x)→T (boundp ’y)→nil Funcţia NULL Sintaxă:

(NULL <articol>)

Funcţia null returnează T dacă <articol> este legat la nil, iar în caz contrar returnează nil. Argumentul notat cu <articol> este un simbol sau o expresie AutoLISP. Exemple: Pentru atribuirile: (setq x 243 s ”AutoLISP” y nil) în urma aplicării funcţiei null se poate scrie: (null y)→T (null x)→nil (null s)→nil (null ’())→T (null 20) →nil Funcţia MINUSP Sintaxă:

(MINUSP <nr>)

Această funcţie returnează T dacă <nr> este un real sau întreg evaluat la o valoare negativă, în caz contrar returnează nil. Exemple: (minusp -1.1)→T (minusp 1110.1)→nil (minusp -45.671)→T Funcţia NUMBERP Sintaxă:

(NUMBERP <articol>)

Page 63: Visual Lisp

Proiectare parametrizată asistată de calculator

64

Funcţia returnează T dacă <articol> este un real sau un întreg, iar în caz contrar nil. Argumentul notat cu <articol> este un simbol sau o expresie. Exemple: Pentru atribuirile: (setq x 243 s ”AutoLISP” y ’x) se obţin următoarele rezultate: (numberp 23)→T (numberp 57.35)→T (numberp x)→T (numberp y)→nil (numberp s)→nil (numberp (eval y))→T Funcţia ZEROP Sintaxă:

(ZEROP <nr>)

Zerop returnează T dacă <nr> este un real sau un întreg evaluat la valoarea zero, iar în caz contrar nil. Funcţia nu este definită pentru alte tipuri de date. Exemple: (zerop 0)→T (zerop 0.04)→nil (zerop 100)→nil (zerop 0.0)→T

2.11.2 Funcţii pentru formarea condiţiilor compuse Funcţia NOT Sintaxă:

(NOT <expr>)

Page 64: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

65

Funcţia not returnează T dacă expresia <expr> este evaluată prin nil, iar în caz contrar nil. Funcţia este utilizată de regulă pentru tipuri de date diferite de liste. Exemple: (setq a 1212 b ”LISP” c nil) (not a)→nil (not b)→nil (not (= a b))→ T (not c)→T (not ’())→T Funcţia AND Sintaxă:

(AND [ <expr1> <expr2> .... <exprn> ] )

Această funcţie returnează rezultatul aplicării operatorului ŞI logic expresiilor notate cu <expr>. Cu alte cuvinte, se evaluează argumentele de la stânga la dreapta, iar dacă există cel puţin un argument evaluat prin valoarea nil, rezultatul este nil; în caz contrar rezultatul este T. Funcţia apelată fără argument returnează valoarea T. Exemple: Pentru atribuirile: (setq a 1.0 b nil c ”ABC”) avem: (and 2 a c)→T (and 2 a b c)→nil (and)→T Funcţia OR Sintaxă:

(OR [ <expr1> <expr2> .... <exprn> ])

Funcţia or returnează rezultatul aplicării operatorului SAU logic expresiilor notate cu <expr>. Se evaluează argumentele de la stânga la dreapta,

Page 65: Visual Lisp

Proiectare parametrizată asistată de calculator

66

iar dacă există cel puţin un argument evaluat printr-o valoare diferită de nil, rezultatul este T; dacă toate argumentele sunt nil returnează nil. Funcţia apelată fără argumente returnează valoarea nil. Exemple: Pentru atribuirile: (setq a 1.0 b nil c ”ABC”) avem: (or nil 2 a c)→T (or 2 a b c)→T (or nil b ’())→nil (or)→nil Funcţiile relaţionale, de test şi logice (de formare a condiţiilor compuse) sunt utilizate la scrierea expresiilor test. Ele sunt utilizate în expresiile simbolice condiţionale sau repetitive care apar în cadrul funcţiilor: if, cond şi while. În funcţie de valorile returnate, se verifică dacă este îndeplinită o anumită condiţie şi se indică ce set de expresii simbolice să se execute în continuare. Observaţie importantă: În expresiile test pot fi utilizaţi atomi, simboluri sau orice alte expresii, deoarece orice obiect AutoLISP are o valoare: nil sau ceva diferit de nil care poate fi considerat T. Spre deosebire de alte limbaje de programare, AutoLISP-ul fiind un limbaj funcţional, ramificarea programelor se face cu ajutorul unor funcţii. Funcţiile condiţionale controlează, prin intermediul unor expresii test, fluxul unui program. Acestea au posibilitatea de a conduce rularea programului pe una din variantele posibile de continuare. Fiecare variantă are ataşat câte un set de expresii simbolice. După cum am precizat, în AutoLISP există două funcţii condiţionale: if şi cond.

2.11.3 Funcţia condiţională if Funcţia IF Sintaxă:

(IF <expr-test> <expr-then> [ <expr-else> ])

Page 66: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

67

Funcţia if are două argumente obligatorii expresiile simbolice notate cu <expr-test>, <expr-then> şi unul opţional expresia simbolică <expr-else>. Se evaluează primul argument <expr-test> şi dacă valoarea rezultată este echivalentă cu T, adică este diferită de nil, atunci se evaluează al doilea argument <expr-then>. Dacă valoarea returnată de primul argument este nil, atunci AutoLISP-ul va evalua, dacă există, al treilea argument <expr-else> (cel opţional). Funcţia returnează valoarea ultimei expresii simbolice evaluate, deci rezultatul evaluării lui <expr-then> sau <expr-else>. Observaţie: Cele două expresii <expr-then> şi <expr-else>, care desemnează ramurile then şi else, sunt expresii simbolice simple. Dacă pe aceste ramuri se doreşte evaluarea mai multor expresii simbolice, atunci acestea trebuie grupate cu ajutorul funcţiei progn. Exemple:

Următoarele expresii se vor tasta direct pe prompter-ul Command: sau în Visual LISP Console. 1. (setq a 2) (if (= a 2) (setq y 15) (setq y 20))→15 Se solicită apoi valoarea lui y (!y în AutoCAD). 2. (setq b 3) (if (and (/= a 0) (numberp b)) (setq z 0) (setq x 20))→0 Se solicită valorile lui z şi x (!z !x în AutoCAD). 3. (setq b nil) ( if b (setq b 10) (setq b 0))→0 Se solicită valoarea lui b (!b în AutoCAD). Funcţia PROGN Sintaxă:

(PROGN [ <expr1> <expr2> .... <exprn> ])

Funcţia progn evaluează secvenţial expresiile <expr> şi returnează valoarea ultimei expresii evaluate. Rolul principal al funcţiei constă în faptul că grupează expresiile care urmează a fi evaluate (este funcţia echivalentă instrucţiunii compuse din alte limbaje de programare). Se utilizează cu precădere în funcţia if. Exemple: 1. (setq a 34 b 56) (if (/= a b) (progn

Page 67: Visual Lisp

Proiectare parametrizată asistată de calculator

68

(setq a 10) (setq b 20) ) (progn (setq a (+ a 10)) (setq b (+ b 20)) ) )→20 Se solicită apoi valorile lui a şi b (!a !b în AutoCAD). 2. (setq a 3) (if (>= a 0) (progn (setq y 12) (setq z 0) ) (setq x 20) )→0 Se solicită apoi valorile lui y, z şi x (!y !z !x în AutoCAD).

2.11.4 Funcţia condiţională cond Funcţia COND Sintaxă: (COND [ ( <expr-test_1> <expr11> <expr12>.... ) ( <expr-test_2> <expr21> <expr22>.... ) ...................... ( <expr-test_n> <exprn1> <exprn2>.... ) [ (T <exprn+1 1> <exprn+1 2>.... )] ] ) Funcţia cond are un număr oarecare de argumente opţionale. După cum se observă, fiecare argument al funcţiei conţine mai multe expresii simbolice, prima dintre ele <expr-test_i> fiind expresia test. Cond evaluează pe rând expresiile logice <expr-test_i> şi când întâlneşte una diferită de nil, se evaluează expresiile <expri1>, <expri2>.... care urmează expresiei test respective, urmând a se relua programul cu următoarea expresie simbolică de după cond. Dacă toate expresiile <expr-test_i> evaluate sunt nil şi există ramura de else, este parcursă aceasta (expresiile simbolice <exprn+1 1>, <exprn+1 2>....) deoarece expresia test aferentă are întotdeauna valoarea T. Această funcţie returnează valoarea ultimei expresii evaluate. Dacă funcţia nu are argumente este returnată valoarea nil.

Page 68: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

69

Din multe puncte de vedere funcţia cond este asemănătoare instrucţiunii Case din alte limbaje de programare. Exemple: 1. Funcţia următoare testează dacă argumentul este mai mare, mai mic sau egal cu zero şi afişează mesajul corespunzător.

(defun test (x) (cond ((> x 0) (princ ”\nValoare pozitiva”)) ((< x 0) (princ ”\nValoare negativa”)) (T (princ ”\nValoare egală cu zero”)) ) (prin1) )

Funcţia definită se apelează în diverse ipostaze: (test y) dacă anterior s-a tastat (setq y 100), (test -5) şi (test 0).

2. Funcţia următoare permite utilizatorului să aleagă o suprafaţă de revoluţie (cilindrică, frontală sau conică), afişează suprafaţa aleasă şi returnează cuvântul cheie aferent acesteia. Suprafaţa cilindrică este cea implicită. (defun tip-supr (/ supr)

(initget ”CIlindrica Frontala COnica”) (setq supr (Getkword ”\n Tipul suprafeţei [CIlindrica/Frontala/COnica]

<Cilindrica>:”)) (cond

((= supr ”CIlindrica”) (princ ”\nSuprafaţa selectata este Cilindrica\n”)) ((= supr ”Frontala”) (princ”\nSuprafaţa selectata este Frontala\n”)) ((= supr ”COnică”) (princ ”\nSuprafaţa selectata este Conica\n”)) (T(setq supr ”CIlindrica”)(princ ”\nSuprafaţa aleasa este Cilindrica\n”))

) supr ;returnează cuvântul cheie ales (suprafaţa aleasă) )

Se apelează prin expresia simbolică (tip-supr).

Page 69: Visual Lisp

Proiectare parametrizată asistată de calculator

70

2.12 Funcţii repetitive

Ciclurile sunt concepte importante în orice limbaj de programare. Ele permit parcurgerea unei secvenţe de program, denumită corpul ciclului, de un anumit număr de ori, cunoscut apriori sau pe baza unei valori returnate de o expresie test. În AutoLISP ciclurile sunt materializate prin intermediul unei expresii simbolice, în sintaxa căreia intervine o funcţie repetitivă. Există trei funcţii repetitive: repeat, while şi foreach.

2.12.1 Funcţia Repeat Funcţia REPEAT Sintaxă:

(REPEAT <număr> [ <expr1> <expr2>

........ <exprn> ]

)

Funcţia repeat evaluează expresiile simbolice notate cu <expr1>, <expr2>,.....<exprn> de un număr fix de ori dat de argumentul <număr>, şi returnează valoarea ultimei expresii evaluate. Dacă la apelarea funcţiei nu se indică nici o expresie atunci este returnată valoarea nil. Funcţia are un argument obligatoriu şi mai multe argumente opţionale. Argumentul obligatoriu trebuie să fie un întreg sau expresie simbolică care în urma evaluării să returneze o valoare întreagă. Acest argument specifică funcţiei repeat de câte ori să evalueze expresiile simbolice care formează corpul ciclului. Exemple: 1. Se atribuie variabilelor a şi b valorile iniţiale 1 şi respectiv 10. Aceste variabile se incrementează de 10 ori, cu ajutorul unui repeat, cu 1 respectiv 10. După fiecare incrementare, se afişează valorile asociate variabilelor. (setq a 1 b 10) (repeat 10

Page 70: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

71

(setq a (1+ a) b (+ 10 b) ) (princ”\na=”) (princ a) (princ”\nb=”) (princ b) )

După parcurgerea de 10 ori a corpului funcţiei repeat, a are valoarea 11 iar b 110. 2. Calculul factorialului unui număr natural cu ajutorul funcţiei repeat. (defun factorial (/ n contor f) (initget 7) (setq n (getint ”\nIntroduceţi n=”) f 1.0 contor 1) (repeat n (setq f (* f contor) contor (1+ contor) ) ) (princ(strcat ”\nFactorialul calculat este ” (itoa n) ”!=” (rtos f 2 0))) (prin1) )

Funcţia definită se apelează prin (factorial).

Observaţie: Funcţia repeat este diferită de instrucţiunile cu acelaşi nume din alte limbaje de programare, ea putând fi asimilată, din anumite puncte de vedere, cu instrucţiunea FOR. Repeat este cea mai simplă funcţie repetitivă, dacă se cunoaşte apriori, de câte ori trebuie evaluat setul de expresii simbolice care formează corpul funcţiei. Există uneori situaţii în care trebuie repetat un set de expresii simbolice de un număr necunoscut iniţial de ori. În acest caz, funcţia while este cea care permite efectuarea acţiunii specificate, pe baza valorii returnate de o expresie test.

Page 71: Visual Lisp

Proiectare parametrizată asistată de calculator

72

2.12.2 Funcţia repetitivă While Funcţia WHILE Sintaxă:

(WHILE <expr-test> [ <expr1> <expr2>

........ <exprn> ]

)

Funcţia while evaluează <expr-test> şi dacă nu are valoarea nil, evaluează setul de expresii notate cu <expr1>, <expr2>,.....,<exprn> care formează corpul ciclului şi apoi se reevaluează expresia test. Acţiunile prezentate mai sus sunt repetate până când expresia <expr-test> returnează nil. Deci atâta timp cât este îndeplinită expresia <expr-test> se execută corpul ciclului. Funcţia returnează valoarea rezultată în urma evaluării ultimei expresii simbolice. Datorită faptului că while este o funcţie mai complexă, pentru a evita apariţia unor erori, programatorul trebuie să aibă în vedere următoarele:

pentru ca setul de expresii simbolice din corpul funcţiei să fie parcurs măcar o dată, trebuie ca valoarea iniţială a expresiei test să fie diferită de nil; deci trebuie îndeplinită condiţia de intrare în ciclu while, adică programatorul trebuie să seteze corect variabilele care intervin în expresia test înainte de a se intra în ciclu; pentru a evita intrarea într-un ciclu infinit, trebuie ca în corpul acestuia să fie

modificate valori ale anumitor variabile astfel încât expresia test să returneze nil la un anumit moment (condiţia de ieşire din ciclu).

Exemple: 1. În timp ce variabila a este diferită de nil (deci T) şi este mai mare decât 0, se micşorează valoarea lui a şi apoi se afişează această valoare dacă este diferită de nil. Se iese din while atunci când a devine egală cu nil. Valoarea iniţială a variabilei a este 20. (setq a 20) (while a (if (> a 0) (setq a (1- a)) (setq a nil)) (if a (princ a)) ) 2. Calculul factorialului unui număr natural cu ajutorul funcţiei while (fără parametru formal).

Page 72: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

73

(defun factorial (/ n contor f) (initget 7) (setq n (getint ”\nIntroduceti n=”) f 1.0 contor 1 ) (while (<= contor n) (setq f (* f contor) contor (1+ contor) ) ) (princ (strcat”\nFactorialul calculat este ” (itoa n) ”!=” (rtos f 2 0))) (prin1) ) Se apelează prin expresia simbolică (factorial). 3. Calculul factorialului unui întreg pozitiv cu ajutorul funcţiei while (cu parametru formal). (defun factp ( n / contor f) (setq f 1.0 contor 1 ) (while (<= contor n) (setq f (* f contor) contor (1+ contor) ) ) (princ (strcat ”\nFactorialul calculat este ” (itoa n) ”!=” (rtos f 2 0))) (prin1) ) Se apelează, de exemplu, prin expresia (factp 10). Observaţie: Funcţia while, din punctul de vedere al modului în care acţionează, este echivalenta instrucţiunii cu acelaşi nume din alte limbaje de programare. Există unele situaţii în care anumite probleme sunt destul de greu de rezolvat cu ajutorul funcţiei while sau repeat. De exemplu dacă se doreşte calcularea factorialului, cu ajutorul funcţiei factp, pentru mai multe valori între care nu există o relaţie de recurenţă. Acest lucru se rezolvă foarte uşor cu ajutorul funcţiei foreach.

Page 73: Visual Lisp

Proiectare parametrizată asistată de calculator

74

2.12.3 Funcţia repetitivă Foreach Funcţia FOREACH Sintaxă:

(FOREACH <variabilă> <listă> [ <expr1> <expr2>

........ <exprn> ]

)

Această funcţie parcurge element cu element lista <listă> atribuindu-i variabilei notată cu <variabilă> valoarea fiecărui element, evaluând succesiv setul de expresii simbolice <expr1>, <expr2>,.....,<exprn> cu valoarea curentă a variabilei. Foreach necesită două argumente obligatorii şi anume: variabila <variabilă> şi lista (<listă>) de valori aferente acesteia. La ieşirea din ciclu variabila va avea valoarea ultimului element din listă, iar valoarea returnată de funcţie este rezultată din evaluarea ultimei expresii <exprn>. Dacă funcţia nu are expresii drept argument, cele care formează corpul ciclului, atunci este returnată valoarea nil. Observaţie: Elementele listei <listă> trebuie să fie de acelaşi tip sau de tipuri compatibile. Exemple: 1. (setq a ”AutoLISP” b ”AutoCAD” c (strcat b ” si ” a) ) (foreach s (list a b c) (print s))→ ”AutoCAD şi AutoLISP” Ultima expresie simbolică va atribui pe rând simbolului s valorile conţinute de lista (a b c) cu a, b şi c evaluate şi le va afişa pe ecran. 2. (foreach I ’(2 5 6 9 23 45 46 61) (factp I)) În acest ultim exemplu, va fi calculat factorialul numerelor date în listă, prin apelarea funcţiei factp, definită în exemplul 3 de la funcţia while.

Page 74: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

75

2.13 Funcţii de conversie

Funcţiile din această categorie permit de regulă convertirea unor şiruri de caractere în întregi sau reali sau a unor numere (întregi/reali) în şiruri de caractere. Funcţia ATOI Sintaxă:

(ATOI <şir>) Funcţia atoi (abreviere de la Ascii TO Integer) permite convertirea unui şir de caractere la un număr întreg. Dacă şirul de caractere desemnează un real atunci conversia se face prin trunchiere. Exemple: (atoi ”56”)→56 (atoi ”5.6”)→5 (atoi ”-5”)→-5 (atoi ”50.67klll2”)→50 (atoi ”k2ll”)→0 Observaţie: Dacă şirul de caractere nu poate fi convertit într-un întreg, funcţia returnează atomul 0, iar dacă primul/primele caractere din şir sunt numerice atunci doar acestea vor fi convertite la un întreg. Funcţia ITOA Sintaxă:

(ITOA <intreg>) Funcţia itoa (Integer TO Ascii) este inversa funcţiei atoi şi permite convertirea unui întreg într-un şir de caractere. Exemple: (itoa 56)→”56” (itoa -5)→ ”-5” Funcţia RTOS Sintaxă:

(RTOS <real> [ <format> [ <precizie> ] ])

Page 75: Visual Lisp

Proiectare parametrizată asistată de calculator

76

Funcţia rtos (Real TO String) este utilizată pentru conversia argumentului <real> (de tip real) într-un şir de caractere. Parametrii opţionali <format> şi <precizie> sunt de tip întreg şi semnifică formatul unităţilor liniare respectiv numărul de zecimale conţinute de şirul de caractere rezultat. Pot fi utilizate aceleaşi formate (tabelul 2.4) prezente în cazul comenzii AutoCAD UNITS. Dacă parametrii opţionali lipsesc atunci conversia se va face în formatul şi cu numărul de zecimale curente (setate cu ajutorul comenzii UNITS). Exemple: (rtos 56.78 1 5)→”5.67800E+01” (rtos 56.78 2 4)→”56.7800” (rtos 17.5 3 )→”1’-5.5\”” (rtos 17.5 4 )→”1’-5 1/2\”” (rtos 7.5 5 )→”7 1/2” Tabelul 2.4

Moduri RTOS

Format

Exemplu

1

Ştiinţific (Scientific)

5.56600E+01

2

Zecimal (Decimal)

23.454

3

Ingineresc (Engineering)

1’ -5.50”

4

Arhitectural (Architectural)

1’ -5 1/2

5

Fracţional (Fractional)

12 2/3

Observaţie: Variabila DIMZIN influenţează rezultatul conversiei. Dacă valoarea acesteia este 8, atunci sunt suprimate zerourile zecimalelor. Funcţia ATOF Sintaxă:

(ATOF <şir>)

Page 76: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

77

Funcţia atof (abreviată de la Ascii TO Float) permite convertirea unui şir de caractere într-un real. Exemple: (atof ”56.34”)→56.34 (atof ”5.01”)→5.01 (atof ”-5”)→-5.0 (atof ”50.67klll2”)→50.67 (atof ”k2ll”)→0.0 Observaţii: 1. Dacă primele caractere ale şirului sunt de tip numeric, dar şirul conţine şi alte caractere diferite de cele numerice, atunci atof va converti la un real doar primele caractere. Iar dacă primul caracter este unul alfabetic atunci funcţia returnează valoarea 0.0. 2. Funcţia nu poate fi folosită (în mod direct) la evaluarea unor expresii test pentru că 0.0 este echivalent cu T. Pentru acestea este indicat a se utiliza funcţia distof. Funcţia DISTOF Sintaxă:

(DISTOF <şir> [ <format> ])

Ca şi atof funcţia distof permite convertirea unui şir de caractere la un real, dar cu precizarea formatului din care se converteşte şirul. Argumentul opţional <format> are aceeaşi semnificaţie ca şi în cazul funcţiei rtos. Exemple: (distof ”56.34”)→56.34 (distof ”5.01”)→5.01 (distof ”-5”)→-5.0 (distof ”50.67klll2”)→nil (distof ”k2ll”)→nil (distof ”56.34” 2)→56.34 (distof ”17 1/2” 5)→17.5 (distof ”1’-5.5\”” 3)→17.5 Observaţii: 1. Dacă şirul de caractere nu poate fi convertit într-un real, funcţia returnează valoarea nil. 2. Funcţiile rtos şi distof sunt complementare. Funcţia ANGTOS

Page 77: Visual Lisp

Proiectare parametrizată asistată de calculator

78

Sintaxă:

(ANGTOS <unghi> [ <format> [ <precizie> ] ])

Transformă argumentul <unghi> într-un şir de caractere ţinând cont de formatul indicat de <format> şi cu un număr de zecimale dat de <precizie>. Argumentul funcţiei se va preciza în radiani iar <format> şi <precizie> sunt atomi sau simboluri de tip întreg. Formatele posibile sunt cele existente în cadrul comenzii AutoCAD UNITS şi prezentate în tabelul 2.5. Tabelul 2.5

Moduri ANGTOS

Format

Exemplu

0

Grade (Degree)

180

1

Grade/minute/secunde (Degrees/minutes/seconds)

82d 20’ 10”

2

Grade centezimale (Grads)

120.235g

3

Radiani (Radians)

3.1416r

4

Unităţi speciale (Surveyor’s units)

N 54d0’ E

Exemple: (setq a PI) (angtos a 0 0)→ ”180” (angtos a 0 4) → ”180.0000” (angtos a 1) → ”180 d 0´ 0 ˝” (angtos a 3 4) → ”3.1416r” (angtos a 4) → ”W” (angtos a 2 4) → ”200.0000g”

Page 78: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

79

Funcţia acceptă chiar şi valori negative pentru argument, dar la transformare, valorile rezultate în şirurile de caractere vor fi încadrate în intervalul [0,2π]. Exemple: (angtos (/ PI 4) 0 2) → ”45.00” (angtos ((* (/ PI 4) -1) 0 2) → ”315.00” Observaţie: Variabila DIMZIN influenţează rezultatul conversiei. Dacă valoarea acesteia este 8, atunci sunt suprimate zerourile zecimalelor. Funcţia ANGTOF Sintaxă:

(ANGTOF <şir> [ <format> ])

Converteşte argumentul <şir> de tip şir de caractere într-un real care reprezintă un unghi exprimat în radiani. Formatul de reprezentare a unghiului în şirul de caractere, este dat de argumentul opţional <format>. Formatele posibile sunt cele din cadrul comenzii AutoCAD UNITS prezentate în tabelul 2.5. Exemple: (angtof ”180” 0)→ 3.14159 (angtof ”180d0’0\”” 1) → 3.14159 (angtof ”3.1416r” 3 ) → 3.1416 (angtof ”W” 4 ) → 3.14159 (angtof ”200.0g” 2) → 3.14159 Observaţie: Funcţiile angtos şi angtof sunt complementare. Funcţia ASCII Sintaxă:

(ASCII <şir>) Funcţia returnează întregul aferent transformării primului caracter al şirului în cod ASCII. Exemple: (ascii ”A”) → 65 (ascii ”B”) → 66 (ascii ”AutoLISP”) → 65 Funcţia CHR

Page 79: Visual Lisp

Proiectare parametrizată asistată de calculator

80

Sintaxă: (CHR <întreg> )

Returnează caracterul al cărui cod ASCII în baza 10 este argumentul. Exemple: (chr 65) → ”A” (chr 66) → ”B”

Funcţia CVUNIT Sintaxă:

(CVUNIT <articol> <su1> <su2>)

Converteşte argumentul <articol> din sistemul de unităţi <su1> în sistemul de unităţi <su2>. Argumentul <articol> poate fi un întreg, un real sau o listă ce materializează un punct 2D sau 3D. Argumentele <su1> şi <su2> sunt şiruri de caractere care desemnează unităţile de măsură în conformitate cu datele stocate în fişierul acad.unt. Exemple:

(cvunit 1.5 "minute" "second") →90.0 (cvunit 32 "degrees" "radians")→0.558505 (cvunit 1.0 "inch" "mm") →25.4 (cvunit '(100 250) "mm" "in") → (3.93701 9.84252) (cvunit '(10 20 30) "ft" "in") → (120.0 240.0 360.0)

Funcţia TRANS Sintaxă:

(TRANS <pct> <sc1> <sc2>)

Translatează punctul notat cu <pct> din sistemul de coordonate <sc1> (în care este exprimat) în sistemul de coordonate <sc2> (în care urmează a fi exprimat). Sistemele de coordonate pot fi exprimate ca:

întregi valoare 0 - pentru WCS, 1 - pentru UCS-ul curent, 2 - pentru DCS-ul curent (Display Coordinate System care este sistemul de coordonate din viewport-ul curent), 3 - pentru PSDCS (Paper Space Display Coordinate System care este sistemul de coordonate din spaţiul hârtie);

nume de entităţi care specifică OCS-ul (Object Coordinate System – este sistemul relativ la care funcţia entget returnează punctele din lista asociată) unei entităţi AutoCAD;

ca un vector 3D de extrudare (acesta este întotdeauna reprezentat în WCS).

Page 80: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

81

Exemple: 1. Dacă se consideră că UCS-ul curent este rotit cu 90˚ în jurul axei Z şi

cu 45˚ în jurul axei X, atunci se poate scrie: (setq p1 '(1.0 2.0 3.0)) ; punctul de translatat (setq sc1 0) ; WCS (setq sc2 1) ] ; UCS-ul curent (trans p1 sc1 sc2) → (2.0 1.41421 2.82843) ; punctul translatat

2. Dacă se trasează în WCS o linie având punctul de start în 10,10 şi

punctul de final în 100,100 şi apoi se consideră că UCS-ul curent este rotit cu 90˚ în jurul axei Z şi cu 45˚ în jurul axei X, atunci se poate scrie:

(setq p2 (cdr (assoc 10 (entget (entlast))))) → (10.0 10.0 0.0) ; punctul start (setq sc1 (entlast)) ; OCS-ul entităţii linie (setq sc2 1) ; UCS-ul curent (trans p2 sc1 sc2) → (10.0 -7.07107 7.07107) ; punctul translatat

2.14 Funcţii pentru gestionarea şirurilor de caractere Funcţiile pentru gestionarea şirurilor de caractere permit: concatenarea a două sau mai multe şiruri de caractere, extragerea unor subşiruri (secvenţe din cadrul şirurilor de caractere), transformarea caracterelor în majusculă sau minusculă (litere mici) şi aflarea lungimii unor şiruri de caractere. Funcţia STRCAT Sintaxă:

(STRCAT [ <şir1> [ <şir2> ... <şirn> ] ]) Funcţia returnează şirul de caractere rezultat în urma concatenării (adunării) şirurilor de caractere furnizate ca argumente. Dacă nu este precizat nici un argument atunci se returnează şirul vid (””). Exemple: (setq s (strcat ”Auto” ”LISP”)) → ”AutoLISP” (setq s (strcat s ” si Auto” ”CAD”)) → ”AutoLISP si AutoCAD” (strcat ”VisualLISP/” s) → ”VisualLISP/AutoLISP si AutoCAD” (strcat) → ”” Funcţia SUBSTR

Page 81: Visual Lisp

Proiectare parametrizată asistată de calculator

82

Sintaxă:

(SUBSTR <şir> <poziţie> [ <lungime> ]) Extrage un subşir de caractere din şirul de caractere notat cu <şir>, începând cu poziţia <poziţie> şi cu un număr de <lungime> caractere. Dacă numărul de caractere nu este dat, se extrage subşirul din poziţia indicată până la sfârşitul şirului argumentului <şir>. Numerotarea caracterelor se face începând cu 1. Argumentele <poziţie> şi <lungime> trebuie să fie întregi strict pozitivi. Dacă poziţia indicată este mai mare decât lungimea şirului de caractere atunci funcţia returnează nil. Exemple: (setq s ”AutoLISP si AutoCAD”) (substr s 5 4) → ”LISP” (substr s 13 4) → ”Auto” (substr s 13 17) → ”AutoCAD” (substr s 10 2) → ”si” (substr s 25 4) → nil Observaţie: În cadrul şirurilor de caractere primul element (caracter) se află pe poziţia 1, spre deosebire de liste şi mulţimi de selecţie unde primul element se află pe poziţia 0. Funcţia STRLEN Sintaxă:

(STRLEN [ <şir1> [ <şir2> ... <şirn> ] ]) Funcţia strlen returnează un întreg care semnifică lungimea (numărul de caractere) al şirului de caractere argument. Dacă sunt prezente mai multe argumente atunci va fi returnat numărul total de caractere care le compun. În situaţia în care nu se indică argumente este returnată valoarea 0. Exemple: (strlen ”AutoLISP” ” si ” ”AutoCAD”) →19 (strlen ”LISP”) →4 (strlen ””) →0 (strlen) →0 Funcţia STRCASE Sintaxă:

Page 82: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

83

(STRCASE <şir> [ <ind> ])

Această funcţie permite generarea unei copii a argumentului <şir>, în care caracterele sunt modificate în majusculă sau minusculă în funcţie de valoarea argumentului opţional <ind>. Dacă <ind> este omis sau este evaluat prin nil, atunci toate caracterele şirului sunt convertite în majusculă, iar dacă <ind> există şi este diferit de nil atunci caracterele sunt transformate în litere mici. Exemple: (strcase ”AutoLISP - AutoCAD”) → ”AUTOLISP - AUTOCAD” (strcase ”AutoLISP - AutoCAD” T) → ”autolisp - autocad” Observaţie: Caracterele diferite de cele alfabetice nu sunt modificate de funcţia strcase. Funcţia WCMATCH Sintaxă:

(WCMATCH <şir> <model_căutare> ) Funcţia wcmatch returnează T dacă argumentul <şir> îndeplineşte criteriul de căutare impus de <model_căutare> sau nil în caz contrar. Ambele argumente sunt de tip şir de caractere. Specificaţiile de căutare (valorile pe care le poate lua <model_căutare>) sunt date în tabelul 2.6. Exemple: (wcmatch ”2” ”#”)→ T (wcmatch ”12” ”#”)→ nil (wcmatch ”a” ”@”)→ T (wcmatch ”abv” ”@”)→ nil (wcmatch ”a” ”.”)→ nil (wcmatch ”<” ”.”)→ T (wcmatch ”Desen” ”D*”)→T

;testează dacă ”Desen” are caracterul ”D” pe prima poziţie (wcmatch ”Desen” ”a*”)→nil

;testează dacă ”Desen” are caracterul ”a” pe prima poziţie (wcmatch ”a” ”?”)→ T (wcmatch ”abc” ”???”)→ T (wcmatch ”abv” ”?????”)→ nil (wcmatch ”Desen” ”~*s*”)→ nil

;testează dacă ”Desen” nu conţine caracterul ”s” (wcmatch ”Desen” ”*s*”)→ T

Page 83: Visual Lisp

Proiectare parametrizată asistată de calculator

84

;testează dacă ”Desen” conţine caracterul ”s” (wcmatch ”Desen” ”~*a*”)→ T

;testează dacă ”Desen” nu conţine caracterul ”a”

Tabelul 2.6

Caracter Specificaţie

# O singură cifră numerică

@ Un singur caracter alfabetic

. Un singur caracter diferit de alfanumeric

* Orice secvenţă de caractere

? Un singur caracter (alfanumeric sau special)

~ Dacă este prim caracter are efect: cu excepţia a ceea ce urmează

[...] Unul din caracterele incluse

[~...] Exceptând caracterele incluse

- Specificare interval în interiorul parantezelor

, Separă două pattern-uri

` Pentru a indica literal un caracter de control

Observaţie: Dacă se doreşte indicarea unor condiţii de căutare compuse se utilizează caracterul de separaţie virgulă. Pentru ca funcţia să returneze T trebuie să fie îndeplinit cel puţin un criteriu. Exemplu: (wcmatch ”Desen” ”???,~*s*,D*”)→ T ;testează dacă ”Desen” este format din trei caractere (nil), nu conţine caracterul ”s” (nil) şi începe cu caracterul ”D” (T). Rezultatul returnat va fi T.

Page 84: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

85

2.15 Funcţii pentru controlul afişării

2.15.1 Funcţii pentru citire/scriere din/în fişiere sau tastatură/ecran Majoritatea funcţiilor din această categorie au un parametru opţional de tip descriptor de fişier, notat cu <df>. Dacă acesta este prezent în apel (şi este un descriptor care identifică în mod corect un fişier deschis cu funcţia open) permite realizarea operaţiilor în fişierul aferent descriptorului. În cazul în care nu este prezent un descriptor de fişier la apelarea funcţiilor, se realizează afişarea rezultatelor în AutoCAD în zona prompter-ului Command:, iar în VLISP în fereastra Visual LISP Console. Funcţia PRIN1 Sintaxă:

(PRIN1 [ <expr> [ <df> ] ])

Prin1 afişează argumentul <expr> evaluat şi returnează valoarea acestuia (apelată fără argument, nu returnează nici o valoare). Argumentul poate fi o expresie simbolică sau în particular un şir de caractere. Dacă se precizează ca argument un şir care conţine caractere de control, funcţia nu le va evalua (expanda). După afişarea rezultatului, funcţia scrie automat caracterul ”\n” (linie goală). Exemple: 1. Afişare pe ecran (setq a 67.78) (setq b ’(x y)) (prin1 ’a) ;afişează A şi returnează A (prin1 a) ;afişează 67.78 şi returnează 67.78 (prin1 b) ;afişează (x y) şi returnează (x y) (prin1 ”LISP”) ;afişează ”LISP” şi returnează ”LISP” (prin1 ”\nLISP”) ;afişează ”\nLISP” şi returnează ”\nLISP” (prin1 " \nCalea este: \”d:\\studenti\\ppac\\aplicatii\”")

;afisează ”Calea este: \”d:\studenti\ppac\aplicatii\”” pe line noua şi ;returnează " \nCalea este: \”d:\\studenti\\ppac\\aplicatii\”")

(prin1) ;afişează o linie goală 2. Scriere în fişier (setq f (open ”EX.TXT” ”w”)) ;deschide fişierul

Page 85: Visual Lisp

Proiectare parametrizată asistată de calculator

86

(prin1 ”Exemplu prin1” f);scrie mesajul pe o linie în fişier şi îl returnează ;pe ecran (setq f (close f)) ;închide fişierul Observaţie: Funcţia prin1 poate fi apelată fără argumente, ca ultimă expresie într-o funcţie definită de programatori pentru quiet exit (ieşire fără a fi returnată o valoare). Funcţia PRINC Sintaxă:

(PRINC [ <expr> [ <df> ] ])

Această funcţie acţionează ca şi prin1 dar caracterele de control sunt tipărite cu expandare (sunt evaluate). Exemple: (setq a 67.78) (setq b '(x y)) (princ 'a) ;afişează A şi returnează A (princ a) ;afişează 67.78 şi returnează 67.78 (princ b) ;afişează (x y) şi returnează (x y) (princ "LISP") ;afişează "LISP" şi returnează "LISP" (princ "\nCalea este: \”d:\\studenti\\ppac\\aplicatii\”")

;afişează Calea este: ”d:\studenti\ppac\aplicatii” pe line noua şi returnează "\nCalea este: \”d:\\studenti\\ppac\\aplicatii\”"

(princ) ;afişează o linie goala Funcţia PRINT Sintaxă:

(PRINT [ <expr> [ <df> ] ])

Print acţionează ca şi prin1 (caracterele de control nu sunt expandate), dar este tipărită o linie nouă (un caracter ”\n”) înainte de <expr> şi un spaţiu după <expr>. Funcţia PROMPT Sintaxă:

(PROMPT <mesaj>)

Funcţia prompt returnează nil şi afişează <mesaj> pe ecran cu expandarea caracterelor de control. Argumentul <mesaj> este de tip şir de caractere.

Page 86: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

87

Exemple: 1. (prompt ”\nIntroduceti o valoare:”)

;returnează nil şi afişează mesajul pe linie nouă 2. (setq n 5) (setq f 120) (prompt (strcat ”\nFactorialul calculat este ” (itoa n) ”!=” (rtos f 2 0)))

;returnează nil şi afişează mesajul pe o linie nouă Observaţii: 1. Funcţia se recomandă a fi utilizată la afişarea mesajelor pe ecran (vezi exemplul 2 de mai sus) deoarece expandează caracterele de control şi afişează mesajele fără ghilimele. 2. Prompt nu afişează valorile în fereastra Visual LISP Console ci nu mai în zona prompter-ului Command:. Funcţia WRITE-LINE Sintaxă:

(WRITE-LINE <şir> [ <df> ])

Această funcţie scrie pe o linie de ecran, sau în fişier, argumentul <şir> (de tip string) între ghilimele, cu expandarea caracterelor de control. Exemple: 1. Afişare pe ecran

(write-line ”\nExemplu”) ; scrie pe ecran Exemplu şi returnează pe linia ; următoare ”\nExemplu”

2. Scriere în fişier (setq f (open ”EX.TXT” ”w”)) ;deschide fişierul (write-line ”\nExemplu write-line\n” f) ;scrie în fişier: prima linie goală,

;pe a doua linie Exemplu write-line şi a treia linie goală. (setq f (close f)) ;închide fişierul Observaţie: Scrierea fizică în fişiere se realizează atunci când acestea se închid cu funcţia close. Funcţia READ-LINE Sintaxă:

(READ-LINE [ <df> ])

Funcţia read-line citeşte un şir de caractere ce formează o linie, de la tastatură sau din fişier şi returnează şirul citit. Dacă citirea se face dintr-un fişier la atingerea sfârşitului de fişier returnează întotdeauna nil.

Page 87: Visual Lisp

Proiectare parametrizată asistată de calculator

88

Exemple: 1. Citire din fişierul EX.TXT creat la exemplul 2 de la funcţia write-line (setq f (open ”EX.TXT” ”r”)) ;deschide fişierul (if f ;dacă fişierul există (setq linie1 (read-line f) ;citeşte prima linie şi avansează

; pointer-ul de fişier pe linia următoare linie2 (read-line f) ; citeşte a doua linie şi avansează

; pointer-ul de fişier pe linia următoare linie3 (read-line f) ; citeşte a treia linie şi avansează

; pointer-ul de fişier pe linia următoare )

) (setq f (close f)) ;închide fişierul

După tastarea expresiilor de mai sus, linie1 şi linie3 vor conţine şirul vid (””) iar linie2 şirul ”Exemplu write-line”. 2. Citire de la tastatură (read-line) ;utilizatorul va introduce de la tastatură un şir Funcţia WRITE-CHAR Sintaxă:

(WRITE-CHAR <nr> [ <df> ])

Funcţia write-char scrie un caracter pe ecran sau în fişier, dat prin codul ASCII (în baza 10) din argumentul <nr>. Returnează codul ASCII al caracterului afişat. Exemple: (write-char 65) ;scrie caracterul A pe ecran şi returnează 65 (write-char 67) ;scrie caracterul C pe ecran şi returnează 67

(write-char 90 f) ;scrie caracterul Z în fişierul identificat prin f şi ;returnează 90

Funcţia READ-CHAR Sintaxă:

(READ-CHAR [ <df> ]) Read-char citeşte un singur caracter de la tastatură sau dintr-un fişier deschis anterior pentru citire de date, identificat prin argumentul <df>. Returnează codul ASCII, în baza 10, al caracterului citit.

Page 88: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

89

Exemplu: (read-char ) Expresia simbolică de mai sus, aşteptă introducerea de la tastatură a unuia sau a mai multor caractere. Dacă se introduce spre exemplu ABC urmat de enter, read-char citeşte primul caracter şi returnează 65 (codul ASCII al primului caracter). La următoarele trei apeluri ale funcţiei se vor returna automat codurile ASCII 66, 67 şi 10 (codul caracterului linie nouă). Abia la următorul apel al funcţiei se aşteaptă introducerea unor alte caractere. Datele introduse sunt păstrate în buffer-ul de intrare-ieşire. Observaţie: La citirea datelor din fişier, funcţia read-char returnează nil la atingerea sfârşitului de fişier.

2.15.2 Funcţii de gestionare a ecranului AutoCAD Funcţiile din această categorie comută ecranul AutoCAD-ului din mod text în mod grafic şi invers sau afişează pe ecran o linie nouă. Funcţia GRAPHSCR Sintaxă:

(GRAPHSCR)

Funcţia graphscr schimbă ecranul din mod text în mod grafic (acţionează ca şi tasta funcţională F2). Returnează întotdeauna nil. Funcţia TERPRI Sintaxă:

(TERPRI)

Funcţia tipăreşte pe ecran o linie nouă şi returnează nil. Terpri nu poate fi utilizată în cazul fişierelor. Pentru această acţiune se vor utiliza funcţiile AutoLISP: write-line, princ,prin1 sau print. Funcţia TEXTPAGE Sintaxă:

(TEXTPAGE)

Funcţia textpage comută ecranul din mod grafic în mod text. Returnează întotdeauna nil.

Page 89: Visual Lisp

Proiectare parametrizată asistată de calculator

90

Funcţia TEXTSCR Sintaxă:

(TEXTSCR)

Ca şi funcţia textpage comută ecranul din mod grafic în mod text (acţionează ca şi tasta funcţională F2). Funcţia returnează nil.

2.16 Funcţii pentru gestionarea fişierelor AutoLISP-ul, spre deosebire de alte limbaje de programare, permite accesul doar la fişiere text (ASCII). Introducerea (scrierea) şi extragerea (citirea) de date în/din fişiere text se realizează de regulă prin intermediul a două funcţii (prezentate anterior): read-line şi write-line. Deschiderea şi închiderea fişierelor în vederea scrierii, respectiv citirii de date, se controlează prin intermediul a două funcţii: open şi close. Funcţia OPEN Sintaxă:

(OPEN <nume_fişier> <mod>)

Funcţia open impune specificarea a două argumente: numele fişierului care urmează a fi deschis şi modul de acces la datele fişierului. Ambele argumente trebuie să fie de tip şir de caractere. Dacă operaţia de deschidere reuşeşte atunci funcţia returnează un atom de tip descriptor de fişier (forma lui fiind, de exemplu, #<file "c:\\studenti\\ppac\\aplicatii\\date.txt">). Dacă operaţia eşuează atunci este returnat atomul nil. Pentru a lucra în continuare cu fişierul, programatorul trebuie să memoreze descriptorul de fişier într-un simbol, deoarece este necesară indicarea acestuia ca argument al funcţiilor de citire/scriere. Dacă descriptorul nu este reţinut atunci nu pot fi prelucrate datele în/din fişier; mai mult, acesta nici măcar nu poate fi închis, deoarece la închiderea fişierului este necesar descriptorul de fişier. Descriptorul de fişier este de fapt fişierul logic, prin intermediul căruia se referă fişierul fizic într-un limbaj de programare. Numele fişierului, identificat în sintaxa funcţiei prin <nume_fişier>, este de tip şir de caractere, iar argumentul <mod> este constituit dintr-un caracter alfabetic. Nu se acceptă pentru argumentul <mod> majuscule pentru versiunile de AutoCAD anterioare AutoCAD-ului 2000. Acesta poate să aibă valorile prezentate în tabelul 2.7.

Page 90: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

91

Exemple: (setq f (open ”EX.TXT” ”w”))→ #<file "EX.TXT"> (setq f (open ”INEXIST.DTA” ”r”))→nil (setq f (open ”EX1.DAT” ”a”))→ #<file "EX1.DAT"> Observaţii: 1. Argumentul <nume_fişier> poate să conţină ca prefix şi calea până la fişierul care urmează a fi deschis. Calea poate să fie prefixată şi cu o unitate de disc. Subdirectoarele din aceasta trebuie separate prin slash (/) sau prin două backslash-uri (\\) conform interpretării caracterelor de control. 2. Nu pot fi deschise în vederea citirii sau scrierii datelor decât fişiere text. Exemple: (setq f (open ”d:/student/ppac/ex.txt” ”w”))→#<file"d:/student/ppac/ex.txt"> (setq f (open ”\\student\\inexist.dta” ”r”))→nil (setq f(open ”c:/teh/arbore.dat” ”a”))→#<file"c:/teh/arbore.dat ">

Tabelul 2.7

Mod de deschidere

Descriere

”r” Deschide fişierul pentru citire, pointer-ul de fişier este poziţionat pe primul caracter din fişier. Dacă <nume_fişier> nu există, se întoarce nil, nefiind permis accesul la citirea datelor.

”w”

Deschide fişierul pentru scriere. Dacă <nume_fişier> nu există, este creat un nou fişier şi este deschis pentru scriere. Dacă <nume_fişier> deja există, datele anterioare vor fi suprascrise.

”a”

Deschide fişierul pentru adăugare de date. Dacă <nume_fişier> nu există, este creat un nou fişier şi este deschis pentru scriere; iar dacă <nume_fisier> există deja, fişierul este deschis şi pointer-ul de fişier este poziţionat la sfârşitul acestuia, în acest fel datele pot fi adăugate în fişier după cele existente.

Funcţia CLOSE Sintaxă:

(CLOSE <df>)

Funcţia close închide un fişier deschis prin apelarea funcţiei open. Aceasta are un singur argument şi anume un descriptor de fişier valid. După apelare, close returnează nil dacă operaţia de închidere s-a realizat cu succes sau afişează un mesaj de eroare în caz contrar.

Page 91: Visual Lisp

Proiectare parametrizată asistată de calculator

92

Exemplu: (setq f (close f)) Deoarece descriptorul de fişier f nu mai este valabil după ce fişierul la care se referă este închis, exemplul atribuie variabilei f valoarea nil, acesta fiind modul recomandat de închidere a unui fişier. În acest fel, se eliberează memoria calculatorului, existând posibilitatea testării stării unui fişier (dacă este închis sau deschis) şi se asigură utilizarea corectă a variabilelor în program. Exemple: 1. Următorul exemplu permite citirea unui fişier text, cu un nume indicat de programator (DATE.TXT), afişând pe ecran conţinutul acestuia. (defun c:citdate ( / linie f) (setq linie "" ;se asigura intrarea in ciclu while f (open "date.txt" "r") ;se deschide fisierul pentru citirea datelor ) (if f ;daca exista fişierul (while linie ;atâta timp cat exista linie in fişier (setq linie (read-line f)) ;se citeşte o linie din fişier (if linie (write-line linie)(setq f (close f))) ;daca exista linie afişeaz-o pe ecran ) ;altfel închide fişierul (prompt "\n!!!!!FISIER INEXISTENT!!!") ;daca nu exista fişierul afişează mesajul ) (prin1) ;ieşire fără a fi returnata o valoare ) 2. Exemplul următor defineşte o nouă comandă AutoCAD care permite citirea unui fişier text, şi afişează conţinutul acestuia pe ecran. (defun c:citfis ( / nume linie f rep) (setq rep T) ;se asigura intrarea in primul ciclu while (while rep (setq nume ;se citeşte numele fişierului (getstring "\nIntroduceti numele fisierului [cu extensie]:")) (setq linie T ;se asigura intrarea in al doilea while f (open nume "r") ;se deschide fişierul pentru citirea datelor ) (if f ;daca exista fişierul (while linie ;atâta timp cat exista linie in fişier (setq linie (read-line f)) ;se citeşte o linie din fişier (if linie (write-line linie) (setq f (close f))) ;daca exista linie se afişează pe ecran (setq rep nil) ;se asigura ieşirea din primul ciclu while ) ;altfel închide fişierul (prompt (strcat ”\nFISIERUL ” nume ” ESTE INEXISTENT!!!”)) ;daca nu exista fişierul afiseaza mesajul ) ) (prin1) ;ieşire fără a fi returnata o valoare )

Page 92: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

93

Funcţia FINDFILE Sintaxă:

(FINDFILE <nume_fişier>)

Funcţia findfile permite utilizatorului să caute un fişier sau o cale existentă pe disc. Dacă numele fişierului este precedat de o anume cale atunci căutarea acestuia se realizează doar în subdirectorul respectiv. În cazul în care se specifică doar numele fişierului, acesta este căutat în căile de căutare curent setate în AutoCAD. Funcţia returnează sub forma unui şir de caractere, calea şi numele fişierului dacă acesta a fost găsit, sau nil dacă nu a fost găsit fişierul respectiv. Subdirectoarele din cale sunt separate de caracterul ”/” sau de caracterele ”\\”. Exemple: Să presupunem că:

subdirectorul din care este lansat AutoCAD-ul este D:\\Program Files\\MDT6;

desenul editat se găseşte în subdirectorul D:\\studenti\\ppac; fişierul DATE.DTA se găseşte în subdirectorul D:\\studenti\\ppac\\; fişierul INEXIST.LSP nu este pe disc.

Dacă se apelează findfile obţinem:

(findfile "ex.txt")→ "D:\\Program Files\\MDT6\\ex.txt" (findfile ”inexist.lsp”)→ nil (findfile "date.dta")→"D:\\studenti\\ppac\\date.dta" (findfile " D:\\studenti\\ppac")→"D:\\studenti\\ppac"

Observaţie: Dacă se indică doar o cale de căutare ca argument al funcţiei findfile şi aceasta există pe disc, atunci funcţia returnează calea respectivă. Funcţia GETFILED Sintaxă:

(GETFILED <titlu> <nume_fişier> <extensie> <mod>)

Funcţia getfiled generează o fereastră de dialog cu un antet dat de <titlu>, care conţine lista fişierelor disponibile pe disc, cu extensia dată în argumentul <extensie> şi cu fişierul implicit indicat de <nume_fişier>. Primele trei argumente din sintaxa funcţiei, sunt de tip şir de caractere, iar argumentul <mod> este de tip întreg şi poate să aibă una din valorile date în tabelul 2.8. Funcţia returnează numele fişierului (precedat de cale) specificat de utilizator sau nil. Subdirectoarele din cale sunt separate de caracterul ”/” sau de caracterele

Page 93: Visual Lisp

Proiectare parametrizată asistată de calculator

94

”\\”. Dacă utilizatorul nu indică un nume valid de fişier sau apasă butonul Cancel atunci getfiled returnează nil.

Tabelul 2.8

<mod> Semnificaţie

1

(bitul 0)

Cerere de creare a unui nou fişier; nu este indicată setarea acestui mod atunci când se doreşte deschiderea unui fişier existent pe disc.

4

(bitul 2)

Permite utilizatorului introducerea unui nume arbitrar (utilizat de regulă pentru indicarea extensiilor de fişiere); dacă se precizează o extensie anume, atunci aceasta nu mai poate fi modificată în fereastră, utilizatorul fiind obligat să aleagă un fişier existent pe disc.

8

(bitul 3)

Execută o căutare în căile curent setate în AutoCAD pentru fişierul cerut şi returnează doar numele fişierului respectiv; dacă fişierul este găsit într-un alt subdirector atunci este returnată şi calea.

16

(bitul 4)

Argumentul <nume_fişier> poate să conţină doar o cale de căutare pentru fişiere.

32

(bitul 5)

La alegerea unui fişier de pe disc, utilizatorul nu mai este avertizat de înlocuirea fişierului selectat, operaţia de înlocuire realizându-se în mod automat.

64

(bitul 6)

Nu transferă fişierul dacă utilizatorul specifică un URL.

128

(bitul 7)

Nu permite introducerea unui URL.

Exemple: 1. Expresia simbolică următoare:

Page 94: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

95

(getfiled ”Selectati un fisier lisp” ”d:\\Program Files\\mdt6\\support\\ex.lsp” ”LSP”8) va genera fereastra de dialog din figura 2.14, permiţând indicarea unui nume de fişier. 2. Următoarea expresia simbolică: (getfiled ”Creati un nou fisier” ” d:\\Program Files\\mdt6\\date” ”txt” 1) va genera fereastra de dialog din figura 2.15 ce va permite indicarea numelui unui nou fişier. Dacă utilizatorul alege de pe disc un fişier existent, AutoCAD-ul solicită, prin fereastra din figura 2.16, validarea operaţiei de modificare a conţinutului fişierului. 3. Expresia simbolică următoare: (getfiled ”Selectati un fişier desen” ”d:/Program Files/mdt6/sample/exemplu” ”dwg” 8) generează fereastra de dialog din figura 2.17, care permite indicarea unui nume de fişier desen (cu extensia DWG). Observaţii: 1. Dacă extensia este indicată ca fiind şirul vid (””) atunci aceasta este considerată ca fiind oricare (*) iar în fereastră sunt prezentate numele tuturor fişierelor (All files). 2. În situaţia în care la apelare se indică extensia DWG, fereastra de dialog conţine o zonă de previzualizare a fişierelor existente pe disc (cele care au extensia DWG).

Fig. 2.14 Fereastră de dialog generată la apelarea funcţiei getfiled cu valoarea 8 pentru <mod>.

Page 95: Visual Lisp

Proiectare parametrizată asistată de calculator

96

Fig. 2.15 Fereastră de dialog generată la apelarea funcţiei getfiled cu valoarea 1 pentru <mod>.

Fig. 2.16 Fereastră de dialog pentru validarea operaţiei de înlocuire a fişierului.

Fig. 2.17 Fereastră de dialog generată la apelarea funcţiei getfiled cu valoarea 1 pentru <mod> şi cu extensia DWG.

Page 96: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

97

2.17 Accesul la entităţile desenelor În AutoCAD, oricărei entităţi generate într-o sesiune de editare îi este pus în corespondenţă un nume de entitate, atribuit în mod automat de sistem. Numele de entitate este utilizat la identificarea entităţilor AutoCAD. Un nume de entitate se poate schimba de la o sesiune de editare la alta, dar fiecare nume de entitate este întotdeauna acelaşi (unic) într-o sesiune de editare. Acesta este un atom special de forma <Entity name:xxxxxxx> (unde xxxxxxx este un număr hexazecimal). Numele de entităţi pot fi utilizate în AutoCAD, de regulă ca răspunsuri la prompter-ul Select objects: . Nu se acceptă specificarea numelor de entităţi, prin scrierea lor de la tastatură. Sunt predefinite funcţii care permit aflarea numelor de entităţi prin parcurgerea bazei de date a AutoCAD-ului sau prin selectare, de către utilizator, a anumitor entităţi. În AutoCAD se întâlnesc două categorii de entităţi: entităţi principale şi entităţi secundare. Entităţile principale sunt clasificare în: entităţi AutoCAD simple (linie, cerc, arc de cerc, punct, solid, text, trace, etc) şi entităţi compuse (bloc sau polilinie 3D). Entităţile secundare sunt constituite din subentităţile care fac parte din entităţile compuse. Entitatea compusă e caracterizată de un nume de entitate care o identifică în întregime şi mai multe nume de entităţi care identifică subentităţile (entităţile secundare). Funcţia ENTLAST Sintaxă:

(ENTLAST)

Funcţia entlast returnează numele ultimei entităţi principale neşterse din baza de date a desenului. Este utilizată de regulă pentru a obţine numele unei noi entităţi (ultima) generate cu ajutorul funcţiei command. Exemplu: Exemplul de mai jos permite ştergerea ultimei entităţi desenate în AutoCAD. (setq ne (entlast)) (command ”erase” ne ””) Funcţia ENTNEXT Sintaxă:

(ENTNEXT [ <nume_ent> ])

Page 97: Visual Lisp

Proiectare parametrizată asistată de calculator

98

Dacă este apelată fără argument, funcţia returnează numele primei entităţi neşterse din baza de date a desenului. Dacă entnext este apelată cu un parametru de tip nume de entitate, atunci returnează numele entităţii (neşterse) din baza de date poziţionată imediat după argumentul <nume_ent>. În cazul în care nu există o următoare entitate după entitatea desemnată de argument, funcţia returnează nil. Entnext returnează atât nume de entităţi principale cât şi de entităţi secundare (subentităţi). Exemple: 1. Exemplul de mai jos permite ştergerea primelor două entităţi desenate în AutoCAD (dacă acestea sunt entităţi principale). (setq ne1 (entnext) (setq ne2 (entnext e1) (command ”erase” ne1 ne2 ””) 2. Următorul exemplu parcurge întreaga bază de date a desenului şi afişează numărul şi numele entităţii, indiferent dacă acestea sunt principale sau secundare. (defun c:contor (/ ne k) (setq k 1 ;se initializeaza contorul ne (entnext) ;se preia numele primei entitati ) (while ne (prompt (strcat "\n Numar entitate:" (itoa k))) ;se afiseaza numarul entitatii (prompt "\n Nume entitate:") (prin1 ne) ;se afiseaza numele entitatii (setq ne (entnext ne) ;se preia numele urmatoarei entitati k (1+ k) ;se mareste contorul ) ) (prin1) ) 3. În cazul în care se doreşte aflarea ultimei entităţi trasate, indiferent dacă este principală sau secundară, se defineşte următoarea funcţie: (defun c:ultimaent (/ neu nsb) (if (setq neu (entlast)) ;se preia numele ultimei entitati principale (while (setq nsb (entnext neu));daca exista subentitate parcurge while ; până când nu mai există subentitate (setq neu nsb) ; se preia numele subentitatii ) ) neu ;returnează numele ultimei entitati principale sau al subentitatii )

Page 98: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

99

Funcţia ENTSEL Sintaxă:

(ENTSEL [ <mesaj> ])

Funcţia entsel este utilizată pentru aflarea numelui unei entităţi selectate de utilizator. Returnează o listă formată din două elemente: numele entităţii selectate şi lista care materializează punctul în care aceasta a fost selectată, adică (<nume_ent> (x y z)). Dacă argumentul opţional <mesaj> (de tip şir de caractere) este indicat, acesta va fi afişat înaintea selectării entităţii, în caz contrar este generat automat mesajul Select objects:. Funcţia acţionează numai pentru entităţi principale. Dacă prin punctul indicat nu trece o entitate atunci este returnat nil. Exemplu: Exemplul de mai jos permite selectarea unei entităţi şi afişează numele şi punctul de selectare al acesteia. Dacă nu este selectată o entitate, funcţia afişează un mesaj şi permite din nou selectarea unei entităţi. (defun c:exsel (/ ne lp lista) ;simbolurile din program reprezintă: ne-numele entităţii ; lp-lista punctului de selectare ; lista-lista returnată de entsel (while (not lista) (setq lista (entsel "\nSelectati o entitate:")) ;se preia lista returnată (if lista ;dacă s-a selectat o entitate (progn (setq ne (car lista) ;se preia numele entităţii lp (cadr lista) ;se preia punctul de selectare ) (prompt "\nNumele entitatii selectate este:") (prin1 ne) ;se afişează numele entităţii (prompt "\nPunctul de selectare este:") (prin1 lp) ;se afişează punctul de selectare ) (prompt "\nNu ati selectat o entitate!!! Mai incercati!!") ) ) (prin1) ) Observaţie: La selectarea entităţii prin intermediul funcţiei entsel, modurile OSNAP setate permanent în AutoCAD, nu sunt luate în considerare. Funcţia NENTSEL

Page 99: Visual Lisp

Proiectare parametrizată asistată de calculator

100

Sintaxă:

(NENTSEL [ <mesaj> ])

Funcţia nentsel permite aflarea numelui unei entităţi principale sau secundare selectate de utilizator. Aceasta returnează o listă formată din numele entităţii selectate şi lista punctului în care entitatea a fost selectată, adică o listă de forma: (<nume_ent> (x y z)) pentru entităţile principale sau (<nume_subent> (x y z)) pentru entităţile secundare. Dacă argumentul opţional <mesaj> (de tip şir de caractere) este specificat, va fi afişat înaintea selectării entităţii, în caz contrar este generat automat mesajul Select objects:. Dacă prin punctul dat de utilizator, nu trece nici o entitate, atunci se returnează valoarea nil. Observaţii: 1. La selectarea entităţii prin intermediul funcţiei nentsel, modurile OSNAP setate permanent în AutoCAD, nu sunt luate în considerare. 2. Dacă entitatea selectată este o polilinie de tip lightweight (lwpolyline), atunci ea este recunoscută de nentsel ca o singură entitate. Funcţia NENTSELP Sintaxă:

(NENTSELP [ <mesaj> ] [ <pct> ])

Această funcţie acţionează ca şi nentsel, în plus argumentul <pct> este lista unui punct de pe entitate. Funcţia returnează şi matricea standard de transformare 4x4. Numele unei entităţi AutoCAD se poate schimba de la o sesiune de editare la alta. Există totuşi un identificator, denumit handle, care rămâne neschimbat (în orice sesiune de editare) atâta timp cât entitatea există în desen. Gestionarea acestor identificatori poate fi realizată cu ajutorul funcţiei handent. Funcţia HANDENT Sintaxă:

(HANDENT <şir>)

Funcţia returnează numele entităţii, din sesiunea curentă de editare, asociată argumentului <şir> care este handle-ul (de tip şir de caractere). Odată obţinut, numele entităţii poate fi utilizat ca argument al funcţiilor din familia ENTXXX (anterior prezentate). Dacă şirul specificat ca argument nu identifică o entitate, funcţia returnează nil.

Page 100: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

101

Exemplu: (handent "2B")) ;poate să returneze <Entity name: 40063d58> în sesiunea curentă de editare. Utilizând aceeaşi expresie simbolică în acelaşi desen AutoCAD, într-o altă sesiune de editare, se poate obţine un alt nume de entitate. Deci identificatorul de tip handle este acelaşi, pentru o entitate, în orice sesiune de editare. Funcţia handent poate să returneze şi numele entităţilor şterse în sesiunea curentă de editare, existând astfel posibilitatea readucerii acestora în desen cu ajutorul funcţiei entdel (prezentată în subcapitolul 2.18).

2.18 Accesul la datele asociate entităţilor AutoCAD

Cu ajutorul numelui unei entităţi, programatorii pot obţine caracteristicile entităţii identificate de acesta. În AutoLISP datele caracteristice entităţilor sunt memorate sub forma unor liste asociate. Listele asociate conţin atât liste normale cât şi liste speciale denumite perechi cu punct (dotted pairs).

2.18.1 Perechile cu punct în AutoLISP O pereche cu punct este o listă de o formă specială care conţine două elemente de tip atom. Întotdeauna, pe ramura cdr (din dreapta) a arborelui binar (aferentă unei perechi cu punct) se găseşte un element diferit de nil. Atât listele normale, cât şi perechile cu punct sunt utilizate în listele asociate entităţilor, pentru reprezentarea codurilor DXF şi a valorilor aferente acestora. Primul element al unei perechi cu punct poate fi obţinut ca şi cel al unei liste normale, cu funcţia car. Al doilea element poate fi obţinut direct cu funcţia cdr. Se observă uşor că al doilea element al unei liste normale se obţine într-un mod diferit. Forma generală a unei perechi cu punct este următoarea:

(<e1> . <e2>). Se remarcă faptul că cele două elemente sunt separate de punct, iar înainte şi după punct, există întotdeauna spaţiu. Exemple: 1. (8 . ”0”)

Page 101: Visual Lisp

Proiectare parametrizată asistată de calculator

102

2. (0 . ”LINE”) În figura 2.18 se prezintă arborii binari pentru două obiecte similare: o listă normală şi o pereche cu punct, ambele conţinând aceleaşi elemente.

Fig. 2.18 Arborii binari pentru o listă normală şi o pereche cu punct.

Perechile cu punct pot fi generate prin: îngheţarea mecanismului de evaluare (prin apelarea funcţiei quote) sau cu ajutorul funcţiei cons.

Prin îngheţarea mecanismului de evaluare: Exemplu: (setq pp ’(0 . ”LINE”)) Observaţie: A nu se uita spaţiile înainte şi după punctul care separă cele două elemente ale unei perechi cu punct.

Prin utilizarea funcţiei CONS:

Funcţia CONS Sintaxă:

(CONS <e1> <e2>)

Funcţia cons este utilizată pentru generarea perechilor cu punct sau a unor liste normale. Dacă argumentul <e2> este o listă, se generează lista formată din elementele lui <e2> cu <e1> inserat pe prima poziţia a listei. Dacă atât <e1> cât şi <e2> sunt atomi atunci este generată automat perechea cu punct (<e1> . <e2>). Exemple: (setq pp (cons 0 ”LINE”))→ (0 . ”LINE”)

( )

(”LINE”)

(0 ”LINE”)

0

”LINE”

”LINE”

(0 . ”LINE”)

0

Page 102: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

103

(setq ln (list 0 ”LINE”))→ (0 ”LINE”) (car pp)→0 (car ln)→0 (cdr pp)→ ”LINE” (cdr ln)→ (”LINE”) (cons 5 ’(6 7 8 9))→ (5 6 7 8 9) (cons ’(5) ’(6 7 8 9))→ ((5) 6 7 8 9)

2.18.2 Liste asociate entităţilor Listele asociate entităţilor AutoCAD, se prezintă sub forma unor liste AutoLISP complexe, formate din subliste normale şi perechi cu punct. Au următoarea formă generalizată:

( ...(codDXF [ . valoare ]/[ lista ]) ...) Exemplu: Pentru o entitate de tip linie, lista asociată cu datele asociate obligatorii, are următoarea formă: ((-1 . <Entity name: .......>) ; numele entităţii (0 . ”LINE”) ; tipul entităţii (5 . ”2F”) ; handle-ul (8 . ”0”) ; layer-ul

(67 . 0) ; spaţiul în care este entitatea (100 . "AcDbLine") ; marcatorul de subcalsă (410 . "Model") ; numele layout-ului

(10 20.0 40.0 60.0) ; punctul de start (11 30.0 70.0 80.0) ; punctul final (210 0.0 0.0 1.0) ; direcţia de extruziune )

Primul element al fiecărei subliste este cheia sau codul DXF al acesteia, elementele rămase sunt datele asociate secţiunii determinate de cheie. În exemplul dat, cheia primei subliste este întregul -1, data aferentă acestei chei este numele entităţii. Cheia celei de a doua subliste este atomul 0, iar data asociată este tipul entităţii. În tabelul 2.9 sunt prezentate codurile DXF pentru o entitate de tip linie, iar în Anexa acestei lucrări sunt prezentate codurile principalelor entităţi grafice utilizate în liste asociate.

Tabelul 2.9

Codul DXF Data asociată

Page 103: Visual Lisp

Proiectare parametrizată asistată de calculator

104

-1 Numele entităţii 0 Tipul entităţii (Line, Arc, Circle, etc) 5 Handle-ul entităţii 8 Layer-ul de apartenenţă 67 Spaţiul (Model/Paper) în care se găseşte

entitatea 100 Marcatorul de subclasă 410 Numele Layout-ului 10 Punctul de start 11 Punctul final

210 Direcţia de extruziune Lista asociată oricărei entităţi poate fi obţinută cu ajutorul funcţiei entget. Funcţia ENTGET Sintaxă:

(ENTGET <nume_ent> [ <lista-aplic> ])

Funcţia entget necesită un argument obligatoriu, care specifică numele entităţii pentru care se doreşte extragerea listei asociate din baza de date a AutoCAD-ului. Exemplu: Dacă se trasează în layer-ul 0 o linie din punctul 10,10 până în punctul 100,100 atunci se poate obţine lista asociată acestei entităţi prin expresiile: (setq ne (entlast)) (setq lasoc (entget ne)) Simbolul lasoc va avea atribuită o listă asociată de genul: ((-1 . <Entity name: 40063d78>)

(0 . "LINE") (330 . <Entity name: 40063cf8>) (5 . "2F") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbLine") (10 10.0 10.0 0.0) (11 100.0 100.0 0.0) (210 0.0 0.0 1.0)

Page 104: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

105

) Observaţie: Funcţia entget acceptă un al doilea parametru opţional (<lista-aplic>), care permite obţinerea datelor extinse. În subcapitolul 2.21 al prezentei lucrări, va fi tratat conceptul de date extinse şi se va reveni asupra funcţiei. Extragerea unei subliste sau a unei perechi cu punct dintr-o listă asociată este realizabilă prin apelarea funcţiei assoc. Funcţia ASSOC Sintaxă:

(ASSOC <cod> <1ista_asoc>)

Funcţia necesită două argumente şi anume: <cod> care este cheia ce permite identificarea sublistei din cel de al doilea argument <1ista_asoc>, care conţine o listă asociată unei entităţi. Assoc returnează întotdeauna o listă sau o pereche cu punct. Pentru a obţine datele aferente unei chei se va aplica cdr pe rezultatul returnat de funcţia assoc. Dacă codul DXF indicat în sintaxa de apel a funcţiei assoc nu există în lista asociată, atunci este returnat atomul nil. Exemplu: (setq lasoc (entget (entlast))) ;returnează lista asociată ultimei entităţi (assoc 8 lasoc) ;returnează perechea (8 . ”nume-layer”) (setq numelayer (cdr (assoc 8 lasoc))) ;returnează numele layer-ului (setq tipent (cdr (assoc 0 lasoc))) ;returnează tipul entităţii Observaţie: Funcţia assoc poate fi utilizată şi pentru extragerea datelor dintr-o listă de liste normale şi/sau perechi cu punct. Exemplu: (setq supraf ’((tip . ”CILINDRICA”) (dia . 123.4) (aid . -0.05) (asd . 0.05) (lung . 50.0) (ail . 0) (asl . 0) (rugo . 1.6))) (assoc ’tip supraf) →(tip . ”CILINDRICA”) (cdr (assoc ’tip supraf)) → ”CILINDRICA” (setq d1 (cdr (assoc ’dia supraf))) → 123.4 (setq rug (cdr (assoc ’rugo supraf))) → 1.6 Modificarea entităţilor AutoCAD din AutoLISP se realizează în două etape:

preluarea listei asociate entităţii şi modificarea acesteia cu ajutorul funcţiei subst;

Page 105: Visual Lisp

Proiectare parametrizată asistată de calculator

106

reactualizarea entităţii, în baza de date, aplicând funcţia entmod asupra noii liste asociate. Funcţia ENTMOD Sintaxă:

(ENTMOD <1ista_asoc>)

Funcţia necesită argumentul <1ista_asoc> (care reprezintă noua listă asociată entităţii de modificat) şi actualizează entitatea (cu noua lista asociată) în baza de date a desenului (inclusiv pe ecran), returnând lista asociată sau nil în cazul unei liste asociate invalide. Observaţii: 1. Funcţia entmod poate modifica atât entităţi grafice cât şi nongrafice. 2. Entmod nu poate modifica tipul entităţii, numele entităţii şi handle-ul entităţii. 3. Nu poate fi utilizată pentru entităţi de tip viewport. Exemple: 1. Se trasează o linie în AutoCAD şi apoi se tastează expresiile simbolice de mai jos care modifică punctul de final al liniei în 100,100,0. (setq ne (entlast)) ;se preia numele ultimei entităţi trasate (setq la (entget ne)) ;se preia lista asociată ultimei entităţi trasate (setq lamod (subst ’(11 100 100 0) (assoc 11 la) la )) ;se generează noua listă asociată entităţii modificate (entmod lamod) ;se modifică entitatea 2. Se trasează un cerc în AutoCAD şi apoi se tastează expresiile simbolice de mai jos care modifică raza cercului (noua rază va fi 35) şi centrul acestuia în punctul 100,100,0. (setq ne (entlast)) ;se preia numele ultimei entităţi trasate (setq la (entget ne)) ;se preia lista asociată ultimei entităţi trasate (setq lamod (subst ’(10 100 100 0) (assoc 10 la) la )) (setq lamod (subst (cons 40 35) (assoc 40 lamod) lamod )) ;se generează noua listă asociată entităţii modificate (entmod lamod) ;se modifică entitatea 3. Următorul exemplu preia toate entităţile din baza de date a desenului şi modifică pentru entităţile de tip linie, layer-ul în care sunt desenate (în layer-ul existent ”L1”). (defun c:mod (/ ne nou lasoc) (setq ne (entnext) ;se preia prima entitate nou (cons 8 ”L1”)) ;se generează perechea cu punct

Page 106: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

107

(while ne ;cat timp există entitate (setq lasoc (entget ne)) ;se preia lista asociată (if (= (cdr (assoc 0 lasoc)) ”LINE”) ;dacă entitatea este linie (entmod (subst nou (assoc 8 lasoc) lasoc));se reactualizează ) (setq ne (entnext ne));se trece pe următoarea entitate din desen ) (prin1) ) Ştergerea entităţilor AutoCAD din AutoLISP, cu acces direct la baza de date, se realizează cu ajutorul funcţiei entdel. Funcţia ENTDEL Sintaxă:

(ENTDEL <nume_ent>)

Funcţia entdel necesită un argument <nume_ent> care reprezintă numele entităţii care va fi ştearsă din desenul curent sau al entităţii care va fi readusă pe ecran dacă aceasta a fost ştearsă anterior în sesiunea curentă de editare. Această funcţie acţionează numai pe entităţi principale. Exemplu: (setq e1 (entlast))

;se preia în simbolul e1 numele ultimei entităţi desenate (entdel e1) ;se şterge entitatea identificată prin e1 (entdel e1) ;se readuce pe ecran entitatea ştearsă e1 Funcţia ENTUPD Sintaxă:

(ENTUPD <nume_ent>)

Funcţia reactualizează pe ecran imaginea unei entităţi compuse (polilinie 3D sau bloc) după ce au fost modificate (cu entmod) subentităţi componente. Valoarea returnată este numele entităţii compuse dacă a fost realizată operaţia de reactualizare a entităţii sau nil în caz contrar. Exemplu:

Page 107: Visual Lisp

Proiectare parametrizată asistată de calculator

108

Se trasează o polilinie 3D în AutoCAD şi apoi se tastează expresiile simbolice de mai jos care modifică punctul primului vertex al poliliniei în 100,50,0. (setq e1 (entlast)) ;se preia numele ultimei entităţi trasate (setq e2 (entnext e1)) ;se preia numele primei subentităţi (vertex) din polilinie (setq la (entget e2)) ;se preia lista asociată primului vertex (setq la (subst '(10 100.0 50.0 0.0) (assoc 10 la) ;se modifică lista asociată la ) ) (entmod la) ;se mută vertexul în desen (entupd e1) ;se regenerează polilinia AutoLISP-ul permite programatorilor generarea entităţilor AutoCAD în mod direct, fără apelarea funcţiei command, prin specificarea listei asociate entităţii respective (care va fi generată) ca argument al funcţiilor entmake sau entmakex. Funcţia ENTMAKE Sintaxă:

(ENTMAKE <1ista_asoc>)

Dacă entitatea dată de argumentul <1ista_asoc> este creată cu succes, atunci funcţia entmake returnează lista asociată (indicată ca argument), iar dacă entitatea nu poate fi creată (deoarece lista asociată nu este corectă) se returnează nil. O metodă de creare a unei noi entităţi, constă în obţinerea mai întâi, cu ajutorul funcţiei entget, a listei asociate unei entităţi existente în desen de acelaşi tip cu noua entitate, modificarea acesteia cu datele caracteristice noii entităţi şi apoi adăugarea în desen a entităţii cu funcţia etnmake, care va avea ca argument noua listă asociată. Înainte de a crea o entitate nouă, entmake verifică dacă numele layer-ului este valid, dacă numele tipului de linie şi al culorii sunt cunoscute. Dacă un nou nume de layer este introdus, atunci funcţia creează automat layer-ul. Exemplu: Următoarea expresie simbolică, generează o nouă entitate AutoCAD cu următoarele proprietăţi: de tip ”LINE”, layer-ul de apartenenţă ”NOU”, cu punct de start 1.0,1.0,0.0 şi punct final 100.0,100.0,0.0 . (entmake

Page 108: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

109

’((0 . ”LINE”) (8 . ”NOU”) (10 1.0 1.0 0.0) (11 100.0 0.0 0.0)) ) → ((0 . "LINE") (8 . "NOU") (10 1.0 1.0 0.0) (11 100.0 0.0 0.0)) Observaţii: 1. Perechile cu punct (-1 . <Entity name: .......> şi (5 . ”.....”) sunt generate automat de către AutoCAD, dacă ele apar în lista asociată, atunci ele sunt ignorate de comandă. 2. Perechile cu punct ce au codul DXF 100 sunt ignorate de entmake pentru majoritatea categoriilor de entităţi AutoCAD. 3. Funcţia poate fi utilizată pentru entităţi grafice şi nongrafice. Funcţia ENTMAKEX Sintaxă:

(ENTMAKEX <1ista_asoc>)

În cazul în care entitatea descrisă prin lista asociată <1ista_asoc>, specificată ca argument al funcţiei entmakex, este creată cu succes, se returnează numele acesteia (<Entity name: .......>), iar dacă entitatea nu poate fi creată (deoarece lista asociată nu este corectă) se returnează nil.

Funcţia poate fi utilizată atât pentru entităţi grafice cât şi pentru entităţi nongrafice.

Exemplu: Următoarea expresie simbolică generează o nouă entitate AutoCAD cu următoarele proprietăţi: tip entitate ”CIRCLE”, layer-ul de apartenenţă ”0”, cu punct de centru 100.0,100.0,0.0 şi rază 35.5 . (entmakex ’((0 . ”Circle”) (8 . ”0”) (10 100.0 100.0 0.0) (40 . 35.5)) ) ;returnează un nume de entitate

Page 109: Visual Lisp

Proiectare parametrizată asistată de calculator

110

2.19 Funcţii pentru crearea şi utilizarea mulţimilor de selecţie În AutoCAD entităţile pot fi grupate în mulţimi de selecţie (selection sets). Mulţimile de selecţie sunt atomi speciali de forma: <Selection set: xxx>. Comenzile AutoCAD şi funcţiile AutoLISP pot utiliza mulţimile de selecţie, în acest fel intervenindu-se global asupra tuturor entităţilor conţinute într-o mulţime de selecţie. În AutoCAD, mulţimile de selecţie se folosesc în cadrul comenzilor ce utilizează prompter-ul Select objects: . Chiar dacă o mulţime de selecţie este un atom, aceasta este creată ca o colecţie de nume de entităţi. AutoLISP-ul poate lucra cu maxim 128 de mulţimi de selecţie, deschise în acelaşi timp. Numărul poate fi uneori mai mic, acesta depinde de configuraţia de calcul folosită şi de mărimea mulţimilor de selecţie. De obicei se asociază câte un simbol fiecărei mulţimi de selecţie care se creează sau se modifică; în caz contrar nu este posibil accesul la mulţimea de selecţie şi nu există nici o modalitate de a elibera resursele sistemului care o utilizează (până la ieşirea definitivă din AutoCAD). Se recomandă ca, în momentul în care o mulţime de selecţie nu mai este utilizată în aplicaţie, să se atribuie forţat simbolului aferent valoarea nil, eliberându-se în acest fel memoria ocupată. AutoLISP-ul conţine o serie de funcţii pentru crearea şi gestionarea mulţimilor de selecţie, care sunt prezentate în continuare. Funcţia SSGET Sintaxă:

(SSGET [<mod>] [[<pct1>] [<pct2>] [lista_puncte] [lista_filtre]])

Funcţia ssget, creează returnează o mulţime de selecţie. Argumentul opţional <mod> este un şir de caractere care specifică metoda de selectare a entităţilor şi poate să ia valorile prezentate în tabelul 2.10. Argumentele opţionale <pct1>, <pct2> şi <lista_puncte> sunt puncte care completează metoda de selectare. Dacă se specifică un punct fără un argument <mod>, atunci va fi selectată entitatea care trece prin acel punct (ca la selectarea individuală a entităţilor în AutoCAD). Modurile osnap sunt ignorate de această funcţie. Dacă toate argumentele din sintaxa funcţiei ssget sunt omise, atunci utilizatorul va fi cel care va forma mulţimea de selecţie, în mod interactiv, pe prompter-ul Select objects:, afişat automat de mediu. În acest caz poate fi utilizată orice metodă de selectare cunoscută în AutoCAD.

Page 110: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

111

Parametrul opţional <lista_filtre> este o listă de perechi cu punct sau liste normale în care apar coduri DXF. Acest parametru este utilizat pentru filtrarea entităţilor din AutoCAD care satisfac anumite condiţii. Tabelul 2.10

Metoda de selectare Semnificaţia ”L” Selectarea ultimei entităţi desenate (last). ”P” Selectarea tuturor entităţilor indicate în cadrul

mulţimii anterioare de selecţie.

”W” Selectarea tuturor entităţilor care se găsesc în întregime în fereastra delimitată de argumentele <pct1> şi <pct2> (Window).

”WP”

Selectarea tuturor entităţilor care se găsesc în întregime în poligonul descris prin argumentul <lista_puncte> şi (Window Polygon).

”C”

Selectarea tuturor entităţilor conţinute şi a celor care ating (traversează) fereastra delimitată de argumentele <ptc1> şi <pct2> (Crossing).

”CP”

Selectarea tuturor entităţilor conţinute şi a celor care traversează (ating) poligonul descris prin argumentul <lista_puncte> şi (Crossing Polygon)

”F”

Selectarea tuturor entităţilor care traversează (ating) conturul descris prin argumentul <lista_puncte> şi (Fence)

”X”

Selectarea tuturor entităţilor din desen, dacă nu apare o listă de filtre, vor fi selectate toate entităţile care satisfac condiţiile impuse de lista de filtre.

Exemple: (ssget) ;solicită utilizatorului formarea mulţimii de selecţie (ssget ”L”) ;selectează ultima entitate adăugată în baza de date (ssget ”P”) ;selectează entităţile indicate la formarea ultimei mulţimi de selecţie (ssget ”W” ’(1.0 2.0) ’(20.0 10.0)) ;selectează toate entităţile aflate în întregime în fereastra determinată (ssget ”WP” (list ’(1.0 2.0) ’(20.0 10.0) ’(150.0 50.0) ’(20.0 80.0))) ;selectează toate entităţile aflate în întregime în poligonul determinat - ;de punctele 1,2 20,10 150,50 şi 20 80

Page 111: Visual Lisp

Proiectare parametrizată asistată de calculator

112

(ssget ”C” ’(1.0 2.0) ’(20.0 10.0)) ;selectează toate entităţile conţinute şi a celor care ating fereastra ;determinată de punctele 1,2 şi 20,10 (ssget ”CP” (list ’(1.0 2.0) ’(20.0 10.0) ’(150.0 50.0) ’(20.0 80.0))

’((0 . ”LINE”))) ;selectează toate entităţile aflate în întregime sau care ating poligonul ;determinat de punctele 1,2 20,10 150,50 20 80 şi sunt linii (ssget ”F” (list ’(1.0 2.0) ’(20.0 10.0) ’(150.0 50.0) ’(20.0 80.0))) ;selectează toate entităţile care ating conturul delimitat de ;punctele 1,2 20,10 150,50 şi 20 80 (ssget ’(100.0 20.0)) ;selectează entitatea care trece prin punctul 100,20 (ssget ”X”) ;selectează toate entităţile din baza de date a desenului (ssget ”X” ’((0 . ”LINE”))) ;selectează toate entităţile de tip linie din desen (ssget ”X” (list (cons 0 ”CIRCLE”))) ;selectează toate cercurile din desen (ssget ”X” (list (cons 0 ”LINE”) (cons 8 ”L1”))) ;selectează toate entităţile de tip linie care se găsesc în layer-ul L1

(ssget "X" (list (cons 0 "ARC") (cons 8 ”EXEMPLU”)(cons 62 1))) ;selectează toate entităţile de tip arc care se găsesc în layer-ul EXEMPLU ;şi sunt de culoare RED (codul 1)

Prin intermediul codului -4 pot fi realizate grupări logice în lista de filtre. Operatorii logici utilizaţi sunt următorii: <AND........AND> (pentru mai mulţi operanzi), <OR........OR> (pentru mai mulţi operanzi), <XOR........XOR> (pentru doi operanzi) şi <NOT........NOT> (pentru un operand). Operatorii sunt specificaţi ca şiruri de caractere majusculă. Exemplu:

(ssget ”X” ’((-4 . ”<OR”) (-4 . ”<AND”) (0 . ”CIRCLE”) (40 . 20.0) (-4 . ”AND>”) (-4 . ”<AND”) (0 . ”LINE”) (8 . ”L1”) (-4 . ”AND>”) (-4 . ”OR>”)) );selectează toate cercurile din desenul curent cu raza de 20.0 şi toate liniile din layer-ul ”L1”

Page 112: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

113

Observaţii: 1. Mulţimile de selecţie returnate de ssget sunt formate numai din numele aferente entităţilor principale. 2. O mulţime de selecţie poate să conţină atât entităţi din spaţiul model cât şi entităţi din hârtie. Când o mulţime de selecţie este utilizată într-o operaţie, ssget elimină temporar entităţile din spaţiul care nu este curent. Funcţia SSLENGTH Sintaxă:

(SSLENGTH <m_sel>)

Această funcţie returnează un întreg care semnifică numărul de entităţi conţinute în mulţimea de selecţie indicată ca argument. Dacă numărul de entităţi este mai mare decât limita maximă a tipului de dată întreg, atunci data returnată este de tip real. Exemplu:

(setq s1 (ssget ”L”)) ;generează o mulţime de selecţie formată din ;ultima entitate desenată

(sslength s1)→1 ;returnează numărul de elemente din mulţime Funcţia SSNAME Sintaxă:

(SSNAME <m_sel> <index>)

Funcţia ssname returnează numele entităţii din mulţimea <m_sel>, identificată prin parametrul <index>. Numerotarea entităţilor într-o mulţime de selecţie se face începând cu zero. Dacă <index> este negativ sau mai mare decât numărul de elemente minus unu (din mulţime) se returnează nil. Exemple:

(setq s1 (ssget ”X”)) ;se generează o mulţime de selecţie formată ;din toate entităţile din desen

(setq e1 (ssname s1 0) ;se preia numele primei entităţi din mulţime e12 (ssname s1 11);se preia numele entităţii de pe poziţia a 11-a ;(a 12-a pentru utilizator) e100 (ssname s1 99) ;se preia numele entităţii de pe poziţia a 99-a ;(a 100-a pentru utilizator)

)

Page 113: Visual Lisp

Proiectare parametrizată asistată de calculator

114

Funcţia SSNAMEX Sintaxă:

(SSNAMEX <m_sel> [ <index> ])

Funcţia returnează numele entităţii din mulţimea <m_sel>, identificată prin <index> împreună cu descrierea modului în care a fost selectată entitatea şi punctele caracteristice modului respectiv, sub forma unei liste de liste. Modurile de selectare sunt codificate, cu numere întregi, astfel:

0 – mod neprecizat (de exemplu Last, All etc.); 1 – selectare prin punctare; 2 – Window sau WPoligon; 3 – Crossing sau CPolygon; 4 – Fence.

Dacă <index> este negativ sau mai mare decât numărul de elemente minus unu (din mulţime) se returnează nil.

Exemple: (setq s1 (ssget ”X”)) ;se generează o mulţime de selecţie formată din toate entităţile din desen (setq l1 (ssnamex s1 0)) →((0 <Entity name: 40079d68> 0)) ;se preia numele şi modul primei entităţi din mulţime (setq s2 (ssget)) ;se generează o mulţime prin selectarea entităţilor de către utilizator (setq l2 (ssnamex s1 0)) → ((1 <Entity name: 40079d60> 0 (0 (201.413 110.595 0.0)))) ;se preia numele şi modul primei entităţi din mulţime

Funcţia SSADD Sintaxă:

(SSADD [ <nume_ent>[ <m_sel> ] ])

Funcţia ssadd adaugă entitatea identificată prin <nume_ent> la mulţimea de selecţie <m_sel> şi returnează mulţimea de selecţie modificată. Dacă funcţia este apelată fără argumente, se generează o mulţime de selecţie vidă, iar dacă este apelată doar cu un argument de tip nume de entitate, este generată o mulţime de selecţie care conţine entitatea specificată prin argument. În cazul în care entitatea dată ca argument este conţinută de mulţimea de selecţie, atunci ssadd ignoră operaţia fără a afişa un mesaj de eroare.

Page 114: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

115

Exemple: (setq e1 (entnext)) ;se preia prima entitate din baza de date (setq s1 (ssadd)) ;se generează o mulţime de selecţie vidă (setq s2 (ssadd e1)) ;se generează o mulţime cu o singură entitate (setq e2 (entnext e1)) ;se preia o nouă entitate din baza de date (setq s2 (ssadd e2 s2)) ;se adaugă la s2 entitatea e2 Funcţia SSDEL Sintaxă:

(SSDEL <nume_ent> <m_sel>)

Ssdel permite ştergerea entităţii <nume_ent> din mulţimea de selecţie <m_sel> şi returnează mulţimea de selecţie modificată. Dacă entitatea nu face parte din mulţimea de selecţie atunci funcţia returnează nil. Exemplu: (setq e1 (entnext)) ;se preia prima entitate din baza de date (setq s1 (ssadd e1)) ;se generează o mulţime de selecţie formată din e1 (setq s1 (ssdel e1 s1));se şterge e1 din mulţimea de selecţie (ssdel e1 s1) ;returnează nil deoarece e1 nu mai face parte din ;mulţimea de selecţie Funcţia SSMEMB Sintaxă:

(SSMEMB <nume_ent> <m_sel>)

Funcţia ssmemb verifică dacă entitatea <nume_ent> este conţinută de mulţimea de selecţie <m_sel> şi returnează numele entităţii dacă aceasta face parte din mulţimea respectivă. Dacă entitatea nu face parte din mulţimea de selecţie atunci funcţia returnează nil. Exemplu: (setq e1 (entnext)) ;se preia prima entitate din baza de date (setq e2 (entnext e1)) ;se preia următoarea entitate din baza de date (setq s1 (ssadd e1)) ;se generează o mulţime de selecţie, s1, formată ;din e1 (ssmemb e1 s1) ;returnează numele de entitate e1 (ssmemb e2 s1) ;returnează nil deoarece e2 nu face parte din ;mulţimea de selecţie

Page 115: Visual Lisp

Proiectare parametrizată asistată de calculator

116

CAPITOLUL 3

APLICAŢII

3.1 Pentru conturul indicat în figura 3.1 să se definească o nouă comandă AutoCAD care să permită generarea acestuia (fără grosime), în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare.

Fig. 3.1 Conturul de trasat.

Fig. 3.2 Simbolurile utilizate în program.

Page 116: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

117

Programul AutoLISP care rezolvă problema propusă este prezentat în continuare, iar la scrierea acestuia s-a ţinut cont de simbolurile indicate în figura 3.2. (defun c:ex1 (/ r p1 p2 p3 p4 p5 p6 p7 cmd osm) (setq cmd (getvar "cmdecho")) ;se preia starea curentă a variabilei CMDECHO (setvar "cmdecho" 0) ;se setează variabila CMDECHO pe zero (se inhibă ecoul) (setq osm (getvar "osmode")) ;se preia starea curentă a variabilei OSMODE (setvar "osmode" 0) ;se setează variabila OSMODE pe zero (se inhibă modurile OSNAP) (initget 1) (setq p1 (getpoint "\nIntroduceti punctul de baza :")) ;se solicită utilizatorului punctul de bază cu preluarea erorii de ;introducere nulă (initget (+ 1 2 4)) (setq r (getdist p1 "\nIntroduceti raza :")) ;se solicită utilizatorului raza cu preluarea erorilor de introducere ;nulă, zero sau valori negative (setq p2 (list (car p1) (+ (cadr p1) r)) p3 (list (+ (car p2) (* (/ 15 4.0) r)) (cadr p2)) p4 (list (car p3) (cadr p1)) p5 (list (car p4) (- (cadr p4) r)) p6 (list (- (car p5) r) (cadr p5)) p7 (list (car p1) (cadr p5)) ) ;se calculează coordonatele punctelor care definesc conturul (command "arc" p2 "c" p1 p7 "arc" p5 "c" p4 p3 "line" p2 p3 "" "line" p7 p5 "" "line" p2 p6 p3 "" ) ;se trasează conturul de generat (setvar"cmdecho" cmd) ;se restaurează vechea valoare a variabilei CMDECHO (setvar "osmode" osm) ;se restaurează vechea valoare a variabilei CMDECHO (prin1) ;pentru quiet exit )

Page 117: Visual Lisp

Proiectare parametrizată asistată de calculator

118

3.2 Pentru conturul indicat în figura 3.3 să se definească o nouă comandă AutoCAD care să permită trasarea acestuia (fără grosime), în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare. Datele de intrare sunt: punctul de bază P1, lungimea L şi înălţimea H.

Fig. 3.3 Conturul de trasat cu simbolurile aferente.

Programul AutoLISP care rezolvă problema propusă este prezentat în continuare, iar la scrierea acestuia s-a ţinut cont de simbolurile indicate în figura 3.3. (defun c:ex2 (/ p1 p2 p3 p4 L h osm cmd )

(setq osm (getvar ”osmode”)) (setq cmd (getvar ”cmdecho”)) (setvar ”osmode” 0) (setvar ”cmdecho” 0) (initget 1) (setq p1 (getpoint ”\nIntroduceti punctul de baza P1:”)) (initget 7) (setq L (getdist p1 ”\nLungimea L:”)) (initget 7) (setq h (getdist p1 ”\nInaltimea H:”)) (setq ;se calculeza valorile simbolurilor necesare generarii p2 (list (+ (car p1) L) (cadr p1)) p3 (list (car p2) (+ (cadr p2) H)) p4 (list (car p1) (cadr p3)) p5 (list (+ (car p1) (/ L 2)) (+ (cadr p4)(* L (cos(/ pi 6))))) )

Page 118: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

119

(command ”circle” ”3p” p1 p2 p5 ;se traseaza conturul

”line” p1 p2 p3 p5 p4 ”c” ”line” p4 p3 ”” ) (setvar ”osmode” osm) (setvar ”cmdecho” cmd) (prin1)

)

In situaţia în care se consideră că P1 şi P3 sunt date de intrare, programul AutoLISP este următorul :

(defun c:ex2mod (/ p1 p2 p3 p4 l osm cmd ) (setq osm (getvar "osmode")) (setq cmd (getvar "cmdecho")) (setvar "osmode" 0) (setvar "cmdecho" 0) (initget 1) (setq p1 (getpoint "\nIntroduceti punctul de baza P1:")) ;se citeste P1 (initget 1) (setq p3 (getcorner p1 "\nIntroduceti punctul P3:")) ;se citeste P3 (setq ;se calculeza valorile simbolurilor necesare generarii p2 (list (car p3) (cadr p1)) p4 (list (car p1) (cadr p3)) L (- (car p3) (car p1)) p5 (list (+ (car p1) (/ L 2)) (+ (cadr p4)(* L (cos(/ pi 6))))) ) (command "circle" "3p" p1 p2 p5 ;se traseaza conturul "line" p1 p2 p3 p5 p4 "c" "line" p4 p3 "" ) (setvar "osmode" osm) (setvar "cmdecho" cmd) (prin1) )

Page 119: Visual Lisp

Proiectare parametrizată asistată de calculator

120

3.3 Pentru conturul din figura 3.4 să se definească o nouă comandă AutoCAD care să permită generarea acestuia (fără grosime), în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare şi cu următoarele date de intrare: punctele P1, P2 poziţionate pe o orizontală şi raza R.

Fig. 3.4 Conturul de trasat cu simbolurile aferente.

Programul AutoLISP care rezolvă problema propusă este prezentat în continuare, iar la scrierea acestuia s-a ţinut cont de simbolurile prezentate în figura 3.4.

(defun c:ex3 (/ r r2 p1 p2 p3 p4 p5 p6 p7 cmd osm ortho )

(setq osm (getvar ”osmode”)) (setq cmd (getvar ”cmdecho”)) (setq ortho (getvar ”orthomode”)) (setvar ”orthomode” 1) ;se activeaza modul ortho (setvar ”osmode” 0) (setvar ”cmdecho” 0) (initget 1) (setq p1 (getpoint ”\nIntroduceti punctul P1:”)) ;se citeste punctul P1 (initget 1) (setq p2 (getpoint p1 ”\nIntroduceti punctul P2:”)) ;se citeste punctul P2 (setvar ”orthomode” ortho) (initget 7) (setq r (getdist p1 ”\nRaza R:”)) ;se citeste raza (setq ;se calculeza simbolurile necesare generarii r2 (-(car p2) (car p1) r) p3 (list (car p2) (- (cadr p2) r2))

Page 120: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

121

p4 (list (- (car p3) r2) (cadr p3)) p5 (list (car p1) (- (cadr p1) r))

p6 (list (car p4) (cadr p5)) p7 (list (car p6) (cadr p1))

) (command ”circle” p1 r ;se traseaza conturul

”circle” p2 p7 ”circle” “2p” p3 p4 ”line” p1 p4 p2 ”c” ”line” p3 p4 p7”” ”line“ p5 p6 ””

) (setvar ”osmode” osm) (setvar ”cmdecho” cmd) (prin1)

)

3.4 Pentru secţiunea prezentă în figura 3.5 să se definească o nouă comandă AutoCAD care să permită trasarea acesteia (fără grosime), în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare. Datele de intrare vor fi: punctul de bază P1, raza R şi înălţimea H. Caracteristicile haşurii, ce urmează a fi trasată, sunt: definită de utilizator, liniile de haşură sunt aflate la distanţa de 2 şi sunt înclinate la 45º.

Fig. 3.5 Secţiunea de trasat cu simbolurile aferente.

Programul AutoLISP care parametrizează secţiunea propusă este prezentat în continuare. La scrierea acestuia s-a ţinut cont de simbolurile indicate în figura 3.5.

Page 121: Visual Lisp

Proiectare parametrizată asistată de calculator

122

(defun c:ex4 (/ r p1 p2 p3 p4 p5 p6 cmd osm ) (setq osm (getvar ”osmode”)) (setq cmd (getvar ”cmdecho”)) (setvar ”osmode” 0) (setvar ”cmdecho” 0) (initget 1) (setq p1 (getpoint ”\nIntroduceti punctul de baza P1:”)) (initget 7) (setq r (getdist p1 ”\nIntroduceti Raza R:”)) (initget 7) (command ”circle” p1 r) (setq h (getdist (list (car p1) (+ (cadr p1) r)) "\nIntroduceti inaltimea H:"))

;se introduce inaltimea cu punct de baza quadrant-ul cercului situat la 90 de grade (setq p2 (list (car p1) (-(cadr p1) (- h r))) p3 (list (car p1) (- (cadr p1) r )) p4 (list (car p1) (+ (cadr p1) r)) p5 (list (- (car p1) r 5) (cadr p2)) p6 (list (+ (car p1) r 5) (cadr p2)) ) (command ”line” p5 p6 ”” ”trim” p4 p2 ”” p3 p5 p6 ”” ”bhatch” ”p” ”u” 45 2 ”n” (list (car p2) (+ (cadr p2) 3)) ”” ) (setvar ”osmode” osm) (setvar ”cmdecho” cmd) (prin1)

)

3.5 Pentru piesa din figura 3.6 să se definească o nouă comandă AutoCAD care să permită trasarea acesteia (fără grosime), în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare. Datele de intrare vor fi: punctul de bază P1, raza mare R1, raza mică R2 şi înălţimea H. Comanda va conţine protecţii la introducerea datelor, astfel încât piesa să existe din punct de vedere geometric şi va trasa entităţile pe măsură ce se introduc datele de intrare. Caracteristicile haşurii sunt următoarele: definită de utilizator, liniile de haşură sunt aflate la distanţa de 2 şi sunt înclinate la 45º.

Page 122: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

123

Fig. 3.6 Piesa de generat cu simbolurile aferente. Aplicaţia care rezolvă problema propusă mai sus, este prezentată în continuare. (defun c:ex5 (/ r1 r2 h p1 p2 p3 p4 p5 p6 cmd osm ) (setq osm (getvar "osmode")) (setq cmd (getvar "cmdecho")) (setvar "osmode" 0) (setvar "cmdecho" 0) (initget 1) (setq p1 (getpoint "\nIntroduceti punctul de baza P1:")) (initget 7) (setq r1 (getdist p1 "\nIntroduceti Raza mare R1:")) (command "circle" p1 r1) (setq r2 (1+ r1)) ;se asigura intrarea in while (while (>= r2 r1) ;atat timp cat raza R2 este >= decat R1 (initget 7) (setq r2 (getdist p1 "\nIntroduceti Raza mica R2:")) ;se introduce R2 (if (>= r2 r1) (princ "\nRaza R2 prea mare")) ;daca R2>=R1 se afiseaza mesaj de eroare ) (command "circle" p1 r2) (setq h r2 p4 (list (car p1) (+ (cadr p1) r1)) ) ;se asigură intrarea în while şi se calculează punctul P4 (while (or (< h (+ r1 r2)) (> h (* 2 r1))) ;atat timp cat H< R1+R2 sau H > 2*R1 (initget 7) (setq h (getdist p4 "\nIntroduceti inaltimea H:")) ;se introduce inaltimea cu punct de baza p4 (if (or (< h (+ r1 r2)) (> h (* 2 r1))) (princ "\nInaltimea H nu este corespunzatoare"))

Page 123: Visual Lisp

Proiectare parametrizată asistată de calculator

124

;daca h< R2+R1 sau h> 2*r1 se afiseaza mesaj de eroare ) (setq p2 (list (car p1) (-(cadr p1) (- h r1))) p3 (list (car p1) (- (cadr p1) r1 )) p5 (list (- (car p1) r1 5) (cadr p2)) p6 (list (+ (car p1) r1 5) (cadr p2)) ) ;se calculează punctele caracteristice (command "zoom" "e" "line" p5 p6 "" "trim" p4 p2 "" p3 p5 p6 "" "bhatch" "p" "u" 45 2 "n" (list (car p2) (- (cadr p4) (/ (- r1 r2)2 ))) "" "zoom" "p" ) ;se finalizează trasarea conturului (setvar "osmode" osm) (setvar "cmdecho" cmd) (prin1) ) 3.6 Considerându-se modelul 3D din figura 3.7, care este obţinut prin extrudarea piesei 2D din figura 3.6, să se definească o nouă comandă AutoCAD care să permită generarea acesteia cu grosime de 0.35, în layer-ul curent, cu inhibarea ecoului şi a modurilor OSNAP la desenare. Datele de intrare vor fi: punctul de bază P1, raza mare R1, raza mică R2, cota H, înălţimea de extrudare He şi unghiul de extrudare Ue. Comanda va conţine protecţii la introducerea datelor, astfel încât piesa să existe din punct de vedere geometric şi va trasa entităţile pe măsură ce se introduc datele de intrare.

Fig. 3.7 Modelul 3D de generat.

Page 124: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

125

Programul care parametrizează modelul 3D din figura 3.7, este prezentat în continuare. (defun c:ex6 (/ r1 r2 p1 p2 p3 p4 p5 p6 he ue e1 e2 e3 m3d cmd osm lwd) (setq osm (getvar "osmode")) (setq cmd (getvar "cmdecho")) (setq lwd (getvar "lwdisplay")) (setvar "osmode" 0) (setvar "cmdecho" 0) (setvar "lwdisplay" 1) (initget 1) (setq p1 (getpoint "\nIntroduceti punctul de baza P1:")) (initget 7) (setq r1 (getdist p1 "\nIntroduceti Raza mare R1:")) (command "lweight" 0.35 ;se seteaza grosimea de 0.35 "circle" p1 r1) (setq e1 (entlast));se preia numele aferent primei entitati trasate (setq r2 (1+ r1)) ;se asigura intrarea in while (while (>= r2 r1) ;atata timp cat raza R2 este >= decat R1 se repeta (initget 7) (setq r2 (getdist p1 "\nIntroduceti Raza mica R2:")) ;se introduce R2 (if (>= r2 r1) (princ "\nRaza R2 prea mare")) ;daca R2>=R1 se afiseaza mesaj de eroare ) (command "circle" p1 r2) (setq e2 (entlast)) ;se preia numele aferent celei de a 2-a entitate trasata (setq h r2 p4 (list (car p1) (+ (cadr p1) r1)) ) ;se asigură intrarea în while şi se calculează punctul P4 (while (or(< h (+ r1 r2))(> h (* 2 r1)));atat timp cat h< R2+R1 sau h> 2*R1 se repeta (initget 7) (setq h (getdist (list (car p1) (+ (cadr p1) r1)) "\nIntroduceti inaltimea H:")) ;se introduce inaltimea cu punct de baza p4 (if (or (< h (+ r1 r2)) (> h (* 2 r1))) (princ "\nInaltimea H nu este corespunzatoare")) ;daca h< R2+R1 sau h> 2*r1 se afiseaza mesaj de eroare ) (setq p2 (list (car p1) (-(cadr p1) (- h r1)))

Page 125: Visual Lisp

Proiectare parametrizată asistată de calculator

126

p3 (list (car p1) (- (cadr p1) r1 )) p5 (list (- (car p1) r1 5) (cadr p2)) p6 (list (+ (car p1) r1 5) (cadr p2)) );se calculeaza punctele caracteristice (command "line" p5 p6 "" ;se traseaza linia "zoom" "e") (setq e3 (entlast)) ;se preia numele acesteia (command "trim" p4 p2 "" p3 p5 p6 "") (initget 1) (setq He (getdist p1 "\nIntroduceti inaltimea de extrudare He:")) ;se introduce inaltimea de extrudare He (initget 1) (setq ue (getreal "\nIntroduceti unghiul de extrudare Ue:")) ;se introduce unghiul de extrudare Ue (command "pedit" e3 "" "j" e1 "" "" ;se genereaza polilinia de baza "extrude" "l" "" he ue ;si apoi aceasta este extrudata ) (setq m3d (entlast)) ;se preia numele modelului 3d rezultat (command "extrude" e2 "" he ue ;se extrudeaza cercul obtinandu-se un cilindru "subtract" m3d "" "l" "" ;se extrage cilindrul din modelul 3d "vpoint" "-1,-1,1" ;se stabileste directia de privire 1,1,1 "hide" ;se ascund muchiile invizibile ) (setvar "lwdisplay" lwd) (setvar "osmode" osm) (setvar "cmdecho" cmd) (prin1) )

Page 126: Visual Lisp

Prof. dr. ing. Gheorghe OANCEA

127

B I B L I O G R A F I E 1. Oancea, Gh. Bruda, F., Drăgoi, M.V, Grafică tehnologică asistată de

calculator. Parametrizarea desenelor în AutoCAD utilizând AutoLISP, Universitatea “Transilvania” din Braşov, 1996.

2. Pozdârcă, Al., Mocian, I., Albert, K., AutoCAD - programare în AutoLISP. Editura Universităţii ”Petru Maior” Târgu-Mureş, 2001.

3. * * * , Visual LISP Developer's Guide, Autodesk, 2000-2002. 4. * * *, AutoLISP Programmer’s Reference - Release 12, Autodesk Ltd, 1992. 5. * * *, Colecţia de reviste Hello CAD_FANS, 1991-1997, Editura Fast Impex

Ltd, Bucureşti. 6. * * * , AutoCAD Customization Guide, Autodesk, 1992-1998. 7. * * *, Fundamentals of AutoLISP, Autodesk Inc. Training Departament,

1992-1996. 8. * * *, DXF Reference, Autodesk, 2000-2002.