Forum: Mikrocontroller und Digitale Elektronik Transformation Kartesische zu polaren Koordinaten


von J. T. (chaoskind)


Angehängte Dateien:

Lesenswert?

MoinMoin,

ich befasse mich weiterhin mit Transformationen, um in weiter Ferne mal 
3D-Objekte auf dem 2D-Bildschirm darstellen zu können.

Siehe dazu evtl auch hier mein Einstieg:
Beitrag "Warum kann man keine structs addieren?"

Um gewisse Punkte vom kartesischen ins polare Koordinatensystem 
übertragen zu können, schreibe ich mir grad Funktionen dafür. Der Weg 
von den Kartesischen zu den Polaren klappt auch schon. Aber auf dem 
Rückweg steckt irgendwie noch der Wurm drin. In der einen Richtung wird 
aus dem Vektor
(-1, -1, 0) ganz richtig der Radius Wurzel2, mit dem Polarwinkel 90° (es 
gibt halt keinen Z-Anteil, der Punkt liegt also in der XY-Ebene) und dem 
Azimutwinkel 45°. Auch logisch, der Punkt(1,1) bzw (-1,-1) liegt ja auf 
der Winkelhalbierenden.
Auf dem Rückweg werden aus eben diesen Polarkoordinaten nun aber
(-58.81.. ,0.556... ,-1.57...). Formel hierher:
http://wwwex.physik.uni-ulm.de/lehre/krm-2008-2009/node56.html

Wenn ich den Rückweg nach dieser Formel:
http://wwwex.physik.uni-ulm.de/lehre/krm-2008-2009/krm-2008-2009.pdf 
(Seite 43)
, die mir richtiger erscheint(vor allem, weil ich Z rein intuitiv 
genauso ermittelt hätte), gestalte kommt aber auch kein sinnvolles 
Ergebnis bei raus.(0.664..., 0.00032..., -6.18..*10^-8). Daher stammt 
auch der "Hinweg".

Die Transformation benötige ich vor allem, um auf den Winkel u und v aus 
dem Wikiartikel schließen zu können, um damit dann meine Vektoren auf 
der Bildebene festzulegen.
Wikiartikel:
https://de.wikipedia.org/wiki/Zentralprojektion
Unterpunkt Projektionsformeln

Hier die Umsetzung:
1
void Polar_zu_Kartesisch(const sPolar* Polar, sKartesisch* Kartesisch)
2
{
3
    Kartesisch->X = ( Polar->Radius * (sinf(Polar->Pol)) * (cosf(Polar->Azimut)) )
4
                  /*+ ( Polar->Pol * ( cosf(Polar->Pol) ) * ( cosf(Polar->Azimut) ) )
5
                  - ( Polar->Azimut * sinf( Polar->Azimut) )*/;
6
7
    Kartesisch->Y = ( Polar->Radius * (sinf(Polar->Pol)*(Pi/180)) * (sinf(Polar->Azimut)*(Pi/180)) )
8
                 /* + ( Polar->Pol*(Pi/180) * ( cosf(Polar->Pol*(Pi/180)) ) * ( sinf(Polar->Azimut*(Pi/180)) ) )
9
                  + ( Polar->Azimut*(Pi/180) * cosf( Polar->Azimut*(Pi/180)) )*/;
10
11
    Kartesisch->Z = ( Polar->Radius * cosf(Polar->Pol*(Pi/180)) );
12
                  //- ( Polar->Pol*(Pi/180) * sinf(Polar->Pol*(Pi/180)) );
13
}

Das auskommentierte wäre die erste Varianten, so wie es jetzt dasteht, 
ist es die zweite.

Im Anhang der gesamte Quellcode.

P.S.
Karl-Heinz, falls du vorbeischaust und dann auch noch Lust hast, 
könntest du evtl mal über die Dateien schauen, ob ich das mit den 
Pointern sinnvoll gelöst hab? Funktionieren tut es zumindest.

Mit vielem Dank im voraus und freundlichen Grüßen,
Chaos

von Karl H. (kbuchegg)


Lesenswert?

1
    Kartesisch->Y = ( Polar->Radius * (sinf(Polar->Pol)*(Pi/180)) * (sinf(Polar->Azimut)*(Pi/180)) )

da sind dir wohl ein paar Klammern verrutscht.

