Autocag größer gleich

Autocag größer gleich

Eines der in den vorigen Kapiteln erw�hnten Kriterien f�r eine Funktion war, dass sie in der Lage sein muss, auf verschiedene Situationen flexibel zu reagieren. Das ist nat�rlich schon dadurch gegeben, dass sie verschiedene Werte f�r ihre Argumente erh�lt. Eine Funktion, die immer gleich reagiert, kann aber auch sinnvoll sein. Wir kennen ja bereits (textscr). Diese Funktion bewirkt immer nur ein Umschalten auf den Textbildschirm (bzw. das Textfenster) und ist dabei absolut unflexibel.

Man muss aber ber�cksichtigen, dass es hier um eine hundertprozentige Nebeneffekt-Funktion geht. Funktionen, deren Haupteffekte immer gleich sind, und die keine Nebeneffekte haben, sind jedoch absolut sinnlos, da man sie auch als Konstanten wie z.B. pi definieren k�nnte. Man m�sste also einfach den Wert an ein Symbol binden und h�tte den gleichen Nutzen. Beispiel: Eine Funktion, die immer Wurzel aus 2 berechnet, kann durch eine Konstante ersetzt werden:

(defun wurzel-zwei()(sqrt 2))
;ist Unsinn und sollte durch
(setq wurzel-zwei (sqrt 2))
                  

ersetzt werden. Am Rande: Man kann in AutoLisp keine echten Konstanten erzeugen, deren Wert sich nicht mehr �ndern l�sst. Das Wort Konstante ist also eine blosse Absichtserkl�rung des Programmierers, den Wert einer Variablen nach dem Setzen nicht mehr zu �ndern.

Wie kann man nun aber noch mehr Flexibilit�t in Funktionen hineinbringen? Was wir brauchen, ist eine M�glichkeit der Entscheidung in der Art WENN dies-der-Fall-ist DANN tue-dieses SONST tue-jenes. Erst eine solche Entscheidungsfreiheit macht es m�glich, wirklich sinnvolle Funktionen zu schreiben. LISP stellt uns dazu die Funktion (if ...) zur Verf�gung, die entweder zwei oder drei Argumente erh�lt:

(if <ausdruck1> <ausdruck2> [<ausdruck3>])
                  

ausdruck3 kann vorhanden sein oder nicht, dies wird durch die eckigen Klammern angezeigt.

ausdruck1 kann ein v�llig beliebiger Ausdruck sein, der entweder nil oder etwas anderes zur�ckgibt. Gibt er etwas anderes als nil zur�ck, wird dann ausdruck2 evaluiert, anderenfalls wird (sofern vorhanden) ausdruck3 evaluiert. In der Praxis werden in ausdruck1 meistens irgendwelche Testfunktionen eingesetzt, von denen LISP eine ganze Reihe zur Verf�gung stellt. Wir sollten uns daher zun�chst mit einigen dieser Testfunktionen befassen:

(> x y) testet, ob x gr�sser als y ist
(< x y) testet, ob x kleiner als y ist
(= x y) testet, ob x gleich y ist
                  

Diese Funktionen k�nnen �brigens auch mit mehr als 2 Argumenten aufgerufen werden. So testet z.B. (> x y z), ob x gr�sser als y und y gr�sser als z ist. Mit anderen Worten: Es wird getestet, ob y zwischen x und z liegt.

Dann gibt es auch noch kombinierte Formen:

(>= x y) testet, ob x gr�sser oder gleich y ist
(<= x y) testet, ob x kleiner oder gleich y ist
                  

Schliesslich haben wir auch noch einen Test auf Ungleichheit:

(/= x y) testet, ob x ungleich y ist
                  

Die folgenden Funktionen bietet noch eine zus�tzliche M�glichkeit:

(zerop x)
; ist �quivalent zu
(= x 0)
                  

testet, ein Wert gleich 0 ist.

Die bisher genannten Funktionen lassen sich auf Zahlen und auch auf Zeichenketten anwenden (zerop ist nur f�r Zahlen gedacht). Der Test auf Gleichheit bzw. Ungleichheit l�sst sich aber auch auf Symbole anwenden.

