← ST-Computer 01 / 1989

Schnelles 3D auf dem ST: FlÀchendeckende Objektgrafik in GFA-BASIC, Teil II

Grundlagen

Im vorangegangenen Artikel, der zusammen mit dem Programmlisting als einzelner Artikel gerade noch vertretbar schien, wurde ein Programm zur Erstellung und Darstellung dreidimensionaler Objektgrafik vorgestellt. Einige Fragen, die noch offenbleiben muhten sowie einige hilfreiche Funktionen zur Programmerweiterung werden jetzt hier behandelt.

GFA-Freaks werden es schon lĂ€ngst erkannt haben, die Datenstruktur des Felds Xyz%(2,Pun_anz) fĂŒr die Punkte weicht von der des FlĂ€chenfelds Fl%(Eck_max+3,Fl_max) ab. So werden die Punkte von 1 bis P_anz durchnumeriert im Gegensatz zu den FlĂ€chen, die von 0 bis F_anz-1 zĂ€hlen. Die EintrĂ€ge im Punktfeld entsprechen den Koordinaten X,Y,Z des jeweiligen Punkts. Die EintrĂ€ge im FlĂ€chenfeld von 0 bis Eck_max sind die Nummern der Punkte analog zum Feld Xys%() in der ‘Korkenzieherreihenfolge’. Die drei EintrĂ€ge, die darauf folgen (Eck_max+1 bis Eck_max+3) sind zuerst die Anzahl der Punkte - 1 und dann 2 Werte fĂŒr die Farb- oder Musterinformation.

Mit Kenntnis dieser Struktur erschließt sich einem die hier neu vorgestellte Prozedur F use recht gut. Am linken Rand des Bildschirms werden alle vorhandenen FlĂ€chen aufgelistet. Sollten es mehr sein als der Monitor anzeigen kann, lĂ€ĂŸt sich mit Pfeilen nach oben oder nach unten scrollen. Jeder Kasten zeigt FĂŒllfarbe oder -muster, die FlĂ€chennummer und die Anzahl der Punkte dieser FlĂ€che Eine Mausbewegung auf einen der KĂ€stchen, und eine Inrandung (neudeutsch: Gegensatz von Umrandung) erscheint. Zudem blinken die Punkte dieser FlĂ€che im Anzeigefeld, falls sie sichtbar sind. Ein Mausklick auf das FlĂ€chenkĂ€stchen, und es erscheint eine Alarmbox mit den Möglichkeiten. FĂŒllmuster oder -farbe abzuĂ€ndern oder die FlĂ€che wegzuwerfen. So lassen sich nun falsch konstruierte FlĂ€chen leicht entfernen, und die Umwandlung von Objekten verschiedener Auflösungsstufen ist auch schnell gemacht.

Diskettenkomfort

Geradezu notwendigen Komfort bringen die neuen MenĂŒpunkte “OBJ LADEN" und “SPEICHERN". Nomen est Omen, es sollte nur erwĂ€hnt werden, daß mit Rechtsklick auf diese MenĂŒpunkte ein Pfadname vorgegeben werden kann, und die Dateiart *.3D? sollte am besten Ă  la DEGAS fĂŒr die unterschiedlichen Auflösungsarten verwendet werden (3D1 niedrige Auflösung, 3D2 mittel, 3D3 hochauflösend).

Die Dateien werden nach einem einfachen Verfahren zusammengequetscht, man muß jedoch darauf achten, daß die Variable Eck_max nicht kleiner gewĂ€hlt wird als die maximale Eckenzahl des zu ladenden Objekts, sonst erfolgt eine Warnung vom Programm. In diesem Zusammenhang der Hinweis, daß die Variablen Pun_max (maximale Punktanzahl), Fl_max (maximale FlĂ€chenanzahl) und Eck_max (maximale Anzahl der Eckpunkte einer FlĂ€che) je nach Belieben verĂ€ndert werden können.

Unbekannte Tiefen

