3D-Supergrafik
Ein dreidimensionales Grafikprogramm, das sich auch vor professionellen 3D-Programmen nicht zu verstecken braucht. Bewiesen wurde das, indem dieses Programm im Rahmen des Wettbewerbs »Jugend forscht ’85« mit dem Sonderpreis Elektronik ausgezeichnet wurde.
Mit diesem Programm ist es möglich, beliebige dreidimensionale Körper zu drehen und in verschiedenen Perspektiven darzustellen. Die Besonderheit dieses Programms ist jedoch, daß es eine Routine zur Lösung des Hinterschneidungsproblems besitzt. Diese Routine ermöglicht es, Körper naturgetreu darzustellen, indem sie Kanten, die von dem Körper verdeckt werden, löscht. Außer der Darstellung von Körpern besitzt das Programm natürlich auch Routinen zum Eingeben, Laden, Speichern und Ausdrucken von Körpern sowie eine eigene Grafikerweiterung in Maschinensprache.
Insgesamt ist das Programm sehr übersichtlich und leicht zu bedienen. Nur die Routine zur Eingabe von Körpern erfordert eine kurze Einarbeitungszeit. Denn zuerst müssen die Eckpunkt-Koordinaten eingegeben werden, dann die Nummern der Punkte, aus denen die Fläche besteht, und zwar in der Reihenfolge, in der sie verbunden werden sollen.
Die Routine zur Berechnung des Bildes erlaubt keine Fehleingaben, so daß man durch Probieren die Auswirkungen der einzelnen Faktoren auf das Bild bestimmen kann. Außerdem braucht sich der Benutzer nicht um die Größe der Darstellung zu kümmern, da dies vom Computer erledigt wird.
Die Speicherbelegung
Bei 3D-Supergrafik handelt es sich eigentlich um drei Programme: Einem Lader (Listing 1), eine Grafikerweiterung in Maschinensprache (Listing 3) und das Hauptprogramm in Basic (Listing 2). Diese Grafikerweiterung belegt den Speicherplatz von $C400 bis $CAFF. Außerdem benutzt sie zwei Grafikbildschirme unter den beiden ROM-Bereichen ($AOOO-$BFFF/$EOOO-$FFFF). Die dazugehörigen Farbspeicher liegen von $8C00 bis $8FFF und von $C000 bis $C3FF. Daraus folgt, daß das Hauptprogramm mit den Variablen im Bereich von $0800 bis $8BFF liegt. Soviel zur Speicherbelegung.
Das Programm
Nach Laden und Starten des Laders gelangt man nach dreißig Sekunden ins Hauptmenü, das fünf Menüpunkte zur Verfügung stellt. Auf die Bedienung der einzelnen Punkte werde ich im folgenden eingehen.
1. Daten eingeben
Bevor man einen dreidimensionalen Körper in den Computer eingeben kann, muß man ihn erst in mathematische Daten zerlegen. Das hört sich schwerer an als es eigentlich ist. Man zeichnet sich einfach eine Vorderansicht und eine Draufsicht des Körpers in Koordinatensysteme. Daraus kann man dann die Eckpunktkoordinaten und die Verbindungsvorschrift ablesen (siehe Bild 1). Nachdem Sie diese Arbeit erledigt haben, können Sie mit der Eingabe der Daten in den Computer beginnen.

Zuerst muß man die Anzahl der Eckpunkte (im Bild 1: 8 Punkte) und die Anzahl der Flächen (im Bild 1: 6 Flächen) des gewünschten Körpers eingeben. Danach sind die räumlichen Koordinaten der Eckpunkte an der Reihe. Nachdem man die Koordinaten des Punktes eingegeben hat, wird man vom Computer gefragt, ob die Eingabe richtig ist. Falls dies so ist, tippt man einfach weiter, falls nicht, drückt man die Taste »N«. Dann kann man die Werte noch einmal eingeben.
Nachdem man alle Eckpunkte definiert hat, muß man eingeben, in welcher Reihenfolge die Punkte zu jeder Fläche verbunden werden sollen. Ist man mit einer Fläche fertig, gibt man nur RETURN ein. Jetzt folgt wieder die Richtigkeitsabfrage des Computers, die analog zur vorherigen Frage beantwortet werden muß. Leider gibt es bei der Flächeneingabe noch eine Einschränkung. Eine Fläche darf nämlich nur aus vier Eckpunkten bestehen. Daraus folgt, daß große Flächen zerlegt, und auf mehrere kleine Flächen verteilt werden müssen (siehe Bild 2). Durch diese Maßnahme entstehen Linien, die die große Fläche teilen. Um so etwas zu vermeiden, kann der Anwender Linien eingeben, die später im Bild nicht gezeichnet werden. Das geht folgendermaßen:
Man schreibt hinter den Punkt, zu dem die nachher nicht sichtbare Linie führen soll, ein »I«.
So, das war das Schlimmste. Alles weitere ist einfach.