Allen Testfunktionen ist gemeinsam, dass sie - wenn das Testergebnis logisch wahr ist - das Symbol T zur�ckgeben, im anderen Fall erhalten wir nil. Da jede R�ckgabe ausser nil gleichbedeutend mit 'wahr' ist, kann es uns eigentlich auch ganz egal sein, was diese Funktionen zur�ckgeben, solange es - ja nach Testergebnis - nil oder etwas anderes ist.

Dies ist aber deshalb von besonderer Bedeutung, da sich das Symbol T um- oder wegdefinieren l�sst, zumindest ist dies bis AutoCAD 14 der Fall. Ab AutoCAD 2000 ist das Symbol T gesch�tzt und unver�nderlich. Wir tun so etwas nat�rlich nicht absichtlich, aber es kann trotzdem passieren. Normalerweise ist der an das Symbol T gebundene Wert ebenfalls das Symbol T (Selbstbindung). Ist T aber versehentlich umdefiniert worden, dann hat T den Wert nil (oder irgendeinen anderen Wert).

Da die Testfunktionen aber immer das Symbol T und nicht dessen Wert zur�ckgeben, macht es nichts, wenn T umdefiniert wurde. Wenn Sie aber selbst weitere Testfunktionen schreiben, m�ssen Sie darauf achten, das Symbol T selbst (quotiert: also 'T) zur�ckzugeben und nicht dessen Wert. Ich weiss, dass dies ein etwas schwieriges Thema ist, dashalb wird in den �bungsaufgaben noch einmal gr�ndlich darauf eingegangen.

Zun�chst einmal zur�ck zur (if)-Funktion. Lassen Sie uns ein paar Beispiele mit den jetzt bekannten Testfunktionen begutachten:

(if(> zahl 100) 100 zahl)
                  

Dieser Ausdruck gibt uns zahl zur�ck, wenn zahl nicht gr�sser als 100 ist. Ist dies jedoch der Fall, wird 100 zur�ckgegeben. Der Ausdruck begrenzt also einen Zahlenwert auf maximal 100. Werfen Sie nun einen Blick auf das n�chste Beispiel:

(if(< zahl 100) zahl nil)
                  

Dieser Ausdruck gibt dann nil zur�ck, wenn zahl gr�sser als 100 ist. Bei diesem Beispiel gibt es aber noch eine Feinheit zu beobachten. Wir k�nnen den Ausdruck verk�rzen zu

(if(< zahl 100) zahl)
                  

Lassen Sie sich nicht zu der Annahme verleiten, dass dieser Ausdruck nichts zur�ckgibt, wenn zahl gr�sser als 100 ist. Jeder Ausdruck in LISP hat eine R�ckgabe! Hier wird im Fall, dass zahl nicht zur�ckgegeben wird, das Ergebnis der Evaluation der Funktion (< ...) zur�ckgegeben, und das ist eben nil. Durch die vorgenommene Verk�rzung des Ausdrucks �ndert sich also nichts! Noch ein paar Beispiele:

(defun 3d-punkt(punkt)
  (if(=(length punkt)2)
    (append punkt(list 0.0))
    punkt
  )
)
                  

Diese Funktion gibt immer einen vollst�ndigen 3D-Punkt mit Z=0 zur�ck.

(if
  (>=(- zahl(fix zahl))0.5)
  (1+(fix zahl))
  (fix zahl)
)
                  

Dieser Ausdruck rundet eine Realzahl auf oder ab.

(if(member dieses-symbol jene-liste)
  dieses-symbol
)
                  

Dieser Ausdruck ver�ndert die (member)-R�ckgabe so, dass nicht mehr der Rest der Liste zur�ckgegeben wird, sondern nur das gesuchte Symbol. Aber ganz am Rande: Das kann man auch mit

(car(member dieses-symbol jene-liste))
                  

erreichen, da (car nil) ja auch nil ergibt.


�bungsaufgaben

  1. Welche Testfunktionen sind im Ergebnis gleich mit den Konstruktionen
    (not(> ...))
    (not(= ...))
    (and(not ...)(not ...))