Des weiteren. Hör mit diesem Unsinn auf, in den Polarkoordinaten den 
Winkel in Grad zu speichern. Du kannst damit sowieso nichts vernünftiges 
anfangen. Wann immmer du etwas mit Polarkoodinaten rechnerisch machen 
willst, müsstest du die Grad wieder in Radianten umrechnen bzw. 
umgekehrt. Zum Rechnen brauchst du immer Radianten. D.h. wenn du in den 
Polarkoordinaten den Winkel in Radianten speicherts und dir nur dann die 
Grad ausrechnest wenn du die Zahl irgendwo ausgibst, dann ist es das 
vernünftigste. Ich weiss zwar nicht, wozu du Polarkoordinaten brauchst, 
in 30 Jahren CAD hab ich sie kein einziges mal gebraucht (wohl aber 
Vektorarithmetik in rauhen Mengen), man speichert intern immer in der 
Form, in der man leicht damit rechnen kann und nur für den (aus 
Programmsicht) seltenen Fall, dass man den Zahlenwert irgendwo 
hinschreiben muss, wandetl man dann in die für Menschen gebräuchliche 
Form. Habe ich hauffenweise mit Zeitpunkten und Zeitdauern zu tun, dann 
speichere ich grundsätzlich alles in linearer Form zb als Sekunden. Und 
nur zur Anzeige mach ich mir die Mühe auf Stunden, Minuten und Sekunden 
umzurechnen. Programmintern lass ich alles auf Sekunden, weil es sich 
damit viel einfacher rechnen lässt. Sinus, Cosinus, Tangens nehmen 
Radianten und die zueghötigen Arcus Funktionen liefern Radianten. Also 
lass ich auch alles auf Radianten.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:

> Die Transformation benötige ich vor allem, um auf den Winkel u und v aus
> dem Wikiartikel schließen zu können, um damit dann meine Vektoren auf
> der Bildebene festzulegen.
> Wikiartikel:
> https://de.wikipedia.org/wiki/Zentralprojektion
> Unterpunkt Projektionsformeln

Vergiss das. das macht man nicht so.

Es gibt viele Einführungen in grundlegende Computergraphik auf unterer 
Ebene.
Meine liebste war immer die hier, in der es um eine kleine Variation 
davon geht, mir der man aber wunderbar das Konzept des Zusammenspiels 
von Vektoren und Matrizen üben kann
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4057037

(Jim Blinn ist einer der ganz Grossen in der Computergraphik.)

von J. T. (chaoskind)


Lesenswert?

Jawollja, danke nun klappt es, bis auf kleine Rundungsfehler. Rechne nun 
auch mit dem Rad.

Nun muss ich nur noch ausklamüsern, wie ich die Vektoren verschieben 
muss, die dann meine BildXY ergeben. Aber da hab ich auch schon ne Idee, 
der Wikiartikel zur Zentralprojektion ist da garnicht schlecht, in dem 
einen Bildchen stecken eigentlich alle Infos drinne, die man braucht. 
Wenns fertig ist, werd ichs mal hier zeigen.

P.S.

Dein zweiter Beitrag war erst nachdem ich den hier verfasst hab, zu 
sehen. Den Link werd ich mir mal zu Gemüte führen, dankeschön =). Von 
Jim Blinn (sicher das der nicht Beam heißt? :D ) hab ich noch nie 
gehört.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:

> P.S.
> Karl-Heinz, falls du vorbeischaust und dann auch noch Lust hast,
> könntest du evtl mal über die Dateien schauen, ob ich das mit den
> Pointern sinnvoll gelöst hab? Funktionieren tut es zumindest.

Das passt schon grundsätzlich.
Aber du bist zusehr auf fixe Körper fixiert. Ein Kubus ist auch nur ein 
Körper, der aus Punkten besteht, die Pinkte sind zu Kanten 
zusammengefasst und die Kanten wiederrum zu Flächen (auch wenn du 
Flächen jetzt noch nicht brauchst). Lass uns mal einfach  nur bei 
Punkten und Kanten bleiben.

EIn allgemeiner Körper sieht zb so aus
(und du willst einen Vektor wirklich nicht sKartesisch nennen. Viel zu 
lang der Name, den wirst du noch 1000-e male schreiben müssen)
1
Punkte:
2
0, 0, 0
3
1, 0, 0
4
1, 1, 0
5
0, 1, 0
6
0, 0, 1
7
1, 0, 1
8
1, 1, 0
9
0, 1, 0
10
11
Kanten
12
0, 1
13
1, 2
14
2, 3
15
3, 0
16
4, 5
17
5, 6
18
6, 7
19
7, 4
20
0, 4
21
1, 5
22
2, 6
23
3, 7

