Dokumentation

Variablen und arithmetische Ausdrücke

<- Texturen und Bumpsmaps
-> Programmablauf: if, for und Makros
Ein paar Worte vorweg
Variablen und Datentypen
Globale und lokale Variablen
Zuweisungen und Ausdrücke
Operatoren
Eingebaute Funktionen

 

Ein paar Worte vorweg

Bisher wurde nur erklärt, wie man die einzelnen Objekte definiert. Die Script-Sprache kann jedoch viel mehr: Sie hat alle Elemente einer strukturierten Programmiersprache. Dazu gehören Variablen, Programmablaufsteuerung usw..
In diesem Teil der Dokumentation habe ich auf Beispielbilder verzichtet, jedoch werde ich im laufenden Text zahlreiche Beispiele geben.

[
nach oben]
 

Variablen und Datentypen

Die Script-Sprache kennt vier verschiedene Datentypen: int (Integer, ganze Zahl), double (Dezimalzahl), vector (Vektor bestehend aus drei double-Zahlen) und string (Zeichenkette). Je nach Datentyp haben die Operatoren verschiedene Wirkungen.
Sobald in einer Zahlenangabe ein Dezimalpunkt vorkommt, wird die Zahl als double-Zahl aufgefasst, ansonsten wird sie wie eine Integer-Zahl behandelt. Damit haben die Angaben 1 und 1.0 durchaus verschiedene Bedeutungen! Zusätzlich kann auch die übliche Exponent-Schreibweise (z.B. 2.3e8 für 2.3*10^8) verwendet werden. Die drei Komponenten eines Vektors müssen in eckigen Klammern angegeben werden (z.B. [1.0, 2.5, 3.7]). Die Komponenten selbst müssen double-Zahlen sein. Integer-Zahlen werden hier automatisch in double-Zahlen umgewandelt.
Zeichenketten müssen in Anführungszeichen stehen (z.B. "Hallo, Welt!"). Innerhalb des Strings sind, in Anlehnung an die Programmiersprache C, einige Sonderzeichen erlaubt, nämlich: "\r" und "\n" für den Zeilenvorschub, "\"" für ein Anführungszeichen und "\\" für den Backslash selbst.
In der Script-Sprache müssen Variablen nicht deklariert werden. Sie werden automatisch erzeugt, sobald ihnen ein Wert zugewiesen wird. Für den Variablennamen gelten die gleichen Regeln wie in vielen anderen Programmiersprachen auch. Insbesondere darf der Name nicht mit einer Ziffer anfangen.
Wird einer Variablen ein Wert zugewiesen, so wird auch der Typ der Variablen entsprechend gesetzt. Diese kann sich bei der nächsten Zuweisung auch wieder ändern. Es ist also durchaus möglich, dass in derselben Variable einmal ein Vektor und später ein String gespeichert ist.
Einige Datentypen können ineinander umgewandelt werden. So kann aus einer double-Zahl z.B. durch Abschneiden der Dezimalstellen eine Integerzahl werden. Dies geschieht duch besondere Operatoren, wie unten beschrieben.

[
nach oben]
 

Globale und lokale Variablen

Zunächst einmal sind alle Variablen global. Das heißt, sobald einer Variablen ein Wert zugewiesen wird, lässt sich dieser von jeder anderen Programmstelle abfragen. Damit man aber später auch rekursive Algorithmen umsetzen kann, kann man eine Variable auch explizit als lokal deklarieren:

...
{
  local name;
  ...
}
Damit wird die Variable "name" in dem Block, in dem sie steht (zwischen { und }) als lokal definiert. Der Typ muss nicht angegeben werden, in jeder local-Anweisung kann nur ein Variablenname vorkommen.
Für diesen aktuellen Block wird nun eine eigene Variable angelegt und nach Beendigung des Blockes wieder gelöscht. Sollte es bereits eine globale Variable oder eine lokale Variable eines übergeordneten Blockes mit dem gleichen Namen geben, so bleibt diese unverändert.
Ein Beispiel:
a=10;
b=20;

new sphere{
  local b;

  a=15;
  b=25;
}
Nach dem Durchlaufen dieses Programms hat a den Wert 15, da dieser in dem sphere-Block zugewiesen wurde. b hat jedoch weiterhin den Wert 20, da mit der Zuweisung in dem sphere-Block nur die dort lokale Variable b verändert wurde, die nach verlassen des Blockes wieder gelöscht wurde.
Hinweis: Auch die Objektattribute wie pos, scale oder die Oberflächeneigenschaften wie flat, phong, reflect werden intern wie lokale Variablen gehandhabt. Die Variablen flat, phong, reflect, trans, phongsize und fraction bekommen bei ihrer (lokalen) Erzeugung den Wert der gleichnamigen globalen Variablen zugewiesen, sofern es sie gibt.

[
nach oben]
 

Zuweisungen und Ausdrücke

Jede Zuweisung hat die Form

  variablenname=Ausdruck;
