Vektoren, Punkte in 3D und 4D



  • Ich will ein paar eigene Klassen für Vektoren, mit den üblichen Berechnungen wie normalisieren, länge, Winkel, addieren, subtrahieren etc. schreiben. Nun habe gibt es ja bei den Homogenen-Koordinaten ja auch die vierte Komponente w, wegen der Homogenen-Koordinaten die die Translationen durch Matrizenmultiplikation ermöglicht. Dazu kommen bei mir ein paar Fragen auf.

    Ist es da ratsam eine 4D-Vektor-Klasse und zusätzlich eine 4D-Punkt-Klasse zu erstellen? Beim Vektor wäre w=0 und beim Punkt w=1, da hier ja auch verschoben werden soll. Beim Vektor zählt ja nur die Richtung und die Länge, eine Translation würde ja die Länge und auch die Richtung verändern können, weswegen w hier auf 0 gesetzt wird. Ist das soweit richtig von mir verstanden?

    Mir ist schon klar, dass man die Koordinaten eines Vektors entweder als Punkt sehen kann, oder in Bezug auf einen Ort als Vektor halt. Daher meine Frage ob man nicht lieber nur eine 4D-Vektor-Klasse macht und dann w entweder auf 0 oder 1 setzt je nachdem ob die Koordinaten einen Vektor oder einen Punkt beschreiben, oder ob man da gleich zwei getrennte Klassen macht, eine für den Vektor und eine für den Punkt. Oder sollte man gleich bei 3D-Vektoren bleiben und w nur mit übergeben wenn man mit einer 4x4 Matrix multipliziert?

    Wie ist es eigentlich bei den Berechnungen mit 4D-Vektoren, also kreuz, dot, länge, addition, multiplikation, lässt man da einfach die w-Komponente außen vor und schleift sie sozusagen mit durch?

    Das sind bestimmt total doofe Fragen, aber ich mache das erst seit gut einer Woche und habe auch kein Abi oder so damals gemacht. Ist halt nur ein Hobby von mir.



  • Wenn man irgendwelche Groessen im 3D-Raum hat, wuerde ich die auch als 3D-Vektor behandeln.
    Was willst Du denn als w setzen wenn Du zwei 3D-Vektoren mit w=1 addierst?

    Es kann aus Performance-Sicht vorteilhaft sein, 3D-Vektoren intern als 4D-Vektor darzustellen weil man das dann gut auf SSE abbilden kann.
    Dann wuerde ich w aber immer auf 0 lassen und generell nie davon ausgehen, dass da irgendwas sinnvolles drinsteht.

    Ich mache das aber bewusst nicht so, weil der 3D-Vektor halt ein Container fuer 3 floats sein soll und ein Array dieses Typs soll dann nicht immer ein unnuetzes float dazwischen haengen haben...
    Aus dem gleichen Grund wuerde ich auch auf virtuelle Funktionen verzichten.

    Ich finde es bequem, wenn eine 4x4-Matrix sowohl 3D- als auch 4D-Vektoren multiplizieren kann - das kann man aber auch anders sehen.



  • Besten Dank, ich habe jetzt erst einmal eine Vektor-Klasse mit vier Tupeln geschrieben, die dann zwischen w=0 und w=1 umswitchen kann bei Bedarf. Später will ich dann mich auch noch an eine SIMD Version versuchen, aber das kommt wirklich erst viel später, jetzt soll das einfach nur funktionieren und vor allem von mir selbst geschrieben worden sein.

    Wie ist es eigentlich wenn ich jetzt eine C++-Vector-Container für die ganzen Vektoren meiner Modelle verwende, kann ich die einfach so an einen OpenGL VBO übergeben oder muss das extra vorher nochmal in ein CArray konvertiert werden?

    Wie sieht es zudem mit dem Speicherplatz auch, da ja mein Vektor eine Klasse mit so einigen Methoden ist, intern werden doch nur die Member(vier floats) bei jeder Instanz neu angelegt und nicht die Methoden mit, da sie ja immer gleich bleiben, oder?



  • Wie sieht es zudem mit dem Speicherplatz auch, da ja mein Vektor eine Klasse mit so einigen Methoden ist, intern werden doch nur die Member(vier floats) bei jeder Instanz neu angelegt und nicht die Methoden mit, da sie ja immer gleich bleiben, oder?

    Die Methoden einer Klasse sind nur einmal im Codesegment deines Programms vorhanden.
    Damit die Methoden wissen, ob sie nun mit Objekt1 oder Objekt2 arbeiten, wird ihnen ein Zeiger mitübergeben, der this Zeiger.

    In C kennst du es ja sicher - da übergibst du den Zeiger auf eine Strutkur, um in einer Funktion darauf zuzugreifen.
    In C++ erledigt der Compiler das für dich, und somit hast du als Programmierer den Eindruck, als würden die Funktionen tatsächlich zur Klasse/zum Objekt gehören.

    Wenns dich interessiert, schau dir einfach mal den Assembler Code zu einem einfachen C++ Code an!

    // in C:
    struct MyStruct
    {
     int x;
     int y;
    };
    
    void foo(MyStruct* s)
    {
     s->x=s->y*2;
    }
    
    // in C++
    struct MyStruct
    {
     int x;
     int y;
    
     void foo()
     {
       this->x=this->y*2;
       // oder abgekürzt:
       x=y*2;
     }
    
    };
    

    Wie ist es eigentlich wenn ich jetzt eine C++-Vector-Container für die ganzen Vektoren meiner Modelle verwende, kann ich die einfach so an einen OpenGL VBO übergeben oder muss das extra vorher nochmal in ein CArray konvertiert werden?

    Wenn die Daten im vector bereits im richtigen Format vorliegen, dann nimm einfach die Startadresse vom vector:
    std::vector<int> myIntVec;
    myIntVec.resize(1000); // enthält 1000 int's
    int* ptr=&myIntVec[0]; // zeigt auf das interne Array. Das ist beim vector garantiert zusammenhängend - im Gegensatz zu std::list.



  • Super, danke für die ausführliche Erklärung.


Anmelden zum Antworten