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

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



Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]