void ddlinetc(double x1,double y1,double z1,double x2,double y2,double z2,double cx,double cy,double cz, double ctx, double cty, double ctz, unsigned char color, double bw) { double alphax; double betax; double gammax; double alphay; double betay; double gammay; signed int px1; signed int py1; signed int px2; signed int py2; double h1; double h2; alphax= atan(ctx-cx/cz-ctz); betax = atan(x1-cx/cz-z1); gammax= alphax-betax; alphay= atan(cty-cy/cz-ctz); betay = atan(y1-cy/cy-z1); gammay= alphay-betay; h1 = 65.0 + (tan(gammax) * bw); h2 = 65.0 + (tan(gammay) * bw); px1 = round(h1); py1 = round(h2); alphax= atan(ctx-cx/cz-ctz); betax = atan(x2-cx/cz-z2); gammax= alphax-betax; alphay= atan(cty-cy/cz-ctz); betay = atan(y2-cy/cz-z2); gammay= alphay-betay; h1 = 65.0 + (tan(gammax) * bw); h2 = 65.0 + (tan(gammay) * bw); px2 = round(h1); py2 = round(h2); lcd_line(px1,py1,px2,py2, color); } int round(double d) { return d<0?d-.5:d+.5; } Dieses Programm ist Teil einer kleinen 3d-Engine, die ich für ein kleines Farbdisplay schreibe... bis jetzt hat alles geklappt... mit dem Taschenrechner habe ich alles nachgerechnet... mit den Werten die ich in diese Fkt einsetze sollte für px und py 68,342 rauskommen... folglich sollte die funktion erstmal einen pixel an 68/68 setzen... macht sie aber nicht :( hab ich vielleicht mit den Dateitypen etwas falsch gemacht? ChriZi
PS: Die funktion macht garnichts... das heisst, sie sendet nur nullen, oder Werte über 130 an die Line-Funktion... ChriZi
Ich würde sagen da fehlen ein paar Klammern:
> betay = atan(y1-cy/cy-z1);
Das bedeutet: atan(y1 - 1.0 - z1);
Soll das so sein?
- Michael
Was soll denn die Funktion machen? Ev. gibt es eine Möglichkeit ohne die ganzen atan() und tan() auszukommen. 1) ruinieren sie dir Genauigkeit 2) sind Winkelfunktionen immer langsam 3) schlägst du dich bei 90° mit unendlich herum -> eine Funktion wie tan() braucht man in der Comutergraphik eigentlich nie. sin() / cos() kommt manchmal vor, hauptsächlich dann wann es darum geht irgendwelche Ergebnisse dem Benutzer in Zahlenform zu präsentieren, bzw. Benutzereingaben engtgegen zu nehmen. Alles andere kann normalerweise mittels Velktoren und Matrizen erschlagen werden.
Die Funktion zeichnet eine Linie im 3dimensionalen Raum und projeziert die Pixel auf einen 130x130 großen Bereich unter beachtung einer Kameraposition und einer Kamera-Target-Position... ausserdem lässt sich mit "bw" noch die Entfernung von Projektionsfläche zum Augpunkt einstellen... Bis jetzt bin ich immer mit Pythagoras ganz gut zurechtgekommen, aber sobald sich die Kamera um das Objekt dreht, komme ich nur noch mit Winkelfkts weiter... Meinst du mit Matrizen eine Wertetabelle für die tan()-Werte? ChriZi
Nein, ich meine eine echte Matrize. So eine Projektion lässt sich gut damit abbilden. Du solltest dir tatsächlich Literatur besorgen (Das kann ich hier auf dem begrenzten Raum und mit den Mitteln die mir das Forum bietet nicht nicht beschrieben), denn sowas macht man komplett anders. Vor allen Dingen berechnest du ja jedesmal die komplette Transformation für jede Linie neu aus den Kameraeigenschaften. Genau das organisiert dir aber die Matrix wesentlich besser. Die Kameraposition, sowie ihre Eigenschaften werden in eine Matrix zusammengefasst und die eigentliche Projektions- arbeit für eine Linie ist dann eine reine Punkt*Matrix Operation. D.h. die Linienfunktion sieht dann so aus: void ddlinetc( struct vector* Start, // Startkoordinate struct vector* End, // Endkoordinate unsigned char color, // Farbe der Linie double bw // ?? ) { struct vector tStart; struct vector tEnd; Multiply( Kamera, Start, &tStart ); Multiply( Kamera, End, &tEnd ); lcd_line( tSart.x, tStart.y, tEnd.x, tEnd.y, color); } Als Literatur in diesem Bereich würde ich dir empfehlen, mal den Foley / Van Damm - "Computer Graphics" zu besorgen. Ist zwar schon älter, aber die Grundlagen dafür sind gut beschrieben. Alternativ könnte ich mal versuchen ob ich noch eine Kopie eines Artikels von Jim-Blinn habe: "Nested Transformations and Blobby man". Auch dort ist der Aufbau über Vektoren und Matrizen und wie man mit ihnen arbeitet, gut enthalten. Kann ich aber erst morgen aus meiner Bibliothek raussuchen.
OK. Ich hab heute morgen beim Scannen irgendwo einen Fehler gemacht. Mir fehlen ein paar Seiten. Wird noch nachgereicht. In der Zwischenzeit, hab ich mal meine alten Source Bestände durchforstet und Code gefunden, der weitgehend auf dieser Vorlage basiert. Den hab ich mal soweit abgspeckt, dass er Posting-fähig ist. Du findest ihn im Anhang. In Graphics.cpp / Graphics.h sind die Graphik-Routinen. In main.c findest du eine kleine Anwendung. Da ich kein Display habe, musste ich das ganze unter Windows testen und dann blind alles Windows-spezifische rauswerfen. Ich hoffe, ich hab da mal keinen Fehler gemacht. Im schlimmsten Fall: Die Graphikfunktionen funktionieren, ev. Fehler können nur im main() sein (aber das musst du sowieso um die Initialisierung deines LCD erweitern), bzw in der Funktion DrawLine (und dort auch nur in dem Bereich in dem die tatsächliche Linie gezeichnet wird).
Danke! Ich glaube, ich les mich erstmal ein bisschen in Matrizentheorie rein ^^ ChriZi
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.