Klassendesign für Mathe



  • Hi,

    ich bin derzeit am grübeln, wie ich Methoden meiner Klasse schön strukturiere, daher wollte ich mir ein paar Meinungen einholen.

    Als Beispiel nehme ich mal eine Matrix-Klasse, wo ich derzeit zwischen 4 Varianten am entscheiden bin.

    Variante 1:

    class matrix
    {
    // [...]
    
        // Diese Matrix zu einer Translationsmatrix wandeln.
        void translate (float x, float y, float z);
    
    // [...]
    };
    

    Variante 2:

    class matrix
    {
    // [...]
    
        // Diese Matrix zu einer Translationsmatrix wandeln und 
        // referenz auf sich selbst wiedergeben.
        matrix& translate (float x, float y, float z);
    
    // [...]
    };
    

    Variante 3:

    class matrix
    {
    // [...]
    
        // Neue Translationsmatrix berechnen und wiedergeben.
        static matrix translate (float x, float y, float z);
    
    // [...]
    };
    

    Variante 4: Gefällt mir nicht so sehr, da ich "globale Funktionen" habe.

    class matrix
    {
    // [...]
    };
    
    // Neue Translationsmatrix berechnen und wiedergeben.
    matrix translate (float x, float y, float z);
    

    Ich würde mehr zur Variante 1 und 2 tendieren, jedoch frage ich eher mal die Profis was die davon halten, da diese ja sicherlich auch schon mal vor so einem Problem standen und sich damit besser auskennen als ich 😉

    Danke euch vielmals für eure Hilfe!

    Liebe Grüße,
    C++'ler



  • ich wuerd sagen, entscheide zw. den varianten 1, 2, 3 so, wie es dir am besten passt, sprich wie du es am besten gebrauchen kannst, wenn du mit der klasse arbeitest.

    mfg,
    julian



  • Tja, das ist das Problem, ich weiß eben nicht gerade wie man es am besten braucht, da ich noch nicht die großartige Erfahrung gesammelt habe wie andere hier. 🙂 Darum frag ich ja auch 😉



  • Also es kommt drauf an, was du machen willst. 1 und 2 spielen eigentlich keine Rolle, ausser du willst sowas machen:

    matrix m;
    m.translate (2,2,2).translate (5,5,5);
    

    (Das wird häufig für Operatoren gemacht, damit man die auch Verknüpfen kann)

    Und da translate für mich eine Veränderung einer Matrix suggeriert, machen 3 und 4 nicht wirklich Sinn.

    Also ich würde hier mal die Variante 2 nehmen, dann noch die Operatoren +, += usw. richtig implementieren und dann ist sowas ganz einfach möglich:

    matrix m;
    matrix b;
    
    matrix c = (m+b.translate (2,2,2)).translate (5,5,5);
    


  • Translate sollte auf der Matrix selbst arbeiten, da man meist die eigentliche Matrix manipulieren möchte und nicht eine Kopie. Falls man dies doch möchte kann man ja leicht die Kopie selbst anlegen und dann translate() benutzen, oder du benutzt zwei methoden einmal translate und eine welche eine Kopie erzeugt die du translate_ oder so nennst



  • Tippgeber schrieb:

    Translate sollte auf der Matrix selbst arbeiten, da man meist die eigentliche Matrix manipulieren möchte und nicht eine Kopie. Falls man dies doch möchte kann man ja leicht die Kopie selbst anlegen und dann translate() benutzen, oder du benutzt zwei methoden einmal translate und eine welche eine Kopie erzeugt die du translate_ oder so nennst

    Das habe ich ja mit meinem obigen Post sagen wollen. Mann kann dann direkt durch den copy-ctor ein neues Objekt initialisieren, indem man einfach die Operationen angibt.



  • Wenn ich das richtig verstanden habe, meinst Du eine Translation in 3D und mit den drei Koordinaten x,y,z ist diese bereits vollständig bestimmt. Es werden also keine keinerlei Koordinaten des 'alten' matrix-Objektes benötigt.

    Dieser Umstand spricht gegen eine Methode und für eine (globale) Funktion, die Dir das gewünschte matrix-Objekt erstellt. Nicht mehr und nicht weniger.

    Du benötigst auch keine statische Funktion, solange Du nur eine Matrix-Klasse besitzt. Wenn Du es 'weniger global' haben möchtest, so würde ich einen namespace vorschlagen, in dem diese Funktion definiert ist.

    Die Schnittstelle, die Du wählst, sollte die Funktion Deiner Domain - in diesem Fall wahrscheinlich das Hantieren mit Transformationsmatizen - sichtbar machen. D.h. die Ausdrücke im Code sollten so aussehen, wie die Ausdrücke, die Du auch als mathematischen Ausdruck hinschreiben kannst.

    Transformationsmatrizen werden auch nicht addiert sondern multipliziert. Es bietet sich daher an, für die Verknüpfung zweier Transformationsmatizen die Multiplikation zu implementieren.

    Auch würde ich die drei Koordinaten in einem Vektor zusammenfassen.

    Im Code sähe es dann z.B. so aus:

    Vector v = ..;
        matrix m = make_translation( v );
    

    Gruß
    Werner


Anmelden zum Antworten