Da gibt es einen Haufen Punkte, durchnummeriert von 0 bis eben so viele 
Punkte, wie man benötigt. Und dann gibt es Kanten, die nichts anderes 
sind als die Nummern der Punkte. Jede Kante besteht aus 2 Punkten, deren 
Punktnumern jeweils ausgeführt sind.
Das obige beschreibt einen Würfel mit Kantenlänge 1. Aber das ist nicht 
der springende Punkt. Der springende Punkt ist, dass ich eine 
Datenstruktur dafür machen kann
1
typedef struct sVector__
2
{
3
  float X;
4
  float Y;
5
  float Z;
6
} sVector;
7
8
typedef struct sEdge__
9
{
10
  unsigned char Start;
11
  unsigned char End;
12
} sEdge;
13
14
typedef struct sSolid__
15
{
16
  unsigned char nrPoints;
17
  sVector*      Points;
18
  unsigned char nrEdges;
19
  sEdge*        Edges;
20
} sSolid;
21
22
//////
23
sVector cubePoints[] =
24
{
25
 { 0, 0, 0 },
26
 { 1, 0, 0 },
27
 { 1, 1, 0 },
28
 { 0, 1, 0 },
29
 { 0, 0, 1 },
30
 { 1, 0, 1 },
31
 { 1, 1, 0 },
32
 { 0, 1, 0 }
33
};
34
35
sEdge cubeEdges[] =
36
{
37
 { 0, 1 },
38
 { 1, 2 },
39
 { 2, 3 },
40
 { 3, 0 },
41
 { 4, 5 },
42
 { 5, 6 },
43
 { 6, 7 },
44
 { 7, 4 },
45
 { 0, 4 },
46
 { 1, 5 },
47
 { 2, 6 },
48
 { 3, 7 }
49
};
50
51
sSolid cube =
52
{
53
  8, cubePoints, 12, cubeEdges
54
};

damit hast du alles beisammen um
* jeden Körper durch Kanten beschreiben zu können
* und damit eine Funktion schreiben zu können, die irgend einen 
beliebigen so aufgebauten Körper auf das Display bringen kann.

Das muss dir doch selbst in der Seele weh getan haben, da immer wieder 
die gleichen Transformationen auf deinen Kubus anzuwenden, anstatt dir 
EINMALIG eine Funktion zu schreiben, die eine Kante (bestehend aus Start 
und Endpunkt) aufzurufen. Du musst anfangen dich zu organisieren, sonst 
gehst du unter! Die Datenmenge erschlägt dich sonst. Also brauchst du 
Datenstrukturen und Funktionen die auf Datenstrukturen arbeiten und 
aufeinander aufbauen!

Zum Beispiel
1
void DrawStraight( sVector* Start, sVector* End )
2
{
3
  sVector StartTrans = Transform( Start );   // in Screenspace transformieren
4
  sVector EndTrans = Transform( End );
5
6
  line(bmp, StartTrans.X, StartTrans.Y, EndTrans.X, EndTrans.Y, makecol(R, G, B))
7
}

damit hast du eine Basisfunktion um eine 'Kante' zu malen. Eigentlich um 
irgendeine 3D Linie, die von einem Startpunkt zu einem Endpunkt fürt. 
Eine Kante in deinem Solid ist genau so etwas. Du musst die Funktion nur 
benutzen
1
void DrawSolid( sSolid* pSolid )
2
{
3
  unsigned char i;
4
5
  for( i = 0; i < pSolid->nrEdges; i++ )
6
  {
7
    unsigned char StartIndex = pSolid->Edges[i].Start;
8
    unsigned char EndIndex = pSolid->Edges[i].End;
9
10
    DrawStraight( &pSolid->Points[StartIdex], &pSolid->Points[EndIndex] );
11
  }
12
}

und damit steht der Mechanismus soweit (die Transformation in Screen 
Space habe ich aussen vor gelassen), dass ich zum Beispiel den Würfel 
von weiter oben da reinstecken kann:
1
  DrawSolid( &cube );

