Koordinatensysteme und Linien



  • Hallo,

    ich habe ein kleines Programm zum Zeichnen eines Models.
    Nun moechste ich das in C++ schreiben, aufraeumen und erweitern.

    Mein Problem aktuell ist dass die Koordinaten in diesem Code nicht so wirklich verstaendlich sind:

    ```cpp
    
    // c --> canvas
    // shape ist an position (x,y) und soll von einigen Linien ueberlagert werden mit Farbe (r,g,b)
    
     for (int i=0; i < line_n*2; i++) {
      int xfrom=line_padding + shape_x + i * line_spacing;
      int xto=line_padding + shape_x + i * line_spacing;
      if ((i % 2) == 0) {
        g = 0.35;
      } else {
        g = 1.0;
      }
    
      int yfrom = shape_y;
      int yto = shaoe_y + line_height;
    
     // zeichnen der Linie
      c.line(xfrom, yfrom, xto, yto,
          r,g,b);
    }
    }
    

    Wie kann man die Koordinaten und Positionen so benennen dass der Code lesbarer (und maintainbar) wird ?
    Vielen Dank!


  • Mod

    Wenn man viele Variablen mit ähnlichen Namen hat (oder mit thematisch zusammengehörigen Namen), dann ist das ein sicheres Zeichen, dass man irgendeine verbundene Datenstruktur nutzen sollte. Du hast das sogar mehrmals bei den selben Variablen, sowohl mit der Relation x-y, als auch der Relation from-to. Und sonst auch bei deinen line- und shape- Eigenschaften.

    Da in deinem Programm bisher jeder Ansatz von solchen Strukturen fehlt (Wohingegen sonst meist sogar gänzlich andersherum gearbeitet wird, von den Datenstrukturen zum Programm hin), gehe ich recht, dass du da bisher überhaupt gar keine Erfahrung hast? Klassen, Vectoren, Arrays, usw., kannst du damit was anfangen?



  • @SeppJ danke, ja OOP sagt mir was... gute Idee, die Linien koennte eine Klasse sein mit (x0, y0) und (x1, y1) als Endpunkt.
    Shape koennte ebenfalls so etwas sein aber da gibt es schon mehr Auswahl.

    Also, so anfange:

      namespace render_engine {
       class line {
             double x0, x1;
             double y0, y1;
        .... 
           }
        class shape {
              e_num type;  // koente rect, or circle sein z.b.
         } 
          }


  • @patrickm123 sagte in Koordinatensysteme und Linien:

    als Endpunkt

    struct Point { double x; double y };?



  • @manni66 was denkst du von dieser struct

    struct point {
        int x;
        int y;
    
        point(const int x=0, const int y=0) : x(x), y(y) {};
    
        void translate(const point & p) {
          x = x + p.x;
          y = y + p.y;
        }
      };
    

    dieses translate soll dabei helfen von einem koordinatensystem ins andere zu schieben.

    ebenfalls braeuchte ich noch was fuer eine bounding box, meistens sollen die element irgendwie automatisch abstand zu einem anderen element halten.



  • Ich würde eher empfehlen, so eine Translation als freie Funktion umzusetzen. So lassen sich verschiedene Transfomationen (die du später wahrscheinlich auch noch brauchst, wenn du da Grafik machst) eleganter verketten - oder auch einfach nur mehrere Translationen, z.B. wenn man ein hierarchisches Modell zeichnen will:

    struct point {
        int x;
        int y;
    }
    
    point translate(const point p, const point t) {
        return point{ p.x + t.x, p.y + t.y };
    }
    
    ...
    
    auto p = translate(rotate(scale(translate(p, a), b), c), d);
    


  • Alternative wäre noch eine fluent interface (also doch mittels einer Klasse):

    auto p = point(x, y).translate(a).scale(b).rotate(c);
    


  • Ein weiteres alternatives Interface könnte auch so aussehen:

    auto p = rotate(c) * scale(b) * translate(a) * point{ x, y };
    

    Dieses Fass würde ich aber erst aufmachen, wenn du das mit dem namespace render_engine ernst meinst und nicht nur ein paar Rechtecke verschieben möchtest.



  • @Finnegan danke, der syntax sieht gut aus, aber in der tat vielleicht erst interessant wenn es viele "shape" types gibs, und evt. gruppen von shapes

    was waeren denn die naechsten schritte fuer eine graphics library, ein paar "einfache" sachen aus dem bereich geometric algorithms: https://en.wikipedia.org/wiki/Category:Geometric_algorithms ?



  • @patrickm123 sagte in Koordinatensysteme und Linien:

    was waeren denn die naechsten schritte fuer eine graphics library, ein paar "einfache" sachen aus dem bereich geometric algorithms: https://en.wikipedia.org/wiki/Category:Geometric_algorithms ?

    Ah, da geht die Reise hin. Gut zu wissen. Da würde es tatsächlich Sinn machen, sich erstmal darum zu kümmern, möglichst bequem ein wenig simple Lineare Algebra machen zu können. Matrix- und Vektorklassen für 2, 3 und 4 Dimensionen und ensprechende grundlegende Operationen (Addition, Multiplikation, Transponieren, Skalar- Kreuzprodukt, Matrix invertieren und sowas). Alternativ auch über eine Bibliothek reinholen (vielleicht glm oder sowas).

    Als nächtses wäre es empfehlenswert, eine Datenstruktur zu bauen, mit der du ohne allzu grosse Verrenkungen auf die für solche Algorithmen interessanten Teile deiner Modelle/Graphen/Dreiecksnetze (Knoten, Kanten, Flächen) zugreifen und diese manipulieren kannst. Da bietet sich vielleicht eine Half-Edge-Datenstruktur an. Die ist sehr flexibel einsetzbar, allerdings machen für verschiedene Algorithmen auch verschiedene Datenstrukturen Sinn - das wird in der späteren Entwicklung möglicherweise nicht die einzige Datenstruktur bleiben. Für effizientes Rendering will man auch wohl eher simple Vertex- und Triangle-Lists haben, mit der man direkt die Grafikkarte füttern kann. Eine Idee wäre einmal Half-Edge zur Manipulation und einmal eine Vertex/Triangle-Repräsentation zum Rendern inklusive einer Konvertierung, mit der du beide Repräsentationen ineinander überführen kannst.

    Bequemer geht das alles natürlich mit einer fertigen Library. CGAL kommt mir da z.B. in den Sinn. Die ist genau für solche Sachen gemacht und beinhaltet wohl auch schon die meisten Algorithmen, die du da vermutlich umsetzten willst. Auch wenn du es selbst machen willst, lohnt es sich die trotzdem mal anzusehen um eine Idee davon zu bekommen, wie so eine Bibliothek aussehen kann, wenn sie ausgewachsen ist und was man dafür alles braucht. Oder CGAL für Lineare Algebra und Datenstrukturen verwenden und die Algorithmen trotzdem damit selbst umsetzen.


Log in to reply