3D-Darstellung in 19 Zeilen
Das Programm stellt ein frei wählbares, dreidimensionales Objekt auf dem Bildschirm dar, das durch Drücken der Funktionstasten gedreht werden kann. Simons Basic ist allerdings Voraussetzung.
Das Programm (Listing 1)wird nach Aktivierung von Simons Basic normal geladen und mit »RUN« gestartet. Danach muß die Datei angegeben werden, die die Daten für den darzustellenden Körper enthält. Bevor die Eingabe mit RETURN abgeschlossen werden kann, muß jedoch erst die Diskette mit der gewünschten Datei in das Laufwerk eingeführt werden. Sind alle Werte eingelesen, erscheint die Figur in Originalform auf dem Bildschirm. Sie kann nun durch Drücken der Funktionstasten (ohne SHIFT) beliebig gedreht werden. F1, F3 und F5 bestimmen die Rotationsachse, während F7 einen Richtungswechsel bewirkt.
Die Erzeugung von Figuren
Die Daten für Figuren müssen in Form einer sequentiellen Datei (Typ SEQ) vorliegen. Eine Figur besteht dabei aus einer begrenzten Anzahl von Geradenstücken, die duch ihre Anfangs- und Endpunkte (x-, y- und z-Werte) gekennzeichnet sind. Jedes Geradenstück wird also durch sechs Zahlen bestimmt. Alle Geradenstücke werden unmittelbar hintereinander in die Datei geschrieben. Ein Endekennzeichen oder sonstige Zusatzangaben sind nicht erforderlich.
Das Demonstrationsprogramm (Listing 2) erzeugt eine Datei mit dem Namen »PYR«, welche die Daten für eine Pyramide enthält. Durch Veränderung der DATA-Zeilen können auch andere Körper definiert werden. Die Koordinaten müssen jedoch so gewählt werden, daß sie nicht außerhalb des Bildschirmbereichs liegen und diesen auch nicht durch die Rotation zu verlassen drohen. Es sei dabei darauf hingewiesen, daß die z-Achse in die Tiefe und die y-Achse nach oben zeigt. Als Orientierungshilfe kann die Demo-Pyramide verwendet werden.
Darstellung eines Punktes
Um einen Raumpunkt auf dem Bildschirm darstellen zu können, muß er zunächst an das zweidimensionale Koordinatensystem angepaßt werden. Es wird hierzu die Fluchtpunktperspektive gewählt, die über die Strahlensätze herleitbar ist:
x’=xf-(zf-z) * (xf-x)/zf
y'=yf-(zf-z) * (yf-y)/zf
x’ | horizontale Bildschirmkoordinate |
y’ | vertikale Bildschirmkoordinate |
x,y,z | Koordinaten des Raumpunktes |
xf,yf,zf | Koordinaten des Fluchtpunktes |
Anwendungsmöglichkeiten
Das Programm kann beispielsweise zur Darstellung und räumlichen Drehung von Computergrafiken (dreidimensionale Funktionen, Gegenstände, Flächen etc.) verwendet werden. Die Erzeugung der Gebilde erfolgt dabei von einem unabhängigen Programm. Nach Erstellung der sequentiellen Datei kann das Ergebnis mittels des Rotationsprogramms betrachtet werden. Dazu kann es sinnvoll sein, noch einige Erweiterungen in das Programm einzubauen. Zum Beispiel würden folgende zusätzlich eingegebenen Zeilen bei Überschreitung des Bildschirmbereiches einen Abbruch verhindern und statt dessen die betreffenden Geraden nur bis an den Rand zeichnen:
22 gosub 60 60 dx=x-v:dy=y-r:mm=0.01:if dx*dy<>0 then mm=dy/dx 62 if x<0 then y=y-mm*x:x=0 64 if x>320 then y=y-mm*(x-320):x=320 66 if v<0 then r=r-mm*v:v=0 68 if v>320 then r=r-mm*(v-320):v=320 70 if y<0 then x=x-y/mm:y=0 72 if y>200 then x=x-y/mm:y=200 74 if r<0 then v=v-r/mm:r=0 76 if r>200 then v=v-(r-200)/mm:r=200 78 if x<0 or x>320 or v>320 or v<0 then x=0:v=0 80 if y<0 or y>200 or r<0 or r>200 then y=0:r=0 82 return
Freilich nimmt ein derart ergänztes Programm beim LISTen mehr als eine Bildschirmseite ein, bietet aber bessere Anwendungsmöglichkeiten.
Ein völlig anderer Aspekt wäre die bloße Verwendung der mathematischen Formeln zum Einbau in eigene Programme (beispielsweise Spiele). Dazu kann es unter Umständen erforderlich sein, sie in Maschinensprache zu übersetzen. Da aber dies bereits mit einfachen 16-Bit-Rechenroutinen und wenigen Tabellen bewerkstelligt werden kann, dürfte das für den erfahrenen Programmierer kein allzu großes Hindernis darstellen.
Mathematisch gesehen: Das Problem der Rotation
Um einen Körper von allen nur erdenklichen Perspektiven darzustellen, muß er im Raum gedreht werden. Die dazu notwendigen Berechnungen sind allerdings recht kompliziert und auch nicht im Rahmen eines extrem kurzen Programms realisierbar, will man den Körper — das heißt alle seine Eckpunkte — um eine beliebig im Raum schwebende Achse rotieren lassen.
Verzichtet man jedoch auf eine beliebige Rotationsachse und beschränkt man sich auf den Sonderfall, daß diese zu einer der Achsen des Koordinatensystems (x-,y- oder z-Achse) parallel liegt, ergibt sich eine erhebliche Vereinfachung, die daraus resultiert, daß — bedingt durch die Parallelität — immer nur zwei Koordinatenangaben eines zu rotierenden Punktes verändert werden und somit das Problem in der Ebene betrachtet werden kann. Konstant bleibt immer diejenige Koordinatenangabe, die sich auf jene Koordinatenachse bezieht, zu welcher die Rotationsachse parallel ist.
Für die Drehung eines Punktes P um einen Punkt R ergeben sich folgende Rechenschritte:
A… Abszisse
O… Ordinate
Koordinaten von R und P : R (ar, or); P (ap,op)
Koordinate von P’ : P’ (ap’, op’)
W… Winkel, der den Grad der Rotation bestimmt
A, B, d, e, h, d’, h’ : siehe Bild 1
A = ABS (ATN((or-op)/(ar-ap)))
if ar-ap >0 then A=-Aπ
if or-op >0 then A=-A
e = SQR((d)(d) + (h)(h))
d = ap—ar; h=op-or
B = W+A; d’ = COS(B)*e; h’ = SIN(B)*e
ap’ = ar+d’; op’=or+h’
Diese mathematischen Ausführungen waren nur für den an den Grundlagen Interessierten gedacht. Natürlich kann man auch mathematisch unbelastet mit dem Programm experimentieren.
(Achim Vowe/ev)x(100), y(100), z(100) | Feld für Daten einer Figur |
e$ | Dateiname |
s, i, q | Zähler |
l, m, n | Schnittpunkt der Rotationsachsen (x, y, z) |
w | Rotationswinkel |
xf, yf, zf | Koordinaten des Fluchtpunktes |
v, r, p | Zwischenspeicher |
x, y, z | Zwischenspeicher für aktuellen Figurenpunkt vor und nach der Rotation |
a$, a% | Variablen für Tastatureingabe |
11 dimx(100),y(100),z(100) 12 input"file ";e$:open1,8,4,e$+",s,r" 13 input#1,x(s),y(s),z(s):s=s+1 14 ifst<>64then13 15 close1:l=122:m=105:n=53:w=.5 20 q=0:hires0,1:xf=147:yf=65:zf=399 21 fori=1tos/2:gosub30:v=x:r=y:gosub30 23 linex,200-y,v,200-r,1:next 24 geta$:ifa$=""then24 28 ifa$="{lgrn}"thenw=-w:goto24 29 a%=asc(a$)-132:goto20 30 x=x(q):y=y(q):z=z(q):p=q:q=q+1:ifa%=1thena=x:o=y:t=l:u=m:gosub50:x=a:y=o 32 ifa%=2thena=x:o=z:t=l:u=n:gosub50:x=a:z=o 33 ifa%=3thena=y:o=z:t=m:u=n:gosub50:y=a:z=o 40 x(p)=x:y(p)=y:x=xf-(zf-z)*(xf-x)/zf 42 y=yf-(zf-z)*(yf-y)/zf:z(p)=z:return 50 e=sqr((a-t)^2+(o-u)^2):c=abs(atn((u-o)/(t-a))):ift-a>0thenc=-c-~ 53 b=w+c:ifu-o>0thenc=-c:b=w+c 55 a=t+cos(b)*e:o=u+sin(b)*e:return
10 open1,8,4,"pyr,s,w" 20 readd 30 ifd<>1e9thenprint#1,d:goto20 40 close1 100 data50,50,0,200,50,0 110 data200,50,0,200,50,100 120 data200,50,100,50,50,100 130 data50,50,100,50,50,0 200 data50,50,0,125,150,50 210 data200,50,0,125,150,50 220 data200,50,100,125,150,50 230 data50,50,100,125,150,50 240 data1e9