aber eben nicht nur einen Würfel. Alles was ich brauch ist eine 
entsprechende Beschreibeung in Form eines sSolid (der aus sEdges und 
sPoints besteht) und ich kann mit genau demselben Mechanismus auch die 
anzeigen!
Egal ob das dann ein angenäherter Zylinder ist, oder ein Tetrahedron 
oder ein Teacup oder ein T-Rex oder eine Flugzeugträger.

ComputerGraphik ist zuallererst einmal Datenstrukturen, Datenstrukturen, 
Datenstrukturen. Erwähnte ich schon, dass Datenstrukturen in CG wichtig 
sind? Dann will ich es lieber noch einmal anführen: Datenstrukturen und 
Organisation sind in CG eminent wichtig.

Besorg dir Literatur! Du wirst sie brauchen. Meine ist schon etwas in 
die Jahre gekommen, aber in meinem Bücherregal stehen mindestens 5 bis 6 
Schinken, die sich mit grundlegender Computer Graphik beschäftigen. Und 
da hab ich die Graphics Gems Serie noch gar nicht dazu gerechnet 
(nochmal 6 Bände, die eine Sammlung von Tips und Tricks darstellen).

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl H. schrieb:

Und

>
1
> void DrawStraight( sVector* Start, sVector* End )
2
> {
3
>   sVector StartTrans = Transform( Start );   // in Screenspace 
4
> transformieren
5
>   sVector EndTrans = Transform( End );
6
> 
7
>   line(bmp, StartTrans.X, StartTrans.Y, EndTrans.X, EndTrans.Y, 
8
> makecol(R, G, B))
9
> }
10
>

wenn du Farbe haben willst, dann speichert du die Farbe natürlich 
ebenfalls in dieser Datenstruktur. Zb. indem du bei jeder Kante eine 
Farbe speichern kannst (offenbar gibt es da ja eine struct, die eine 
Farbe beschreibt), oder indem du zb den ganzen Solid in einer Farbe 
einfärbst und daher beim Solid dir die Farbinformation merkst. Und dann 
natürlich die Farbe in die Funktionen mit rein schleifst.

Sagte ich schon, dass Computergraphik mit Datenstrukturen und 
Organisation zu tun hat? Und das in rauhen Mengen?

von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:
> Jawollja, danke nun klappt es, bis auf kleine Rundungsfehler.

solange du da mit float rumklamüserst, ist das kein Wunder. float nimmt 
man nur, wenn Speicher sparen das oberste Gebot ist. Aber zum Rechnen 
willst du float hassen wie die Pest.

> Dein zweiter Beitrag war erst nachdem ich den hier verfasst hab, zu
> sehen. Den Link werd ich mir mal zu Gemüte führen, dankeschön =). Von
> Jim Blinn (sicher das der nicht Beam heißt? :D ) hab ich noch nie
> gehört.

Einer der 'Graphics Jims'. Aus irgendeinem Grund, der in der Geschichte 
verloren gegangen ist, haben viele der Pioniere Jim geheisse. Jim Blinn 
war der Mann, der die Voyager Flyby Animationen gemacht hat. Die 
wiederrum waren in den 80-ern der Grund, warum ich zur Computer Grafik 
gekommen bin. Ich war Ende der 90-er mal auf einer Siggraph in einem 
seiner Vorträge und konnte mich kurz mit ihm unterhalten. Feiner Kerl, 
wie alle aus dem Utah-Clan, die bei Ivan Sutherland gelernt haben und 
die Grundlagen geschaffen haben.

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

Karl H. schrieb:

> Das passt schon grundsätzlich.
> Aber du bist zusehr auf fixe Körper fixiert. Ein Kubus ist auch nur ein
> Körper, der aus Punkten besteht, die Pinkte sind zu Kanten
> zusammengefasst und die Kanten wiederrum zu Flächen (auch wenn du
> Flächen jetzt noch nicht brauchst). Lass uns mal einfach  nur bei
> Punkten und Kanten bleiben.

Ja bin ich mir bewusst. Die Verallgemeinerung für die Translation, 
Skalierung und Rotation hab ich ja so weit hinbekommen, das ich nur nen 
Punkt reinschmeißen muss. Für das Zeichnen hat mir da noch der Ansatz 
gefehlt, dein Strukturaufbau ist einfach genial! Danke dafür, genau so 
einen Gedankenblitz hats gebraucht.

> (und du willst einen Vektor wirklich nicht sKartesisch nennen. Viel zu
> lang der Name, den wirst du noch 1000-e male schreiben müssen)

