Verbesserung und Tipps zu Vektor Klasse
-
- Die Konstruktoren, die nur 1 Parameter erwarten (außer Kopierkonstruktor), würde ich explicit machen. Das hilft Fehlern vorzubeugen!
- Angle und Dot sollten konstante Referenzen als Parameter erwarten!
-
this->that schrieb:
In der 3D-Grafik wird die benötigte Länge immer die Euklidsche Distanz sein. Für den Fall das man irgend eine freakigere Länge braucht (was nie der Fall sein wird), kann man sich dafür ja ne Extra Funktion schreiben.
Aber wieso sollte man v.length() schreiben können, aber nicht v.norm1()? Wieso nicht nur length(v) dann passt auch norm1(v) intuitiv. (nebenbei frage ich mich, was die Definition soll. Ich bezweifle doch gar nicht, dass es eine Länge gibt, sondern sag nur, dass diese frei wählbar ist, solange sie bestimmte Eigenschaften erfüllt)
@Volkard den Winkel kriegt man auch in anderen Räumen hin, wenn zwischen Länge eines Vektors und Skalarprodukt die Beziehung sqrt(<v,v>) besteht.
-
otze schrieb:
Aber wieso [...]
Weil man es einfach nicht tut.
Kontext beachten:#include <D3dx9math.h>
-
otze schrieb:
(nebenbei frage ich mich, was die Definition soll. Ich bezweifle doch gar nicht, dass es eine Länge gibt, sondern sag nur, dass diese frei wählbar ist, solange sie bestimmte Eigenschaften erfüllt)
In der Definition ist der Begriff Length direkt verlinkt mit der euklidschen Distanz.
hellihjb schrieb:
Weil man es einfach nicht tut.
Eben. Jeder weiß, dass das euklidsche Vektoren sind und niemand wird erwarten, dass ein length ein City-Block Metric (was auch immer das sein soll) liefert.
-
this->that schrieb:
Eben. Jeder weiß, dass das euklidsche Vektoren sind und niemand wird erwarten, dass ein length ein City-Block Metric (was auch immer das sein soll) liefert.
Fall Interesse besteht, was das ist: Ich kann mir nichst anderes denken, als daß http://en.wikipedia.org/wiki/Taxicab_geometry gemeint ist.
-
@volkard: Gibt es eigentlich einen Grund, wieso du im assert() 0<=index prüfst, obwohl index unsigned ist?
-
this->that schrieb:
In der Definition ist der Begriff Length direkt verlinkt mit der euklidschen Distanz.
Nein. In der Definition steht nur Länge. Dass aber die Länge innerhalb eines Vektorraums frei wählbar ist, hatte ich bereits gesagt. Um mal einen Prof zu zitieren: "Ein Vektor ist ein Ding, das bestimmte Operationen hat und für das eine Länge definiert ist". Danach hat er mehrere Funktionen an die Tafel geschrieben, ein Integral als Längendefinition gebracht und gesagt: das sind Vektoren. Kurz danach hat er übrigens den Winkel zwischen verschobenen Sinus-Funktionen anhand dieser Definition bestimmt.
hellihjb schrieb:
Weil man es einfach nicht tut.
Eben. Jeder weiß, dass das euklidsche Vektoren sind
Auch wenn DirectX den Projektionsraum verwendet und durchaus alle Matrizen im Projektionsraum angegeben werden müssen? Auch dieser Raum hat eine eigene Längendefinition. Und je nachdem was man machen will, ist das auch eine wichtige Sache.
@volkard Jo. Das Ding hat verschiedene Namen. Manhatten Distanz ist auch gebräuchlich.
-
otze schrieb:
this->that schrieb:
In der Definition ist der Begriff Length direkt verlinkt mit der euklidschen Distanz.
Nein. In der Definition steht nur Länge. Dass aber die Länge innerhalb eines Vektorraums frei wählbar ist, hatte ich bereits gesagt. Um mal einen Prof zu zitieren: "Ein Vektor ist ein Ding, das bestimmte Operationen hat und für das eine Länge definiert ist". Danach hat er mehrere Funktionen an die Tafel geschrieben, ein Integral als Längendefinition gebracht und gesagt: das sind Vektoren. Kurz danach hat er übrigens den Winkel zwischen verschobenen Sinus-Funktionen anhand dieser Definition bestimmt.
Und inwiefern bringt uns (vor allem den OP) das hier irgendwie weiter? Ich kann einen Vektor auch maximal abstrakt als Element eines Vektorraums über einem Körper K betrachten, für den eine Multiplikation mit bestimmten Eigenschaften definiert ist. Ich kann ihn auch als einen Tensor 1. Stufe betrachten. Was bringt mir das für die PRAKTISCHE Umsetzung? Absolut nichts. In einer 3D Anwendung habe ich euklidsche Vektoren und jeder weiß, was die Länge eines Vektors bedeutet. Bei etwas so trivialem wie der Länge eines Vektors Begriffe wie "City-Block Metric" aufwerfen riecht stark nach Theoretiker, der alles abdecken will aber letztlich zu nichts kommt;)
-
Um mal einen Prof zu zitieren: "Ein Vektor ist ein Ding, das bestimmte Operationen hat und für das eine Länge definiert ist". Danach hat er mehrere Funktionen an die Tafel geschrieben, ein Integral als Längendefinition gebracht und gesagt: das sind Vektoren. Kurz danach hat er übrigens den Winkel zwischen verschobenen Sinus-Funktionen anhand dieser Definition bestimmt.
Du hast ja prinzipiell recht, das hat aber einfach etwas mit der Handhabung in der Praxis zu tun.
Mein Code sieht immer etwas "huffmanartig" aus, dh was man am haeufigsten benoetigt hat die kuerzeste Bezeichnung.
Durch die Existenz einer weiteren Laengenfunktion muesste man konsequenter Weise anstatt length() immer euclidianLength() schreiben - halte ich aber fuer Bloedsinn.
-
was ich als punkt sehe ist die ueberladung vom operator*, an sich hat die klasse auch alles was man braucht um mit farben zu rechnen. bis auf ein paar operator unstimmigkeiten, ich hab deswegen bei mir das meiste in einer basisklasse abgespalten und ein paar dinge dann spezialisiert.
das ist durchaus nuetzlich es zu mischen, z.b. kann ich auf einfache weise, zum debuggen, mir die normalen als farbe abspeichern, indem ich *vec0.5,0.5,0.5,1.f)+vec(0.5f,0.5f,0.5f,0.f); rechne und dann auf unsigned int caste und als tga ablege.
an sich denke ich auch, dass bei richtungs/positions vectoren fuer spiele es sehr eindeutig ist was gemeint ist.
ich hab jedoch auch implementierungen gesehen, bei denen man das inner produkt mit operator^ (weil es eben einen winkel darstellt, mit ein wenig abstraktion) realisierte und operator* wirklich mul war.
fand ich nach kurzer eingewoehnung aber recht angenehm.
-
@this->that Was es dem OP bringt? Nichts. Es sollte dir nur zeigen, dass mit Länge nicht unbedingt die Euklidische Länge gemeint ist. Und das musste ich zeigen, um meine Ansicht zu Untermauern, dass length(v) besser ist als v.length(). Ich kann das auch nochmal genauer Ausführen: Wir haben unterschiedliche Längenmaße. Je nachdem wofür man den Vektor verwendet. Meistens hat man wirklich den Euklidischen Raum, da stimme ich dir zu. Aber schon zum Beispiel bei einem Spielfeld wie bei rundenbasierten Strategiespielen gilt das nicht mehr so ohne weiteres. Da ist für die KI nicht die euklidische Distanz relevant, weil sie nicht bestimmt, wie weit sich die KI bewegen kann, sondern zum Beispiel die City-Block-Metrik(und bei hexagonalen Spielfeldern wieder andere Normen...).
Es gibt also durchaus Fälle, in denen verschiedene Längenmaße zur selben Zeit auftreten. Warum also sollte ich dann nicht beide Längenmaße auf die selbe Weise verwenden können? Selbe Semantik = Selbe Nutzung. Alles andere ist nicht intuitiv. Um deinen Vorschlag aufzugreifen, beides zu verwenden: Warum? Verdoppelung von Funktionalität wie bei string::size() und string::length() wurde auch schon als Müll erkannt.
Ich bin ja auch nicht der Einzige, der das so sieht. boost::uBLAS macht das genau so. Da gibts norm1(v), norm2(v) und normInf(v). Hat da auch den unglaublichen Vorteil, dass man bei beliebig dimensionalen Vektoren nicht mit v.size() und v.length() durcheinander kommen kann, eben weil es nur size() gibt. Und wer seine eigene Norm braucht, kann die einfach definieren, und es fühlt sich exakt so an, wie eine normale uBLAS Norm.
@hellihjb
Das Problem hast du aber immer, wenn du unterschiedliche Normen im Zusammenspiel hast. Nenne die Euklidische Distanz length(v), und sag, dass das die Euklidische Distanz ist. Für die Leute, die nur sie verwenden, fühlt sich das nicht weiter komisch an. Und die Leute, die mehr brauchen, kennen den Unterschied.
-
this->that schrieb:
@Melan: Jetzt find ichs auch ne schöne Vektor Klasse. Durch das Auslagern der "Algorithmen" schön schlank und übersichtlich.
Die Funktion Length() könntest du im Vektor lassen, denn die Länge ist eher eine Eigenschaft des Vektors, als eine Operation. Zusätzlich könntest du dann noch eine freie Funktion anbieten, die die Methode aufruft. Aus meiner Vektor Klasse:
template <class T> inline float Vec3Length(const Vector3<T>& v) { return v.getLength(); }
Dein operator[] ist richtig. Ich würde aber noch ein assert(index < 3) einbauen.
Und die Parameter deiner freien Funktionen würde ich nicht by-value sondern als konstante Referenzen übergeben.danke this->that. Das ist die fertige Klasse:
http://codepad.org/saDvL1lP
Aber warum hast du eine Templateklasse daraus gemacht?
Benutzt du statt float manchmal double?
-
Melan schrieb:
Aber warum hast du eine Templateklasse daraus gemacht?
Benutzt du statt float manchmal double?Es kann doch sein das er beispielsweise vertex-indices ablagern möchte. Ich persönlich mache es ebenfalls mit einem Template, ist wirklich besser...
-
this->that schrieb:
@volkard: Gibt es eigentlich einen Grund, wieso du im assert() 0<=index prüfst, obwohl index unsigned ist?
Nein, vertippt und dann war's mir nicht wichtig genug, es rauszueditieren. War eine Fehleinschätzung.
-
otze schrieb:
Um mal einen Prof zu zitieren: "Ein Vektor ist ein Ding, das bestimmte Operationen hat und für das eine Länge definiert ist".
"Ein Vektor ist ein Element eines Vektorraumes." Und für den gibt es schon eine supi formale Definition.
-
Kóyaánasqatsi schrieb:
Melan schrieb:
Aber warum hast du eine Templateklasse daraus gemacht?
Benutzt du statt float manchmal double?Es kann doch sein das er beispielsweise vertex-indices ablagern möchte.
Ich persönlich mache es ebenfalls mit einem Template, ist wirklich besser...Mal abgesehen von der Existenz dreier Zahlen scheinen mir ein 3D-Vektor und ein Indexed-Triangle aber nicht wirklich viel Funktionalitaet gemeinsam zu haben...
-
ich glaube es gab irgend ein "spiele mit d3d" buch dass vector templates gemacht hat und seitdem kursiert sowas rum
aber an sich seh ich darin auch nicht viel nutzwert bei spielen. float duerfte wohl fast immer der typ sein den man verwendet.
-
Ich war zu Faul um alle Beiträge durchzulesen, also ignoriert es falls es bereits gesagt wurde, aber: Du kannst noch <, >, <=, >= Operatoren überladen.
-
Kóyaánasqatsi schrieb:
Ich war zu Faul um alle Beiträge durchzulesen, also ignoriert es falls es bereits gesagt wurde, aber: Du kannst noch <, >, <=, >= Operatoren überladen.
Und wann ist ein Vektor größer als ein anderer?
Zum beispiel (1 2) vs (2 1) ?
-
Hm, stimmt auch. Aber vielleicht wenn beide Koordinaten größer sind. Also: vec1(2, 3) < vec2(5, 5).