Eine neue Funktion ist auch "TIEFENVERZERRUNG". Hiermit können die Grundwerte von Darstx und Darsty verĂ€ndert werden, die die Anzeige der Tiefe im Eingabefenster regeln. Dies ist vor allem dann vonnöten, wenn mehrere Punkte so dicht beieinanderliegen, daß die FlĂ€chenerstellung zur Tortur wird. Nach einem Klick auf “TIEFENVERZERRUNG" verĂ€ndert sich die Darstellung abhĂ€ngig von der Mausposition. Sie sollte langsam von der oberen rechten Ecke des ersten Quadranten Richtung Ursprung geĂ€ndert werden. Je nĂ€her man dem Mittelpunkt kommt, desto stĂ€rker die Verzerrung. Bei der Position, an der die Punktauflösung gĂŒnstig ist, genĂŒgt ein Mausklick, und die neue Verzerrung wird von nun an vom Programm verwendet.

Kaum erwĂ€hnenswert ist die Programmabbruchsfunktion, die einem die Fingerakrobatik von Alternate-Shift-Control erspart. Bei Programmversionen, die man kompilieren will, sollte “End" durch “Quit" ersetzt werden.

Eine weitere Änderung ergibt sich in der Angabe der X-, Y-, Z-Werte. Die X- und Y-Koodinate können jetzt genau wie der Z-Wert mit Mausdruck oder -klick verĂ€ndert werden. Damit verschiebt sich das Koordinatenkreuz, und Objekte, die grĂ¶ĂŸer sind als das Eingabefenster, können bearbeitet werden.

Die letzte VerĂ€nderung bezieht sich auf die neue MenĂŒfunktion “QUADER ERSTELLEN". Hiermit kann ein beliebig großer Quader an jeder Stelle parallel zu den Koordinatenachsen erstellt werden. Nach Klick auf die MenĂŒfunktion muß man sich zuerst entscheiden, ob man den Quader anhand des Mittelpunkts oder des vorderen linken unteren Eckpunkts bestimmen will. Danach können die GrĂ¶ĂŸenangaben fĂŒr drei Seiten angegeben werden, und dann erfolgt die Eingabe des Eckpunkts bzw. des Mittelpunkts. Nun brauchen nur noch die 6 Muster oder Farben fĂŒr die FlĂ€chen des Quaders eingegeben zu werden, und er erscheint in dem Anzeigefeld.

Versteckte Hilfe

In der bisherigen Programmbeschreibung wurden zwei Funktionen ĂŒber die das Programm verfĂŒgt, nicht erlĂ€utert. Die eine bezieht sich auf das selbsttĂ€tige ÜberprĂŒfen der 'Korkenzieherregel' bei der FlĂ€chenerstellung. Bei allen exakt definierten ausgefĂŒllten Objekten gehört jede Linie zu genau 2 FlĂ€chen. Und bei konsequenter Anwendung der ‘Korkenzieherregel' stellt sich heraus, daß die FlĂ€chenecken jede Linie immer gegenlĂ€ufig beschreiben. Abbildung 1 veranschaulicht diesen verbal schwer zu beschreibenden Effekt. Hier setzt auch das Programm ein und ĂŒberprĂŒft in der Prozedur F_akt, ob nach Fertigstellung einer FlĂ€che diese mit irgendeiner Linie einer anderen FlĂ€che dieselbe Richtung beschreibt. Falls ja, werden die Eckpunkte in umgekehrter Reihenfolge abgespeichert (unter Zuhilfenahme des X%()-Feldes). Dies erklĂ€rt, warum neue FlĂ€chen immer an bereits existierende angrenzen sollten, denn nur dann kann das Programm die richtige ‘Korkenzieherorientierung' ĂŒberprĂŒfen bzw. einsetzen.