Das passt schon so, ich tippe nur sKa und Enter. Das 
Autovervollständigen von CodeBlocks ist da sehr nützlich, finde ich ;-). 
Wobei, wenn man irgendwelche Sachen hin und her copy und pastet, dann 
kanns schon mal nervig sein, wenn da ständig das Autoverstopfendings 
aufploppt.

> [code]
> Punkte:
> 0, 0, 0
> 1, 0, 0
....

Und genau diese Verbindung hab ich in den "Zeichen" funktionen ja 
gemacht. Mir hats vor allem davor gegraust, das ich dann ja für jeden 
Körper eine eigene hätte machen müssen, hätte ich das nicht 
verallgemeinert bekommen. Also nochmals vielen Dank für den Anstoß.

> Da gibt es einen Haufen Punkte, durchnummeriert von 0 bis eben so viele
> Punkte, wie man benötigt. Und dann gibt es Kanten, die nichts anderes
> sind als die Nummern der Punkte. Jede Kante besteht aus 2 Punkten, deren
...

Der Gedanke, das ich das über Arrays verallgemeinern könnte, kam mir 
auch schon, und das ich dann jeden Punkt mit einer Nummer anspringen 
könnte, ala (for i=0; i<bla; i++){Vektor.Punkt[i] machwasmit()}; Aber 
mir fehlte wie gesagt noch der Ansatz

Ich werd mal versuchen, deine zahlreichen Vorschläge umzusetzen.

Hast du evtl noch ne Erklärung, warum das bei Wiki so ungünstig 
umgesetzt ist? Mir kam, vor allem die Transformation der Raum auf die 
Bildkoordinaten eigentlich sehr intuitiv vor...

von J. T. (chaoskind)


Lesenswert?

Karl H. schrieb:
> solange du da mit float rumklamüserst, ist das kein Wunder. float nimmt
> man nur, wenn Speicher sparen das oberste Gebot ist. Aber zum Rechnen
> willst du float hassen wie die Pest.

Will heißen, Festkomma-Arithmetik? Glaubs mir oder nicht, aber neben den 
Arrays kam mir auch shcon der Gedanke, das auf int32 umzustellen. 
Abgehalten hat mich dann aber irgendwann der Gedanke, das man mit Floats 
so schon auf +-1 Skalieren kann. Aber daran hinder mich bei Festkomma ja 
eigentlich auch garnichts dran.

Dann werd ich auch das mal umsetzen.

von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:

> Hast du evtl noch ne Erklärung, warum das bei Wiki so ungünstig
> umgesetzt ist?

Das scheint mir ein Artikel zu sein, der sich an Architekten und Maler 
wendet. Die zeichnen ihre Bilder so.

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

Karl H. schrieb:
> wenn du Farbe haben willst, dann speichert du die Farbe natürlich
> ebenfalls in dieser Datenstruktur. Zb. indem du bei jeder Kante eine
> Farbe speichern kannst (offenbar gibt es da ja eine struct, die eine
> Farbe beschreibt), oder indem du zb den ganzen Solid in einer Farbe
> einfärbst und daher beim Solid dir die Farbinformation merkst. Und dann
> natürlich die Farbe in die Funktionen mit rein schleifst.

Das steht auch schon auf der Änderungsliste der Änderungen auf die ich 
von selbst gekommen bin *stolzguck :D

Karl H. schrieb:
> Sagte ich schon, dass Computergraphik mit Datenstrukturen und
> Organisation zu tun hat? Und das in rauhen Mengen?

Womit hatte Computergraphik gleich zu tun?? :D

Wirklich noch mal ganz herzlichen Dank für deine Mühen. Ich glaube, du 
bist der Mensch, der den größten Einfluss auf meine "Entwicklung" als 
"Programmierer" hatte. Bei fast allen Fragen die hier von mir kamen, kam 
von dir ne Lösung/ ein Ansatz. Sollte ich mal im Lotto gewinnen, dann 
haste n Kasten Bier und ne Kiste Halbleiter gut bei mir =) *DaumenHoch!

von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:
> Karl H. schrieb:
>> solange du da mit float rumklamüserst, ist das kein Wunder. float nimmt
>> man nur, wenn Speicher sparen das oberste Gebot ist. Aber zum Rechnen
>> willst du float hassen wie die Pest.
>
> Will heißen, Festkomma-Arithmetik?