"Ausdruck" kann dabei ein beliebiger arithmetischer Ausdruck sein, dessen Ergebnis auch einen beliebigen Typ haben kann. Der Typ der Variablen wird dann automatisch entsprechend gesetzt. Gibt es die Variable noch nicht, wird sie als globale Variable neu angelegt.
Die arithmetischen Ausdrücke haben die übliche Form. Zur Klammerung können runde Klammern () mit beliebiger Verschachtelungstiefe verwendet werden. Die erlaubten Operatoren sind weiter unten aufgelistet.
In den drei Komponenten eines Vektors [x, y, z] können auch selbst wieder Ausdrücke stehen, deren Ergebnis int oder double ist.

[
nach oben]
 

Operatoren

Es wird zwischen drei Typen von Operatoren unterschieden. Die ersten sind die binären Operatoren (z.B. +, -, *, /), die zwei Operanden haben, die links und rechts davon stehen (also z.B. 2+3). Die zweiten sind die unären Präfixoperatoren. Das sind Operatoren, die nur auf einen Wert wirken, und VOR diesem stehen (z.B. -2.3, ++i, !0 (logische Verneinung)). Entsprechend gibt es auch die unären Postfixoperatoren, die hinter dem Wert stehen (z.B. 3! (Fakultät), 3°). Diese Beispiele zeigen schon, dass derselbe Operator eine völlig andere Bedeutung hat, je nachdem, ob er vor oder hinter einem Wert steht.
In arithmetischen Ausdrücken gilt die übliche Ranfgolge von Operatoren (Punkt-vor-Strich etc.)

Binäre Operatoren:
Operation Typ von a Typ von b Wirkung
a + b int,double int,double Addition. Werden int und double gemischt verwendet, ist das Ergebnis double.
vector vector Vektoraddition (Komponentenweise)
string string Aneinanderfügen der Strings
a - b int,double int,double Subtraktion. Werden int und double gemischt verwendet, ist das Ergebnis double.
vector vector Vektorsubtraktion (Komponentenweise)
a * b int,double int,double Multiplikation. Werden int und double gemischt verwendet, ist das Ergebnis double.
vector vector Vektor-Kreuzprodukt
vector
int,double
int,double
vector
Skalarmultiplikation (komponentenweise Multiplikation)
a / b int,double int,double Division. Werden int und double gemischt verwendet, ist das Ergebnis double. Sind a und b int, so ist auch das Ergebnis int!
vector int,double Komponentenweise Division
a . b vector vector Skalarprodukt
a % b int int Modulo (Divisionsrest)
a ^ b int,double int,double Potenz (a hoch b). Werden int und double gemischt verwendet, ist das Ergebnis double
a == b beliebig gleicher Typ wie a Liefert einen int. Ungleich 0, wenn a gleich b ist, sonst 0
a != b beliebig gleicher Typ wie a Liefert einen int. Ungleich 0, wenn a ungleich b ist, sonst 0
a > b
a < b
a >= b
a <= b
int,double int,double Liefert einen int. Ungleich 0, wenn die Ungleichung erfüllt ist, sonst 0
|| int int Logisches oder. Liefert wieder int.
&& int int Logisches und. Liefert wieder int.
, beliebig beliebig Liefert b zurück. Zum Aneinanderfügen von Zuweisungen

Präfixoperatoren:
Operation Typ von a Wirkung
-a int,double Vorzeichenumkehr
vector Komponentenweise Voreichenumkehr
+a beliebig Liefert a (keine Wirkung)
!a int Logische Verneinung
(double)a int,double Wandelt a in ein double um
vector Liefert den Betrag von a
(int)a int,double Wandelt a in einen int um (Dezimalstellen abschneiden)
(string)a beliebig Liefert eine Zeichenkette, in der der Wert von a steht
++a int,double a muss eine Variable sein. Vor der Auswertung des Ausdrucks wird a um eins erhöht.
--a int,double a muss eine Variable sein. Vor der Auswertung des Ausdrucks wird a um eins erniedrigt.

Postfixoperatoren:
Operation Typ von a Wirkung
a! int Fakultät
int,double Berechnet a*Pi/180 (Umwandlung von Grad ins Bogenmaß). Das Ergebnis ist immer double
a++ int,double Erhöhe nach Auswertung des Ausdrucks a um 1
a-- int,double Erniedrigt nach Auswertung des Ausdrucks a um 1

[
nach oben]
 

Eingebaute Funktionen

In der Scriptsprache können die Funktionen sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh, exp, log, ln und sqrt verwendet werden, in der üblichen Bedeutung. Die trigonometrischen Funktionen erwarten ihr Argument im Bogenmaß. Das Argument muss vom Typ int oder double sein, das Ergebnis ist immer double. Weiterhin stehen pi und e als Konstanten zur Verfügung.
Zusätzlich gibt es die Funktion rotate(v1, v2, v3). Die drei Argumente v1, v2 und v3 müssen Vektoren sein. Die Funktion dreht den Vektor v1, wobei v2 der Drehpunkt ist und die Komponenten von v3 die Drehwinkel um x- y- und z-Achse enthält. Rückgabewert ist der gedrehte Vektor.
Weiterhin nützlich ist die Funktion print(s). Dabei muss s ein String sein, also z.B.:

  print("Der Wert ist "+(string)[1.3,2.4,7.3]);
Gibt "Der Wert ist [1.3,2.4,7.3]" aus.

[
nach oben]

Martin Melcher