2. Daten laden
Dieser Menüpunkt dient dazu, die Daten eines Körpers von Diskette zu laden. Er bietet noch zwei Sonderfunktionen: »$« druckt das Directory der Datenfiles auf der Disk »@« Rückkehr zum Hauptmenü
Bei der Angabe, welches Bild zu laden ist, darfdas »3D-« nicht mit eingegeben werden.
3. Daten speichern
Diesen Menüpunkt sollte man sofort nach der Eingabe eines Körpers aufrufen, um die Daten zu sichern. Er speichert die Daten in einem platzsparendem Format auf Disk. Die Sonderfunktiorien sind analog zu Punkt 2. Dem Dateinamen wird automatisch ein »3D-« vorangestellt.
4. Bild berechnen
Es handelt sich hierbei um den umfangreichsten Punkt des Programmes, der aber nicht schwer zu verstehen ist. Die Auswirkung der einzelnen Parameterauf das Bild läßt sich am besten durch folgende Methode herausfinden: Probieren, probieren, probieren …
Für Interessierte möchte ich hier noch erwähnen, wie ich das Hinterschneidungsproblem in meinem Programm gelöst habe:
Der Computer zeichnet die hinterste Fläche zuerst und füllt sie im unsichtbaren Grafikschirm aus (zu sehen, wenn Sie »F2« drücken). Jeden Punkt, den er dort setzt, löscht er in der sichtbaren Grafik.Auf diese Weise verfährt er auch mit den anderen Flächen, die vorderste Fläche zeichnet er zuletzt. Diese Verfahrensweise läßt sich sehr gut beim Bildaufbau beobachten. Es sieht aus, als ob der Computer den Körper aus einzelnen Teilen zusammensetzt. Es lohnt sich auch, mit den Funktionstasten F1 und F2 beim Bildaufbau zwischen den beiden Grafikseiten hin- und herzuschalten.
Wenn das Bild .fertig gezeichnet ist, kommt man mit der Leertaste wieder in den Textbildschirm. Dort wird man gefragt, ob noch etwas an der Grafik zu ändern ist. Wenn diese Frage bejaht wird, gelangt man in einen kleinen Grafikeditor. Man bewegt das Kreuz mit dem Joystick (Port 2) über den Bildschirm. Bei gedrücktem Feuerknopf werden Punkte gesetzt oder gelöscht. Mit den Tasten »%« und »L« kann man zwischen Punkt setzen und Punkt löschen hin- und herschalten. Verlassen kann man den Editor mit »E«.
5. Hardcopy
Dieser Menüpunkt sendet eine Hardcopy für einen Epson FX/RX-80 auf den seriellen Bus. Falls Sie über einen solchen Drucker verfügen, brauchen Sie nur noch die Sekundäradressen an Ihr Interface anpassen. In Zeile 395 setzen Sie die Sekundäradresse für Groß-/Klein-Schrift ein, in Zeile 407 die Sekundäradresse für den Epson-Direkt-Modus (ohne Auto-Linefeed !).
Sonstige Hinweise
- Falls Sie das Programm mit RUN/STOP unterbrochen haben und die Variablen noch vorhanden sind, können sie es mit »GOTO 115« wieder starten.
- Die Funktionstasten sind folgendermaßen belegt:
F1: Grafik 1
F3: Grafik 2
F5: Textbildschirm
F7: Textbildschirm - Drücken Sie die Funktionstasten nie während Operationen auf dem seriellen Bus (Laden/Speichern/Hardcopy).
- Der Bereich von $9000 bis $9FFF ist aus Hardwaregründen unbenutzt (»Geisterbilder« des Zeichen-ROMs). Dort können eigene Hardcopyroutinen untergebracht werden.
- Man kann sich unter dem Menüpunkt »Bild berechnen« auch die Werte ausgeben lassen, um dann ein Bild von Hand zu zeichnen.
In Bild 3 bis Bild 6 sehen Sie noch einige Beispiele.
Zum Schluß möchte ich Ihnen noch viel Spaß bei der Arbeit mit meinem Programm wünschen.
(Oliver Günter/gk)