Nein. Will heissen double.

Working with floating point numbers
is like moving piles of sand.
Every time you do it,
you loose a little sand
and pick up a little dirt.

(und je weniger Bits dein Floating Point Datentyp ist, desto schlimmer 
ist es. Werde ich nie vergessen, wie mir in meinem ersten Job die 
Simulation eines Roboters nach ein paar Hundert Bahnpunkten um die Ohren 
geflogen ist. Natürlich nicht bei Tests, sondern als sich der Oberboss 
ansehen wollte, was wir so für sein Geld gemacht haben. War ein bisschen 
blöd, weil wir eigentlich eine Graphics Workstation um knapp 300000 Mark 
beantragen wollten)

: Bearbeitet durch User
von Toni Tester (Gast)


Lesenswert?

J. T. schrieb:
> Will heißen, Festkomma-Arithmetik?

Kommt auf die Anwendung an - am PC (im Sinne von Workstation) sehe ich 
das nicht als sinnvoll an. Stattdessen würde ich mindestens doppelte 
Genauigkeit (sprich double), wenn nicht sogar long double, verwenden.

Würde auch vorschlagen, den genauen Datentyp aus deiner "Bibliothek" 
herauszutypedefen bzw. die "Bibliothek" möglichst bitbreitenunabhängig 
zu schreiben.

von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:

>> (und du willst einen Vektor wirklich nicht sKartesisch nennen. Viel zu
>> lang der Name, den wirst du noch 1000-e male schreiben müssen)
>
> Das passt schon so, ich tippe nur sKa und Enter. Das
> Autovervollständigen von CodeBlocks ist da sehr nützlich, finde ich ;-).

Sei dir auch bewusst, dass der Begriff Vektor auch in anderen Begriffen 
vrokommt, wie zb "Normalvektor", "Vektor senkrecht zu einem anderen", 
"Parallelvektor", "Rotationsvektor", "Vektorarithmetik" und noch mehr. 
Vektor ist ein stehender Begriff in CG. Jeder (auch Japaner) weiss, was 
darunter zu verstehen ist. Es gibt 2D-Vektoren, 3D-Vektoren, homogene 
Vektoren, 4D(homogene) Vektoren kommen selten vor - wenn man Animationen 
zum Thema relativistische Physik macht, braucht man sie allerdings.
Wenn du dauernd umdenken willst, ok. Mach es.

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Angehängte Dateien:

Lesenswert?

Es kann auch hilfreich sein, sich bei der Objektbeschreibung ein 
vorhandenes Dateiformat der einfacheren Sorte mal anzuschauen damit man 
Import und Export vereinfachen kann.
OBJ z.B. ist einfach zu lesen, da es rein ASCII kodiert ist, und 
trotzdem erlaubt es je, den Inhalt zu skalieren - von simplen Vertizes 
und Dreiecken bis zu UV Koordinaten für Texturierung.
Anbei mal ein (fast) Einheitswürfel.

von Karl H. (kbuchegg)


Lesenswert?

Matthias S. schrieb:
> Es kann auch hilfreich sein, sich bei der Objektbeschreibung ein
> vorhandenes Dateiformat der einfacheren Sorte mal anzuschauen damit man
> Import und Export vereinfachen kann.
> OBJ z.B. ist einfach zu lesen,

genau.
Das Wavefront Format war in meinen ersten Jahren mein liebstes. Einfach 
zu parsen, einfach zu generieren.
Irgendwo müsste ich noch eine Sammlung von allen möglichen Objekten 
haben.

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

Karl H. schrieb:
> Working with floating point numbers
> is like moving piles of sand.
> Every time you do it,
> you loose a little sand
> and pick up a little dirt.

:D Der ist gut. Hab ich auch bemerkt. Umso länger ich meinen Kubus 
drehen ließ, umso kleiner wurde er um die Drehachse.

Karl H. schrieb:
> Sei dir auch bewusst, dass der Begriff Vektor auch in anderen Begriffen
> vrokommt, wie zb "Normalvektor", "Vektor senkrecht zu einem anderen",
> "Parallelvektor", "Rotationsvektor", "Vektorarithmetik" und noch mehr.
> Vektor ist ein stehender Begriff in CG. Jeder (auch Japaner) weiss, was
> darunter zu verstehen ist.
> Wenn du dauernd umdenken willst, ok. Mach es.

