Name gesucht: Koordinate mit Richtung



  • Wie würde man die Klassen und Variablen unten richtig benennen?

    struct Koordinate {
        double x, y;
    };
    struct Richtung { // oder nur ein typedef auf double?
        double Winkel_zwischen_0_und_2pi;
    };
    struct Koordinate_mit_Richtung {
        Koordinate Ort;
        Richtung Ausrichtung;
    };
    

    Ausserdem: Kann ich Koordinate_mit_Richtung von Koordinate erben lassen oder soll ich besser einen Konvertierungsoperator anbieten?



  • Ist eine Koordinate_mit_Richtung eine Koordinate? Wenn ja ... dann könnte Vererbung das Mittel der Wahl sein. Aber das ist durch die paar Zeilen Code, ohne weitere Infos zu den Klassen schwer zu sagen.
    Da müsstest Du schon ein bissel Butter bei die Fische packen und erklären was du denn mit den beiden Klassen vorhast.



  • Ich denke das hängt stark davon ab, wofür du das nutzen willst. Ich selbst mache viel Grafikprogrammierung und bei mir heissen solche Variablen dann meist position und rotation . Es kann aber sein, dass du vielleicht eine Software für einen Anwendungsbereich schreibst, in dem solche Größen geläufige Fachbegriffe haben. In dem Fall würde ich dann diese verwenden.

    Dass Winkel im Bogenmaß angegeben sind ist bei mir außerdem meist Konvention für das gesamte Projekt, das sollte nicht unbedingt in den Variablennamen einfließen. Wenn man Mißverständnissen vorbeugen will, kann man Grad/Bogenmaß in den Typen einfließen lassen und einen Konvertierungsoperator anbieten.

    Was das erben angeht, so würde ich darauf verzichten - mir fällt zwar jetzt auf Anhieb kein gutes Beispiel ein wo Vererbung hier später zu Problemen führt, aber im Allgemeinen sind zu ausgeprägte Vererbungshierarchien später deutlich schwierger zu warten ("Composition over inheritance"-Faustregel).

    Finnegan



  • Der Anwendungszweck ist vergleichbar mit einem Computerspiel, wo manche Einheiten eine (absolute) Position haben und andere zusätzlich zur Position noch eine Ausrichtung (also wo die Einheit ist und wohin sie schaut). Dann gibt es Hilfsfunktionen, die manchmal nur mit Koordinaten arbeiten und manchmal mit Koordinaten und einer Ausrichtung.

    Anstatt da immer zwei Parameter zu übergeben, dachte ich mir, es sei am besten, daraus eine neue Klasse zu basteln und den Einheiten eine DirectedPosition (so heisst die Klasse aktuell) zu geben. Diese DirectedPosition habe ich von Position geerbt um schnell von DirectedPosition in Position konvertieren zu können und damit ich .x statt .pos.x schreiben kann. Wartungsprobleme sehe ich dabei nicht, denn DirectedPosition wird das einzige Kind bleiben und daran etwas zu ändern habe ich auch nicht vor. Es ist halt schön, DirectedPosition by Reference zu übergeben und in einer anderen Funktion was daran ändern zu können, obwohl sie eigentlich nur eine Position entgegen nimmt. Es ist ja nicht so, dass ich eine Riesenhierarchie auf Position aufbaue.

    Den Winkel hatte ich auch vor, implizit überall in Bogenmass zu speichern.

    Ist das so eine gute Idee?



  • direktor schrieb:

    Der Anwendungszweck ist vergleichbar mit einem Computerspiel, wo manche Einheiten eine (absolute) Position haben und andere zusätzlich zur Position noch eine Ausrichtung (also wo die Einheit ist und wohin sie schaut). Dann gibt es Hilfsfunktionen, die manchmal nur mit Koordinaten arbeiten und manchmal mit Koordinaten und einer Ausrichtung.

    Anstatt da immer zwei Parameter zu übergeben, dachte ich mir, es sei am besten, daraus eine neue Klasse zu basteln und den Einheiten eine DirectedPosition (so heisst die Klasse aktuell) zu geben. Diese DirectedPosition habe ich von Position geerbt um schnell von DirectedPosition in Position konvertieren zu können und damit ich .x statt .pos.x schreiben kann. Wartungsprobleme sehe ich dabei nicht, denn DirectedPosition wird das einzige Kind bleiben und daran etwas zu ändern habe ich auch nicht vor. Es ist halt schön, DirectedPosition by Reference zu übergeben und in einer anderen Funktion was daran ändern zu können, obwohl sie eigentlich nur eine Position entgegen nimmt. Es ist ja nicht so, dass ich eine Riesenhierarchie auf Position aufbaue.

    Kann man sicher so machen, obwohl ich persönlich bei solchen Hilfsfunktionen die Variante mit den zwei Argumenten bevorzuge. Meiner Erfahrung nach kommt es öfter mal vor, dass man eine solche Funktion irgendwann z.B. mit einem Winkel aufrufen möchte, der nicht in einem Position/Winkel-Paar gespeichert ist - vielleicht weil man diesen gerade in einer lokalen Variable ausgerechnet hat. Dann musst du dir erst eine DirectedPosition zusammenbauen um die Funktion aufrufen zu können - das fände ich umständlich und vielleicht auch nicht elegant, wenn das Paar konzeptionell z.B. keine wirkliche "Position mit Richtung" ist, sondern etwas anderes, das du mit der Hilfsunktion ausrechnen willst.

    direktor schrieb:

    Den Winkel hatte ich auch vor, implizit überall in Bogenmass zu speichern.

    Ist das so eine gute Idee?

    Ja, warum nicht. Die trigonometrischen Funktionen wie sin() , cos() , etc. erwarten ohnehin Bogenmaß. Es sollte allerdings aus den Kommentaren/der Dokumentation hervorgehen, welche Einheit hier verwendet wird.
    Man kann es auch etwas umständlicher entwerfen, wenn man vermeiden will, dass es zu Missverständnissen kommt, und wie erwähnt die Einheit zu einem Teil des Typen machen, der dann implizite Konvertierung unterstützt. z.B:

    Degrees angle1 = 90.0_deg;
    Radians angle2 = (0.5 * PI)_rad;
    
    cout << angle1 + angle2 << endl;
    
    180.0 degrees
    

    (Auf genaue Implementierung gehe ich jetzt nicht ein)

    ... oder über Template-Parameter wie es z.B. in std::chrono gemacht wird um die verschiedenen Zeiteinheiten abzubilden.
    Für ein einfaches Spiel ist das aber sicher übertrieben - wenn du allerdings ein Navigationssystem für eine 500-Millionen-Euro-Rakete schreibst, ist es sicher nicht verkehrt, jegliche Missverständnisse von vornherein auszuschließen 😃

    Finnegan


Log in to reply