Ein anderer Aspekt ist die Darstellung des Objekts mit den den Linienmustern innewohnenden Angaben ĂŒber FlĂ€chenzugehörigkeit. Dieser fĂŒr die Erstellung vollstĂ€ndiger Objekte hilfreiche Modus, der sich mit “INFO + ANZEIGE" umschalten lĂ€ĂŸt, wird durch die ÜberprĂŒfung in der Prozedur “Show" (If Grmbo...) erreicht. Hier wird jede Linie daraufhin ĂŒberprĂŒft, ob sie bei einer anderen FlĂ€che auch schon vorhanden ist und, falls ja, gestrichelt dargestellt. Diese ÜberprĂŒfung geht (Brute Force) alle FlĂ€chen und deren Linien durch und bricht nur bei einer zweiten Linie ab. Dieser Aufwand, der fĂŒr jede einzelne Linie aufgebracht werden muß. erklĂ€rt den langsamen Bildaufbau in dieser Darstellungsart. Programmtechnisch kann hier noch viel verbessert werden. da jede gestrichelte Linie ja mindestens zweimal berechnet und ausgegeben wird. Um das Programm nicht noch lĂ€nger und unĂŒbersichtlich zu machen, mußte hierauf leider verzichtet werden.

Ein Hinweis noch fĂŒr die Erstellung von großen FlĂ€chen mit vielen Eckpunkten. Hier muß darauf geachtet werden, mit den ersten drei Punkten ‘Korkenzieherrichtigkeit' zu erzielen, denn nur diese werden fĂŒr die Berechnung des Kreuzprodukts ausgewertet. Danach entgegengesetzte Laufrichtung beeinflußt die Darstellung nicht im mindesten.

Die Einbindung der neuen Prozeduren dĂŒrfte nicht schwerfallen. Außer den DATA-Zeilen muß nur noch der Befehlsaufruf in der Hauptschleife ersetzt werden (siehe Listing). Die Prozeduren selbst können einfach an das bisherige Programm angehĂ€ngt werden. Und nach all der MĂŒhe bleibt lediglich noch der Wunsch, daß sie mit beeindruckenden 3D-Konstruktionen und erfolgreichen Programmerweiterungen gekrönt werden. Die Redaktion wĂŒrde sich freuen, an Ihren Erfahrungen und Ergebnissen teilzuhaben.

Martin A. Wielebinski

Literatur

William M. Newman/Robert F. Sproull,
GrundzĂŒge der interaktiven Computergrafik,
1986, McGraw-Hill, Hamburg

c't 1984,
Heise Verlag, Hannover
(Sehr unterhaltsame Artikelserie ĂŒber ein 6502-Assemblerpaket fĂŒr dreidimensionale Drahtmodelle.)

c't S.144 ff
Von Vektoren und Volumina: Nr. 2 1988,
Heise Verlag, Hannover

CHIP SPECIAL
Computergrafik: MĂ€rz 1981,
Vogel Verlag, WĂŒrzburg.