Damit hast du allerdings recht. Mir war anfänglich wichtig, den 
Unterschied zwischen einem Punkt im Raum und einem Vektor zu "sehen". 
Aber eigentlich gibts den ja nicht. Aber irgendwie geistert mir denoch 
das Gefühl im Kopf rum, dass da ein Unterschied sein muss zwischen einem 
Punkt im Raum und einem Pfeil der vom Ursprung zum Punkt zeigt.

Toni Tester schrieb:
> Kommt auf die Anwendung an - am PC (im Sinne von Workstation) sehe ich
> das nicht als sinnvoll an. Stattdessen würde ich mindestens doppelte
> Genauigkeit (sprich double), wenn nicht sogar long double, verwenden.

Werd ich mal versuchen. Beim Versuch mit int hat er sich grad darüber 
beschwert, das er durch 0 teilen muss.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

J. T. schrieb:

> Zentralprojektion

Dafür benötigst du keine Polarkoordinaten; kartesische Koordinaten 
reichen voll aus und sind zudem effizienter:

1) Wähle eine Bildebene B, entspricht deinem Monitor.  Die Bildebene 
wird aufgespannt durch 2 orthonormale Vektoren X und Y.  1 Längeneinheit 
entspricht der Breite eines Pixel.

2) Wähle einen Augpunkt A, entspricht einem beubachtenden Auge

3) Für jeden Punkt P, der dargestellt werden soll, schneide die Strecke 
AP mit B.  Das Ergebnis P' liegt dann in B und kann durch die B 
aufspannenden Vektoren X und Y dargestellt werden.  Sinnigerweise liegen 
A und P auf unterschiedlichen Seiten von B.

4)  Voilà! Du hast die Koordinaten von P aufm Bildschirm.

Bildebene:
Strahl vom Auge zu einem Punkt P:
Weil P' in B liegt, gilt:
Multipliziere (1) mit Z = X×Y und beachte Z·X = Z·Y = 0:

Multipliziere (1) mit X und beachte X·Y = 0:
Analog für beta.

von Karl H. (kbuchegg)


Lesenswert?

J. T. schrieb:
> Karl H. schrieb:
>> Working with floating point numbers
>> is like moving piles of sand.
>> Every time you do it,
>> you loose a little sand
>> and pick up a little dirt.
>
> :D Der ist gut.

Leider nicht von mir.

> Hab ich auch bemerkt. Umso länger ich meinen Kubus
> drehen ließ, umso kleiner wurde er um die Drehachse.

Yep. Und irgendwann macht es 'krawumm' und der Würfel fällt auseinander. 
Die kleinen Fehler akkumulieren sich. Und hinterhältigerweise tun sie 
das exponentiell. Am Anfang sind sie klein. Aber wenn sie zu wachsen 
anfangen, dann geht es sehr schnell. Hat lange gedauert, bis Johann 
(mein betreuender Mathematiker) und ich das Problem stabil in den Griff 
gekriegt haben (und wir haben gelernt, Skalieroperationen zu hassen, 
weil sie uns daran gehindert haben, die Matrizen wieder zu 
orthonormalisieren)


> Unterschied zwischen einem Punkt im Raum und einem Vektor zu "sehen".
> Aber eigentlich gibts den ja nicht.

Yep.
In homogenen Koordinaten lassen sich sogar Punkte und Richtungen in 
einem einheitlichen Vektor ausdrücken. Bis dahin unterscheidest du 
zwischen einem Positionsvektor und einem Richtungsvektor. (wobei die 
Unterscheidung hauptsächlich logischer Natur sind auch wenn sich 
Richtungsvektoren anders transformieren als Positionsvektoren)

> Aber irgendwie geistern mir denoch
> das Gefühl im Kopf rum, dass da ein Unterschied sein muss zwischen einem
> Punkt im Raum und einem Pfeil der vom Ursprung zum Punkt zeigt.

Das gibt sich.
Irgendwann kommt es dir natürlich vor. Dann ist ein Punkt im Raum auch 
nichts anderes als ein Vektor im 0-Punkt, der um einen bestimmten Betrag 
in eine bestimmte Richtung verschoben wurde. Man könnte also sagen: 
Eigentlich gibt es nur einen einzigen Punkt. Aber den kann ich überall 
hin verschieben - ich muss mir also nur den Pfeil merken, der den Punkt 
im Koordinatenursprung an die bewusste Position verschiebt :-)

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.