$0000 | Zeropage |
$0400 | Textbildschirm |
$0800 | Programm und Variablen |
$8000 | Farbspeicher 2 |
$9000 | frei |
$A000 | Basic-ROM und Grafik 2 |
$C000 | Farbspeicher 1 |
$C400 | Grafikerweiterung |
$D000 | I/O-Bereich |
$E000 | Kernal-ROM und Grafik 1 |
SYS 50176 | Grafik 1 ein |
SYS 50179 | Grafik 2 ein |
SYS 50182 | Textbildschirm ein |
SYS 50185 | Grafik 1 löschen |
SYS 50188 | Grafik 2 löschen |
SYS 50191,F1,F2 | Farbe setzen für Grafik 1+2 |
SYS 50194,X,Y | Punkt setzen |
SYS 50197,X,Y | Punkt löschen |
SYS 50200,X1,Y1,X2,Y2 | Linie ziehen |
SYS 50203,X1,Y1,X2,Y2 | Linie löschen |
SYS 50206,X,Y | Hinterschneidungsroutine |
SYS 50209 | Directory |
SYS 50212 | Funktionstasten initialisieren |
SYS 50215,LF | Hardcopy |
Arrays: | |
DX,DY,DZ | Eckpunktkoordinaten eines Körpers |
WX,WY,WZ | Eckpunktkoordinaten nach dem Drehen |
BX,BY | Bildschirmkoordinaten der Eckpunkte |
MX,MY,MZ | Koordinaten der Flächenmitteltunkte |
FL | Eckpunkte einer Fläche |
PF | Punktanzahl einer Fläche |
RF | Reihenfolge der Flächen |
Strings: | |
IN$ | Gedrückte Taste |
FU$ | Funktionsstring (Überschrift) |
FL$ | Filename |
Einfache Variablen: | |
V | VIC-Basisadresse |
Q,W,E,R | Laufvariablen |
AP | Anzahl Punkte |
AF | Anzahl Flächen |
FX,FY,FZ | Koordinaten des Augpunktes |
ZX,ZY,ZZ | Zwischenwertspeicher |
AE | Vergrößerungsfaktor |
JO | Joystickregister Port 2 |
XD,YD,ZD | Drehwinkel um X-, Y- und Z-Achse |
FE,T,S | Nummer des Diskfehlers, Track, Sector |
XP,YP,WI,WK | Hilfsvariablen der Drehroutine |
M,N,B,C | Hilfsvariablen der Fluchtpunktroutine |
PX,NX,PY,NY | Hilfsvariablen bei der Größenberechnung |
AX,AY,BX,BY | Hilfsvariablen bei der Größenberechnung |
LO | Löschvariable |
100 ifc=1thengoto115 101 poke53280,15:poke53281,15:printchr$(147)chr$(144)chr$(9)chr$(14)chr$(8); 102 print"Funktion : Hauptprogramm laden" 103 print"{blu}****************************************"; 104 print"* {blk}3D-Supergrafik {blu}*"; 105 print"* *"; 106 print"* {blk}von Oliver Guenter {blu}*"; 107 print"****************************************" 108 poke55,255:poke56,139 109 forq=0to62 110 readw 111 poke53184+q,w 112 next 113 c=1 114 load"3d-1",8,1 115 print"{gry3}{down}{down}{down}load";chr$(34);"3d-2";chr$(34);",8,1 116 print"{down}{down}{down}{down}run" 117 print"{up}{up}{up}{up}{up}{up}{up}{up}"; 118 forq=0to2:poke631+q,13:next 119 poke198,3 120 data0,0,0,0,0,0,0,16,0,0,16,0 121 data0,16,0,0,16,0,0,16,0,0,16,0 122 data0,0,0,0,0,0,31,131,240,0,0,0 123 data0,0,0,0,16,0,0,16,0,0,16,0 124 data0,16,0,0,16,0,0,16,0,0,0,0 125 data0,0,0
PROGRAMM : 3D-1 C400 CAAE ----------------------------------- C400 : 4C 2A C4 4C 33 C4 4C 3C 1F C408 : C4 4C 4C C4 4C 5B C4 4C E9 C410 : 6A C4 4C 9C C4 4C B9 C4 A2 C418 : 4C 8D C5 4C 94 C5 4C 47 5D C420 : C7 4C 4D C9 4C B8 C9 4C E4 C428 : 15 CA A9 3B A2 08 A0 00 61 C430 : 4C 42 C4 A9 3B A2 38 A0 EF C438 : 01 4C 42 C4 A9 1B A2 17 B5 C440 : A0 03 8D 11 D0 8E 18 D0 6B C448 : 8C 00 DD 60 A0 00 84 FA 6A C450 : A9 E0 85 FB A9 00 A2 20 AF C458 : 4C 8F C4 A0 00 84 FA A9 14 C460 : A0 85 FB A9 00 A2 20 4C 25 C468 : 8F C4 A0 00 84 FA A9 C0 CA C470 : 85 FB 20 FD AE 20 9E B7 90 C478 : 8A A2 04 20 8F C4 A0 00 FA C480 : 84 FA A9 8C 85 FB 20 FD 32 C488 : AE 20 9E B7 8A A2 04 A0 F4 C490 : 00 91 FA C8 D0 FB E6 FB B1 C498 : CA D0 F4 60 20 D6 C4 20 20 C4A0 : FF C4 A9 00 85 FE A9 E0 24 C4A8 : 85 FF 20 5D C5 A9 00 85 95 C4B0 : FE A9 A0 85 FF 20 5D C5 5E C4B8 : 60 20 D6 C4 20 FF C4 A9 DF C4C0 : 00 85 FE A9 E0 85 FF 20 F2 C4C8 : 62 C5 A9 00 85 FE A9 A0 AF C4D0 : 85 FF 20 62 C5 60 20 FD 85 C4D8 : AE 20 EB B7 86 02 A5 14 BF C4E0 : 85 FA A5 15 85 FB E0 C8 3C C4E8 : 90 06 20 3C C4 4C 48 B2 40 C4F0 : A5 FB C9 01 90 08 D0 F2 98 C4F8 : A5 FA C9 40 B0 EC 60 A5 D4 C500 : 02 29 F8 85 FE 85 FC A9 E9 C508 : 00 85 FD 06 FC 26 FD 06 10 C510 : FC 26 FD 18 A5 FC 65 FE 78 C518 : 85 FC A5 FD 69 00 85 FD ED C520 : 06 FC 26 FD 06 FC 26 FD CA C528 : 06 FC 26 FD A5 02 29 07 13 C530 : 18 65 FC 85 FC A5 FD 69 B2 C538 : 00 85 FD 18 A5 FA 29 F8 46 C540 : 65 FC 85 FC A5 FB 65 FD F0 C548 : 85 FD 18 A5 FA 29 07 49 2E C550 : 07 AA A9 01 CA 30 03 0A 85 C558 : D0 FA 85 02 60 38 08 4C C7 C560 : 64 C5 18 08 18 A5 FE 65 23 C568 : FC 85 FA A5 FF 65 FD 85 C8 C570 : FB A5 02 A0 00 A2 34 28 09 C578 : 78 86 01 90 04 11 FA B0 9C C580 : 04 49 FF 31 FA 91 FA A2 BC C588 : 37 86 01 58 60 A9 FF 85 AC C590 : 97 4C 98 C5 A9 00 85 97 0C C598 : 20 D6 C4 A5 02 8D AE CA E6 C5A0 : A5 FA 8D B7 CA A5 FB 8D 01 C5A8 : B8 CA 20 D6 C4 A5 02 8D 45 C5B0 : AF CA A5 FA 8D B0 CA AD 72 C5B8 : B7 CA 85 14 A5 FB 8D B1 8C C5C0 : CA AD B8 CA 85 15 A0 01 6E C5C8 : 8C BC CA 8C B9 CA 8C B7 8A C5D0 : CA 88 8C B8 CA 8C BB CA AE C5D8 : 8C BA CA 88 AD B1 CA C5 A4 C5E0 : 15 90 09 D0 1E AD B0 CA 41 C5E8 : C5 14 B0 17 38 A5 14 ED A3 C5F0 : B0 CA 8D B5 CA A5 15 ED 29 C5F8 : B1 CA 8D B6 CA 8C BC CA E2 C600 : 4C 14 C6 38 AD B0 CA E5 66 C608 : 14 8D B5 CA AD B1 CA E5 09 C610 : 15 8D B6 CA AD AF CA CD 12 C618 : AE CA B0 10 38 AD AE CA 9B C620 : ED AF CA 8D B4 CA 8C B9 90 C628 : CA 4C 32 C6 ED AE CA 8D 18 C630 : B4 CA AD B6 CA D0 24 AD AB C638 : B5 CA CD B4 CA B0 1C AE 5C C640 : B4 CA 8D B4 CA 8E B5 CA E1 C648 : AD BC CA 8D BA CA AD B9 E4 C650 : CA 8D BB CA C8 8C BC CA A2 C658 : 8C B9 CA AD B6 CA 4A 8D 2F C660 : B3 CA AD B5 CA 6A 8D B2 36 C668 : CA 4C FF C6 AD BC CA 30 7D C670 : 0E 18 65 14 85 14 A5 15 20 C678 : 69 00 85 15 4C 8C C6 38 9A C680 : A5 14 E9 01 85 14 A5 15 84 C688 : E9 00 85 15 18 AD AE CA B5 C690 : 6D BB CA 8D AE CA 18 AD 3C C698 : B2 CA 6D B4 CA 8D B2 CA 1B C6A0 : AD B3 CA 69 00 8D B3 CA D7 C6A8 : EE B7 CA D0 03 EE B8 CA 5F C6B0 : AD B3 CA CD B6 CA 90 47 36 C6B8 : D0 08 AD B5 CA CD B2 CA 2A C6C0 : B0 3D 38 AD B2 CA ED B5 77 C6C8 : CA 8D B2 CA AD B3 CA ED DE C6D0 : B6 CA 8D B3 CA AD BA CA 60 C6D8 : 30 0E 18 65 14 85 14 A5 CB C6E0 : 15 69 00 85 15 4C F5 C6 74 C6E8 : 38 A5 14 E9 01 85 14 A5 0D C6F0 : 15 E9 00 85 15 18 AD AE D1 C6F8 : CA 6D B9 CA 8D AE CA AD 15 C700 : AE CA 85 02 A5 14 85 FA BC C708 : A5 15 85 FB 20 23 C7 AD AE C710 : B8 CA CD B6 CA 90 09 AD 28 C718 : B5 CA CD B7 CA B0 01 60 94 C720 : 4C 6C C6 20 FF C4 A9 00 25 C728 : 85 FE A9 A0 85 FF 20 5D 3E C730 : C5 A9 00 85 FE A9 E0 85 46 C738 : FF A5 97 F0 04 20 5D C5 50 C740 : 60 20 62 C5 60 A5 FA 20 61 C748 : D6 C4 A5 FA 8D BD CA A5 86 C750 : FB 8D BE CA A5 02 8D BF 3B C758 : CA A9 00 8D C6 CA 8D C7 31 C760 : CA 8D C8 CA A0 01 8C C3 48 C768 : CA 8D C4 CA 8C C5 CA 20 E6 C770 : 08 C8 AD BD CA 85 FA AD 1F C778 : BE CA 85 FB AD BF CA 85 8B C780 : 02 20 00 C9 A5 02 F0 01 FC C788 : 60 AD BD CA 85 FA AD BE EC C790 : CA 85 FB 18 AD BF CA 6D FE C798 : C5 CA 85 02 20 00 C9 A5 D8 C7A0 : 02 F0 05 A9 01 8D C8 CA C6 C7A8 : AD C3 CA 49 FE 8D C3 CA 14 C7B0 : AD C4 CA 49 FF 8D C4 CA B0 C7B8 : 20 3C C8 AD C3 CA 49 FE 94 C7C0 : 8D C3 CA AD C4 CA 49 FF 5F C7C8 : 8D C4 CA 20 3C C8 18 AD 34 C7D0 : BF CA 6D C5 CA 8D BF CA B6 C7D8 : AD C8 CA D0 03 4C F5 C7 B0 C7E0 : AD C5 CA C9 01 F0 01 60 B8 C7E8 : A9 FF 8D C5 CA A9 00 8D C2 C7F0 : C8 CA 20 22 C8 AD C7 CA 18 C7F8 : D0 03 4C 89 C7 A9 00 8D 73 C800 : C7 CA 20 22 C8 4C 89 C7 1D C808 : AE C6 CA AD BD CA 9D C9 BE C810 : CA AD BE CA 9D D3 CA AD B9 C818 : BF CA 9D DD CA E8 8E C6 1B C820 : CA 60 AE C6 CA CA BD C9 2C C828 : CA 8D BD CA BD D3 CA 8D 42 C830 : BE CA BD DD CA 8D BF CA 2C C838 : 8E C6 CA 60 AD BD CA 8D F7 C840 : C0 CA AD BE CA 8D C1 CA 5E C848 : AD BF CA 8D C2 CA AD BD EE C850 : CA 85 FA AD BE CA 85 FB A1 C858 : AD BF CA 85 02 20 E6 C8 96 C860 : 18 AD BD CA 6D C3 CA 85 43 C868 : FA AD BE CA 6D C4 CA 85 75 C870 : FB AD BF CA 85 02 20 00 74 C878 : C9 A5 02 F0 13 AD C0 CA EA C880 : 8D BD CA AD C1 CA 8D BE 7A C888 : CA AD C2 CA 8D BF CA 60 F5 C890 : 18 AD BD CA 6D C3 CA 8D 83 C898 : BD CA 85 FA AD BE CA 6D 52 C8A0 : C4 CA 8D BE CA 85 FB AD 29 C8A8 : C8 CA D0 03 4C 4E C8 18 F4 C8B0 : AD BF CA 6D C5 CA 85 02 6A C8B8 : 20 00 C9 A5 02 F0 03 4C 4C C8C0 : 4E C8 18 AD BF CA 6D C5 C2 C8C8 : CA 8D BF CA 20 08 C8 38 78 C8D0 : AD BF CA ED C5 CA 8D BF 35 C8D8 : CA A9 00 8D C8 CA A9 01 B4 C8E0 : 8D C7 CA 4C 4E C8 20 FF 39 C8E8 : C4 A9 00 85 FE A9 E0 85 FD C8F0 : FF 20 62 C5 A9 00 85 FE FF C8F8 : A9 A0 85 FF 20 5D C5 60 17 C900 : 20 12 C9 20 FF C4 A9 00 6C C908 : 85 FE A9 A0 85 FF 20 2D BE C910 : C9 60 A6 02 E0 C8 90 06 96 C918 : 20 3C C4 4C 48 B2 A5 FB BA C920 : C9 01 90 08 D0 F2 A5 FA C0 C928 : C9 40 B0 EC 60 18 A5 FE 36 C930 : 65 FC 85 FA A5 FF 65 FD C0 C938 : 85 FB A5 02 A0 00 A2 34 61 C940 : 78 86 01 31 FA 85 02 A2 8B C948 : 37 86 01 58 60 A9 B0 85 2F C950 : BB A9 C9 85 BC A9 08 85 47 C958 : B7 85 BA A9 60 85 B9 20 0F C960 : D5 F3 A5 BA 20 B4 FF A5 E2 C968 : B9 20 96 FF A9 00 85 90 A9 C970 : A0 03 84 FB 20 A5 FF 85 6D C978 : FC A4 90 D0 2F 20 A5 FF 8F C980 : A4 90 D0 28 A4 FB 88 D0 93 C988 : E9 A6 FC 20 CD BD A9 20 B9 C990 : 20 D2 FF 20 A5 FF A6 90 33 C998 : D0 12 AA F0 06 20 D2 FF E7 C9A0 : 4C 93 C9 A9 0D 20 D2 FF 7A C9A8 : A0 02 D0 C6 20 42 F6 60 07 C9B0 : 24 3A 33 44 2D 2A 3D 53 06 C9B8 : 78 A9 C5 8D 14 03 A9 C9 BB C9C0 : 8D 15 03 58 60 A9 00 8D 12 C9C8 : 02 DC 8D 27 D0 AD 00 DC B5 C9D0 : 85 F9 A9 FF 8D 02 DC A5 64 C9D8 : C5 C9 03 D0 0B 20 3C C4 89 C9E0 : A9 00 8D 15 D0 4C 31 EA 99 C9E8 : C9 04 D0 0B 20 2A C4 A9 03 C9F0 : 01 8D 15 D0 4C 31 EA C9 A5 C9F8 : 05 D0 0B 20 33 C4 A9 00 2C CA00 : 8D 15 D0 4C 31 EA C9 06 73 CA08 : D0 08 20 3C C4 A9 00 8D 21 CA10 : 15 D0 4C 31 EA 20 FD AE CC CA18 : 20 9E B7 20 50 F2 A9 00 BC CA20 : A0 E0 85 FD 84 FE A2 19 4E CA28 : A0 0D 2C A0 05 B9 98 CA 84 CA30 : 20 D2 FF 88 10 F7 A9 28 82 CA38 : 85 15 A9 80 85 97 A9 00 7E CA40 : 85 14 A0 07 A9 34 78 85 01 CA48 : 01 B1 FD 85 02 A9 37 85 A7 CA50 : 01 58 A5 02 25 97 F0 07 08 CA58 : A5 14 19 A6 CA 85 14 88 5D CA60 : 10 E2 A5 14 20 D2 FF 46 F2 CA68 : 97 90 D3 A5 FD 69 07 85 43 CA70 : FD 90 02 E6 FE C6 15 D0 2F CA78 : C1 A9 0D 20 D2 FF A9 0A 3D CA80 : 20 D2 FF CA D0 A5 A9 1B 7A CA88 : 20 D2 FF A9 32 20 D2 FF B6 CA90 : A9 0D 20 D2 FF 4C CC FF B8 CA98 : 01 40 04 2A 1B 09 0D 14 56 CAA0 : 00 65 1B 17 33 1B 80 40 8B CAA8 : 20 10 08 04 02 01 DF
1 rem 2 rem 3d-supergrafik 3 rem by oliver guenter 4 rem graevingholzstr. 44 5 rem 4600 dortmund 16 6 rem tel: 0231/853317 7 rem 8 rem fuer c-64 mit vc-1541 9 rem 100 rem ******************************* 101 rem * initialisierung * 102 rem ******************************* 103 sys50212:sys50182:sys50191,15,15 104 v=53248:poke50168,63 105 pokev+21,0:pokev+32,15:pokev+33,15 106 dimdx(150),dy(150),dz(150) 107 dimmx(150),my(150),mz(150) 108 dimbx(150),by(150) 109 dimwx(120),wy(120),wz(120) 110 dimfl(120,8) 111 dimpf(120),rf(120) 112 rem ******************************* 113 rem * hauptmenue * 114 rem ******************************* 115 fu$="Hauptmenue":gosub124 116 printtab(11);"{down}-1- Daten eingeben" 117 printtab(11);"{down}-2- Daten laden" 118 printtab(11);"{down}-3- Daten speichern" 119 printtab(11);"{down}-4- Bild berechnen" 120 printtab(11);"{down}-5- Hardcopy" 121 getin$:in=val(in$) 122 oningoto134,175,201,228,387 123 goto121 124 rem ******************************* 125 rem * titel + funktion * 126 rem ******************************* 127 print"{clr}{blk}Funktion : ";fu$ 128 print"{blu}****************************************"; 129 print"* {blk}3D-Supergrafik {blu}*"; 130 print"* *"; 131 print"* {blk}(C) Oliver Guenter {blu}*"; 132 print"****************************************{blk}" 133 return 134 rem ******************************* 135 rem * daten eingeben * 136 rem ******************************* 137 fu$="Daten eingeben":gosub124 138 input"{down}Wie viele Punkte ";ap 139 ifap=0thengoto112 140 input"{down}Wie viele Flaechen ";af 141 ifaf=0thengoto112 142 forq=1toap 143 fu$="Punkte eingeben":gosub124 144 print"{down}Punkt :";q 145 input"{down}{down}X-Koordinate ";dx(q) 146 input"{down}Y-Koordinate ";dy(q) 147 input"{down}Z-Koordinate ";dz(q) 148 print"{down}richtig ?" 149 poke198,0:wait198,1 150 ifpeek(631)=78thenprint"{up}{up}{up}{up}{up}{up}{up}{up}{up}{up}":poke198,0:goto143 151 next 152 poke198,0 153 forq=1toaf 154 fu$="Flaechen eingeben":gosub124 155 print"{down}Flaeche :";q;"{down}" 156 r=0 157 forw=1to8 158 ifr=1thennext:goto168 159 print"Punkt :";w; 160 t$="" 161 inputt$ 162 t=val(t$) 163 ift<0ort>aporint(t)<>tthenprint"{up}{up}":goto159 164 ifright$(t$,1)="l"thent=-t 165 fl(q,w)=t 166 ift=0thenr=1:pf(q)=w-1:next 167 next:pf(q)=8 168 print"{down}richtig ?" 169 poke198,0:wait198,1 170 ifpeek(631)=78thenprint"{home}{down}{down}{down}{down}{down}{down}{down}{down}{down}":poke198,0:goto154 171 next 172 print"{down}{down}{rvon}< SPACE >{rvof}" 173 getin$:ifin$<>" "then173 174 goto112 175 rem ******************************* 176 rem * daten laden * 177 rem ******************************* 178 fu$="Daten laden ($=Dir)":gosub124 179 input"{down}Filename ";fl$ 180 iffl$="@"thengoto112 181 iffl$="$"thenprint:sys50209:goto179 182 open15,8,15:open1,8,2,"3d-"+fl$+",s,r" 183 gosub423 184 ifer=1thenclose1:close15:goto179 185 get#1,a$:ap=asc(a$) 186 forq=1toap 187 input#1,a$:dx(q)=val(a$) 188 input#1,a$:dy(q)=val(a$) 189 input#1,a$:dz(q)=val(a$) 190 next 191 get#1,a$:af=asc(a$) 192 forq=1toaf 193 get#1,a$:pf(q)=asc(a$) 194 forw=1topf(q) 195 get#1,a$:fl(q,w)=asc(a$)-128 196 next 197 next 198 close1 199 close15 200 goto112 201 rem ******************************* 202 rem * daten speichern * 203 rem ******************************* 204 fu$="Daten speichern ($=Dir)":gosub124 205 gosub413:ifer=1thengoto112 206 input"{down}Filename ";fl$ 207 iffl$="@"thengoto112 208 iffl$="$"thenprint:sys50209:goto206 209 open15,8,15:open1,8,2,"3d-"+fl$+",s,w" 210 gosub423 211 ifer=1thenclose1:close15:goto206 212 print#1,chr$(ap); 213 forq=1toap 214 print#1,dx(q) 215 print#1,dy(q) 216 print#1,dz(q) 217 next 218 print#1,chr$(af); 219 forq=1toaf 220 print#1,chr$(pf(q)); 221 forw=1topf(q) 222 print#1,chr$(fl(q,w)+128); 223 next 224 next 225 close1 226 close15 227 goto112 228 rem ******************************* 229 rem * bild berechnen * 230 rem ******************************* 231 fu$="Bild berechnen":gosub124 232 gosub413:ifer=1thengoto112 233 input"{down}X-Drehwinkel ";xd 234 input"{down}Y-Drehwinkel ";yd 235 input"{down}Z-Drehwinkel ";zd 236 input"{down}Hinterschneidung (j/n) ";hi$ 237 ifhi$="j"thenhi=1:goto240 238 ifhi$<>"n"thenprint"{up}{up}{up}":goto236 239 hi=0 240 input"{down}Fluchtpunkt (j/n) ";f$ 241 iff$="j"thenf=1:goto245 242 iff$<>"n"thenprint"{up}{up}{up}":goto240 243 f=0 244 goto247 245 input"{down}Augpunkt-Koor. 0,0,25{left}{left}{left}{left}{left}{left}{left}{left}";fx,fy,fz 246 iffz<=0thenprint"{up}{up}{up}":goto245 247 input"{down}Werte ausgeben (j/n) n{left}{left}{left}";we$ 248 ifwe$="j"thenwe=1:goto251 249 ifwe$<>"n"thenprint"{up}{up}{up}":goto247 250 we=0 251 print"{down}{down}Drehe Punkte" 252 forq=1toap 253 wx(q)=dx(q) 254 wy(q)=dy(q) 255 wz(q)=dz(q) 256 next 257 ifxd=0thengoto262 258 forq=1toap 259 wi=xd:xp=wy(q):yp=wz(q):gosub434 260 wy(q)=xp:wz(q)=yp 261 next 262 ifyd=0thengoto267 263 forq=1toap 264 wi=yd:xp=wz(q):yp=wx(q):gosub434 265 wz(q)=xp:wx(q)=yp 266 next 267 ifyd=0thengoto272 268 forq=1toap 269 wi=zd:xp=wx(q):yp=wy(q):gosub434 270 wx(q)=xp:wy(q)=yp 271 next 272 iff=1thengoto278 273 forq=1toap 274 bx(q)=wx(q) 275 by(q)=wy(q) 276 next 277 goto285 278 print"{up}Berechne Bildpunkte" 279 forq=1toap 280 x1=fx:y1=fy:z1=fz 281 x2=wx(q):y2=wy(q):z2=wz(q) 282 gosub446 283 bx(q)=x1:by(q)=y1 284 next 285 ifhi=0thengoto298 286 print"{up}Berechne Mittelpunkte" 287 forq=1toaf 288 zx=0:zy=0:zz=0 289 forw=1topf(q) 290 zx=zx+bx(abs(fl(q,w))) 291 zy=zy+by(abs(fl(q,w))) 292 zz=zz+wz(abs(fl(q,w))) 293 next 294 mx(q)=zx/pf(q) 295 my(q)=zy/pf(q) 296 mz(q)=zz/pf(q) 297 next 298 print"{up}Berechne Achseinheiten" 299 px=0:nx=0:py=0:ny=0 300 forq=1toap 301 zx=bx(q) 302 zy=by(q) 303 gosub458 304 next 305 ax=-(px+nx)/2 306 ay=-(py+ny)/2 307 bx=(abs(px)+abs(nx))/3.2 308 by=(abs(py)+abs(ny))/2 309 ae=bx 310 ifbx<bythenae=by 311 ae=ae*100/98 312 forq=1toaf 313 rf(q)=q 314 next 315 ifhi=0thengoto325 316 print"{up}Berechne Reihenfolge " 317 forq=1toaf-1 318 forw=q+1toaf 319 ifmz(rf(q))<=mz(rf(w))thengoto323 320 a=rf(q) 321 rf(q)=rf(w) 322 rf(w)=a 323 next 324 next 325 print"{up}Zeichne Bild " 326 sys50185:sys50176 327 forq=1toaf 328 sys50188 329 nf=rf(q) 330 forw=1topf(nf) 331 zx=bx(abs(fl(nf,w))) 332 zy=by(abs(fl(nf,w))) 333 gosub466 334 e=w+1:ife>pf(nf)thene=1 335 x=zx:y=zy 336 zx=bx(abs(fl(nf,e))) 337 zy=by(abs(fl(nf,e))) 338 gosub466 339 r=sgn(fl(nf,e)) 340 lo=0 341 ifr=1thengoto344 342 ifhi=0thengoto347 343 lo=3 344 sys50200+lo,x,y,zx,zy 345 iflo=3thensys50194,x,y 346 iflo=3thensys50194,zx,zy 347 next 348 ifhi=0thengoto353 349 zx=mx(nf) 350 zy=my(nf) 351 gosub466 352 sys50206,zx,zy 353 next 354 print"{up}{rvon}< SPACE >{rvof} " 355 getin$:ifin$<>" "thengoto355 356 sys50182 357 input"{up}Bild aendern (j/n) ";ae$ 358 ifae$="n"thengoto376 359 ifae$<>"j"thengoto357 360 x=160:y=100:lo=3:sys50176:pokev+21,1 361 getin$:ifin$="s"thenlo=0 362 ifin$="l"thenlo=3 363 ifin$="e"thenpokev+1,0:goto373 364 jo=peek(249) 365 if(joand1)=0andy>0theny=y-1 366 if(joand2)=0andy<199theny=y+1 367 if(joand4)=0andx>0thenx=x-1 368 if(joand8)=0andx<319thenx=x+1 369 if(joand16)=0thensys50194+lo,x,y 370 pokev,((x+13)and255):pokev+1,y+40 371 pokev+16,((x+13)and256)/256 372 goto361 373 print"{up}{rvon}< SPACE >{rvof} " 374 sys50182 375 getin$:ifin$<>" "thengoto375 376 ifwe=0thengoto112 377 forq=1toap 378 fu$="Werte ausgeben":gosub124 379 print"{down}Punkt :";q 380 print"{down}{down}X-Koordinate :";bx(q) 381 print"{down}Y-Koordinate :";by(q) 382 iff=0thenprint"{down}Z-Koordinate :";wz(q) 383 print"{down}{down}{rvon}< SPACE{$a0}>{rvof}" 384 getin$:ifin$<>" "thengoto384 385 next 386 goto112 387 rem ******************************* 388 rem * hardcopy epson rx-80 * 389 rem ******************************* 390 fu$="Hardcopy":gosub124 391 input"{down}Ist der Drucker wirklich an ";d$ 392 ifd$="j"thengoto395 393 ifd$<>"n"thenprint"{up}{up}{up}":goto391 394 goto112 395 open4,4,2:rem ++ gross/klein ++ 396 print#4 397 print#4,"Name : ";fl$ 398 print#4,"X-Drehwinkel :";xd 399 print#4,"Y-Drehwinkel :";yd 400 print#4,"Z-Drehwinkel :";zd 401 print#4,"Hinterschneidung : ";hi$ 402 print#4,"Fluchtpunkt : ";f$ 403 iff=1thenprint#4,"Augpunkt :";fx;",";fy;",";fz 404 print#4 405 print#4 406 close4 407 open4,4,1:rem ++ epson mode ++ 408 sys50215,4 409 print#4,chr$(10) 410 print#4,chr$(10) 411 close4 412 goto112 413 rem ******************************* 414 rem * auf daten testen * 415 rem ******************************* 416 er=0 417 ifap>0thenreturn 418 print"{down}{rvon}Keine Daten vorhanden !{rvof}" 419 print"{down}{down}{rvon}< SPACE >{rvof}" 420 getin$:ifin$<>" "thengoto420 421 er=1 422 return 423 rem ******************************* 424 rem * fehlerkanal abfragen * 425 rem ******************************* 426 er=0 427 input#15,fe,fe$,t,s 428 iffe=0thenreturn 429 print"{down}{rvon}Diskfehler :{rvof} ";fe$ 430 print"{down}{rvon}Track :{rvof}";t 431 print"{down}{rvon}Sektor :{rvof}";s 432 er=1 433 return 434 rem ******************************* 435 rem * rec->pol + wi pol->rec * 436 rem ******************************* 437 la=sqr(xp^2+yp^2) 438 ifxp=0thenwk=~/2*sgn(yp):goto442 439 wk=atn(yp/xp) 440 ifsgn(xp)=-1thenwk=wk+~*sgn(yp) 441 ifsgn(xp)=-1andsgn(yp)=0thenwk=~ 442 wk=wk+(wi*~/180) 443 xp=cos(wk)*la 444 yp=sin(wk)*la 445 return 446 rem ******************************* 447 rem * schnittpt. gerade/ebene * 448 rem ******************************* 449 ifx2=x1thengoto453 450 m=(z2-z1)/(x2-x1) 451 b=z1-m*x1 452 x1=-b/m 453 ify2=y1thengoto457 454 n=(z2-z1)/(y2-y1) 455 c=z1+n*y1 456 y1=-c/n 457 return 458 rem ******************************* 459 rem * ae berechnen * 460 rem ******************************* 461 ifpx<zxthenpx=zx 462 ifnx>zxthennx=zx 463 ifpy<zythenpy=zy 464 ifny>zythenny=zy 465 return 466 rem ******************************* 467 rem * bildkoor. berechnen * 468 rem ******************************* 469 zx=160+((zx+ax)*100/ae) 470 zy=100-((zy+ay)*100/ae) 471 return