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