' ' ************************************************* ' * * ' * 3D-Grafik Edier- und Demoprogramme fĂŒr die ST * ' * von Martin A Wielebinski. * ' * Teil 2, die bisher 'reservierten' Funktionen: * ' * FlĂ€cheneditor, Load & Save. * ' * * ' ************************************************* ' ' Um die zusĂ€tzlichen Prozeduren lauffĂ€hig zu machen mĂŒssen zwei kleine ' Änderungen des Originalprogramms vorgenommen werden ' ' Die Befehlsaufrufe in der Hauptschleife lauten nunmehr: ' If Com<10 On Com Gosub Wert,Wert,Wert,In_gr,Verz,Gitt,Phol,Fhol,G3d Else On Com-9 Gosub F_use,Quader,D,D,D.D,D,D,Olad,Osp,Pstp Endif ' ' Und die Data-Zeilen mit dan MenĂŒtasten folgendermaßen: ' Data "- X: +" Data "- Y: +" Data "- Z: +"" Data INFO + ANZEIGEMODUS Data TIEFEN-VERZERRUNG Data GITTER | SETZEN Data PUNKTMOD|XYZ-EING Data FLÄCHEN ERSTELLEN Data 3D-GRAFIK STARTEN Data FLÄCHEN EDITIEREN Data QUADER EINGEBEN Data FREI,FREI,FREI Data FREI,FREI,FREI Data OBJ LADEN|PFAD BEST Data SPEICHERN|PFAD BEST Data 3D PROGRAMM BEENDEN ' ' Die nun folgenden Prozeduren werden einfach an das Originalprogramm ' angehĂ€ngt, eigene Funktionen mĂŒsstan problemlos ' weiterbenĂŒtzt werden können. ' Procedure Verz ! Bildschirmverzerrung einstellen Local I,J,A$ A$="Darstellungsverzerrung:|Je nĂ€her sie die Maus dem|Mittelpunkt bringen" Gosub Ali(0,A$+' desto|stĂ€rker die Verzerrung.",1,"Aha!") Gosub Mclr J=Grmbo ! Schnelle Darstellung Grmbo=0 Repeat Darstx=(Mousex-Ymi)/10 ! Verzerrung x und y anhand Darsty=(Ymi-Mousey)/10 ! des Mittelpunkts berechnen If Darstx=0 ! DĂŒrfen aber nicht 0 betragen Darstx=1 Endif If Darsty=0 ! dito Darsty=1 Endif Gosub Show ! VerĂ€nderungen anzeigen Until Mousek ! bis Maustaste geklickt wird Grmbo=J ! Originaldarstellung wieder herstellen Return ' Procedure Hol_pfad ! Kein Kommentar Gosub Inbox("DEN ZUGRIFFSPFAD FÜR|DIE DATEN ANGEBEN.|z.B: A:\GFA\GRAFIK\3D\",1) Disk$=Wert$ Return '' Procedure Osp ! Objekt abspeichern Local I,J,Maxeck If Mk=2 Gosub Hol_pfad ! Bei Rechtsklick Pfad holen Else ! sonst: Fileselect Disk$+"*.3D?",F$ If F$<>"" Open "O",#1,F$ ! Falls guter Dateiname öffnen Maxeck=0 For I=0 To F_anz-1 If Fl%(Eck_max+1,I)>Maxeck Maxeck=Fl%(Eck_max+1,I) ! Maximale Eckanzahl einer FlĂ€che des Endif ! Objekts ermitteln Next I Gosub Byte(F_anz) ! Punktanzahl, Gosub Byte(F_anz) ! FlĂ€chenanzahl Gosub Byte(Maxeck) ! und maximale Eckenanzahl zur Datai If P_anz For I=1 To P_anz For J=0 To 2 Gosub Byte(Xyz%(J,I)) ! Alle Punktkoordinaten, Next J Next I Endif If F_anz For I=0 To F_anz-1 For J=0 To Maxeck Gosub Byte(Fl%(J,I))! alle relevanten FlĂ€chennummern Next J For J=Eck_max+1 To Eck_max+3 Gosub Byte(Fl%(J,I))! und die FlĂ€cheninformationen ausgeben. Next J Next I Endif Close #1 ! Das war es schon. Endif Endif Return ' Procedure Byte(W) ! Diese Proz. wirft 2 Bytes zur Diskette W=W+32768 Out #1,(W Div 256) Out #1,(W Mod 256) Return ' Procedure Olad ! LĂ€dt ein Objekt von Disk Local I,J,Maxeck If Mk=2 Gosub Hol_pfad ! Rechtsklick -> holt Pfad Else Fileselect Disk$+"*.3D?","",F$ If F3<>"" Open "I",#1,F$ ! Falls guter Dateiname anfĂŒgan Gosub Wrd I=Ww ! und 3 Words einlesen Gosub Wrd J=Ww Gosub Wrd Maxeck=Ww If Maxeck>Eck_max ! Maximale Eckanzahl möglich? Gosub Ali(3,"Objekt hat mehr Ecken|als die Var. Eck_max.",1,"Stop") Else P_anz=I ! JA, Werte ĂŒbernehmen F_anz=J If P_anz For I=1 To P_anz For J=0 To 2 Gosub Wrd Xyz%(J,I)=Ww ! Alle Punktkoordinaten Next J Next I Endif If F_anz For I=0 To F_anz-1 For J=0 To Maxeck Gosub Wrd Fl%(J,I)=Ww ! alle FlĂ€chennummern Next J For J=Eck_max+1 To Eck_max+3 Gosub Wrd Fl%(J,I)=Ww ! und alle FlĂ€cheninfos lesen. Next J Next I Endif Endif Close #1 ! das wars... Endif Endif Return ' Procedure Wrd ! Diese Procedure liest 2 Bytes Wl=Inp(#1) Ww=Wl*256+Inp(#1)-32768 Return ' Procedure Pstp ! Programm abbrechen??? Local A$ A$="Programm wirklich|beenden und alle|Daten vernichten?" Gosub Ali(3,A$,2," JA |Nein") If But=1 Cls ! Jawoll!!! End Endif Return ' ' Diese umfangreiche Procedure ermöglicht die Edierung von FlĂ€chen: ' Procedure F_use Local Mmx,Mmy,Mmk,I,Stnr,Aktnr,Rnr,A$ If F_anz A$="Sie können links die FlĂ€che|auswĂ€hlen und durch|Mausklick edieren!" Gosub Ali(0,A$+"ZurĂŒck mit Rechtsklick!",1,"Aha!") Deffill 0,1 Pbox 0,0,50,Ysl Text 10,Tyo,"^^^^^" Text 10,Yty*19+Tyo,"vvvvv" ! Bildschirm ruinieren Color 1 Stnr=0 ! Startnummer = 0 ' Starty: Deffill 0,1 Pbox 0,Yty,50,Yty*19 ! FlĂ€chenbox am linken Schirmrand Aktnr=-1 For I=1 To 18 Box 0,Yty*I,50,Yty*(I+1) ! Box ausgeben If Stnr+I-1<F_anz A$=Str$(Stnr+I)+" "+Str$(Fl%(Eck_max+1,Stnr+I-1)+1)+"P" Text 28-3*Len(A$),Yty*I+Tyo,A$ ! Text ausgeben Mmy=Fl%(Eck_max+2,Stnr+I-1) Mmx=Fl%(Eck_max+3,Stnr+I-1) If Max Deffill 1,Mmx,Mmy Else Deffill Mmy,1 Endif Pbox 0,Yty*I,8,Yty*(I+1) ! FĂŒllfarbe oder -muster Endif Next I Do ! Warteschleife Mouse Mmx,May,Mak If Mmx<40 ! Maus In Box? I=Mmy Div Yty If I>0 And I<19 And Stnr+I-1<F_anz ! ja, gĂŒltige FlĂ€chennummer? If I<>Aktnr Graphmode 3 ! ja, aktivieren If Aktnr<>I ! alte ausschalten??? Box 10,Yty*Aktnr+2,48,Yty*(Aktnr+1)-2 ! jawoll Endif Box 10,Yty*I+2,48,Yty*(I+1)-2 ! Inrandung Aktnr=I ! aktive Position Rnr=Stnr+Aktnr-1 ! aktuelle FlĂ€chennummer Graphmode 0 Endif Endif If Mmk=1 ! Maus auch noch gedrĂŒckt? If I>0 And I<19 ! ja, auf FlĂ€chennummer? If Aktnr<>-1 Gosub Ali(2,"FlĂ€che löschen oder|neu einfĂ€rben ???",1,"Mix|Kill|Farbe") If But=3 Gosub Colget ! neue Farbe oder Muster holen Fl%(Eck_max+2,Rnr)=Cnr !abspeichern Fl%(Eck_max+3,Rnr)=Czei Endif If But=2 And F_anz>0 !FlĂ€che löschen??? For I=Rnr To F_anz !jawoll, durch Verschieben For J=0 To Eck_max+3 ! hinauswerfen Fl%(J,I)=Fl%(J,I+1) Next J Next I Dec F_anz ! FlĂ€chenzĂ€hler -= 1 Endif Endif Goto Starty ! und neue Box zeichnen.. Else If I=0 ! Nach oben scrollen? Sub Stnr,16 If Stnr<0 Stnr=0 Endif Goto Starty Else Add Stnr,16 ! ansonsten nach unten If Stnr+16>F_anz Stnr=F_anz-18 Endif Goto Starty Endif Endif Endif Endif If Aktnr<>-1 ! Falls FlĂ€che gewĂ€hlt Gosub Flacker(Stnr+Aktnr-1) ! Die Punkte blinken Gosub Flacker(Stnr+Aktnr-1) ! lassen Endif Exit If Mmk=2 ! Bei Rechtsklick beenden Loop Endif Return ' Procedure Flacker(F_nr) ! Punktblinkroutine Local I,J,X,Y Graphmode 3 For J=0 To Fl%(Eck_max+1,F_nr) ! Alle Punkte I=Fl%(J,F_nr) ! umrechnen X=Ymi-Arbxyz%(0)+(Xyz%(0,I)+(Xyz%(2,I)-Arbxyz%(2))/Darstx) Y=Ymi-Arbxyz%(1)-(Xyz%(1,1)+(Xyz%(2,I)-Arbxyz%(2))/Darsty) Xf X>53 And X<Ys-3 ! und falls sichtbar Circle X,Y,4 ! anzeigen Endif Next J Graphmode 0 Return ' Procedure Quader ! Quader in einem Zug erstellen Local P1,P2,P3,P4,P5,P6,F7,P8,I,Bo,A$ A$="Quader erstellen. Wodurch|festlegen? (Mitte oder|Ecke unten links vorne)" Gosub Ali(2,A$,1,"Nix|Mitte|Ecke") If But>1 Gosub Inbox("LÄNGE DER X,YZ-SEITEN|EINGEBEN.",3) Bo=1 For I=0 To 2 Y%(I)=X%(I) ! Werte merken If Y%(I)=0 Bo=0 ! Falls 0 abbrechen Endif Next I If Bo Gosub Inbox("UND JETZT DEN BE-|FESTIGUNGSPUNKT ",3) If But=2 ! Falls Mittelpunkt For I=0 To 2 X%(I)=X%(I)-Y%(I)/2 ! Un.li vor Ecke errechnen Next I Endif Gosub P_neu(X%(0),X%(1),X%(2)) ! Alle neuen Punkte anfordern P1=Pnr Gosub P_neu(X%(0),X%(1)+Y%(1),X%(2)) P2=Pnr Gosub P_neu(X%(0)+Y%(0),X%(1)+Y%(1),X%(2)) P3=Pnr Gosub P_neu(X%(0)+Y%(0),X%(1),X%(2)) P4=Pnr Gosub P_neu(X%(0),X%(1),X%(2)+Y%(2)) P5=Pnr Gosub P_neu(X%(0),X%(1)+Y%(1),X%(2)+Y%(2)) P6=Pnr Gosub P_neu(X%(0)+Y%(0),X%(1)+Y%(1),X%(2)+Y%(2)) P7=Pnr Gosub P_neu(X%(0)+Y%(0),X%(1),X%(2)+Y%(2)) P8=Pnr Gosub F14_neu(P1,P2,P3,P4) ! und die 6 FlĂ€chen erstellen Gosub F14_neu(P1,P5,P6,P2) Gosub F14_neu(P2,P6,P7,P3) Gosub F14_neu(P3,P7,P8,P4) Gosub F14_neu(P4.P8,P5,P1) Gosub F14_neu(P8,P7,F6,P5) Endif Endif Return ' Procedure F14_neu(A,B,C.D) ! 4-PunktflĂ€che erstellen Fl%(0,F_anz)=A Fl%(1,F_anz)=B Fl%(2,F_anz)=C Fl%(3,F_anz)=D Fl%(Eck_max+1,F_anz)=3 ! alles eintragen Gosub Colgat ! Farbe oder Muster holen Fl%(Eck_max+2,F_anz)=Cnr ! abspeichern Fl%(Eck_max+3,F_anz)=Czei Inc F_anz ! FlĂ€chenzĂ€hler erhöhen Return

Listing: 3 D-Grafik-Edier- und Demoprogramm Teil 2