Bresenham Algorithmus



  • indent hat geschrieben:

    void polygon_zeichnen(Monitor * m, ELEMENT * liste)
    {
        int y, x, int_fehler, delta, schritt, dx, dy, inc_x, inc_y;
    
        ELEMENT *hz = liste;
        ELEMENT *hz2 = liste->next;
        Punkt punkt;
    
        if (hz != NULL && hz2 != NULL)
        {
            while (hz2 != NULL)
            {
                x = hz->inhalt.x;          // Koordinaten retten
                y = hz->inhalt.y;
    
                dy = hz2->inhalt.y - hz->inhalt.y;  // Hoehenzuwachs berechnen
                dx = hz2->inhalt.x - hz->inhalt.x;  // Schrittweite
    
                if (dx > 0)                // Linie nach rechts?
                    inc_x = 1;             // x inkrementieren
                else                       // Linie nach links
                    inc_x = -1;            // x dekrementieren
                if (dy > 0)                // Linie nach unten?
                    inc_y = 1;             // y inkrementieren
                else                       // Linie nach oben
                    inc_y = -1;            // y dekrementieren
    
                if (dy < dx)
                {                          // flach nach oben oder unten
                    int_fehler = -dx;      // Fehler bestimmen
                    delta = 2 * dy;        // Delta bestimmen
                    schritt = 2 * int_fehler;   // Schwelle bestimmen
                    while (x != hz2->inhalt.x)
                    {                      // Fuer jede x-Koordinate
                        punkt.x = x;
                        punkt.y = y;
                        punkt_setzen(punkt, m); // setze Pixel
                        x = x + inc_x;     // naechste x-Koordinate
                        int_fehler = int_fehler + delta;    // Fehler aktualisieren
                        if (int_fehler > 0)
                        {                  // neue Spalte erreicht?
                            y = y + inc_y; // y-Koord. aktualisieren
                            int_fehler = int_fehler + schritt;  // Fehler aktualisieren
                        }
                    }
                }
                else
                {                          // steil nach oben oder unten
                    int_fehler = -dy;      // Fehler bestimmen
                    delta = 2 * dx;        // Delta bestimmen
                    schritt = 2 * int_fehler;   // Schwelle bestimmen
                    while (y != hz2->inhalt.y)
                    {                      // fuer jede y-Koordinate
                        punkt.x = x;
                        punkt.y = y;
                        punkt_setzen(punkt, m); // setze Pixel
                        y = y + inc_y;     // naechste y-Koordinate
                        int_fehler = int_fehler + delta;    // Fehler aktualisieren
                        if (int_fehler > 0)
                        {                  // neue Zeile erreicht?
                            x += inc_x;    // x-Koord. aktualisieren
                            int_fehler = int_fehler + schritt;  // Fehler aktualisieren
                        }
                    }
                }
                punkt.x = hz2->inhalt.x;
                punkt.y = hz2->inhalt.y;
                punkt_setzen(punkt, m);    // setze Pixel
                hz = hz->next;
                hz2 = hz2->next;
            }
        }
    }
    

    dein code mag schneller sein (wenn er liefe), aber ich wuerde die redundanzen entfernen. dann siehts wenigstens sauberer aus.



  • Hi. Wenn du willst, kannst du das mal mit meiner Realisierung dieses Algorithmus vergleichen. Vielleicht kannst du so den Fehler finden.

    (Die ist allerdings auf n Dimensionen verallgemeinert, so dass ich nicht jeden Quadranten separat behandeln konnte. Im Prinzip sollte es aber das gleiche sein.)

    public float castLine(final Vector startPoint, final Vector endPoint)
       {
          // Check parameters.
          if (startPoint.getDimension() != dimension)
             throw new IllegalArgumentException("startPoint has wrong dimension.");
          if (endPoint.getDimension() != dimension)
             throw new IllegalArgumentException("endPoint has wrong dimension.");
    
          // Clip line: 
          // Resulting line is given by rasterStartPoint and rasterEndPoint.
          final int[] rasterStartPoint = new int[dimension];
          final int[] rasterEndPoint = new int[dimension];
          if(!setFirstPointInRaster(rasterStartPoint,startPoint,endPoint)) return 0.0f;
          if(!setFirstPointInRaster(rasterEndPoint,endPoint,startPoint)) return 0.0f;
    
          // Init helper variables.
          int maxDiffIndex = 0;
          final int[] intDifferences = new int[dimension];
          final int[] relativePosition = new int[dimension];
          final int[] position = new int[dimension];
          final int[] increments = new int[dimension];
          for(int i = 0 ; i < dimension ; ++i)
          {
             intDifferences[i] = rasterEndPoint[i] - rasterStartPoint[i];
             increments[i] = (intDifferences[i] > 0) ? 1 : -1;
             intDifferences[i] = Math.abs(intDifferences[i]);
             if (intDifferences[i] > intDifferences[maxDiffIndex]) maxDiffIndex = i;
             relativePosition[i] = intDifferences[i] >> 1;
             position[i] = rasterStartPoint[i];
          }
          final int maxDifference = intDifferences[maxDiffIndex];
          final int maxIncrement = increments[maxDiffIndex];
    
          // Process line: 
          // 1. Reset pointProcessor.
          // 2. Process Bresenham-Line-Algorithm
          // 3. Return value of pointProcessor
          pointProcessor.reset();
          for(;position[maxDiffIndex] != rasterEndPoint[maxDiffIndex] ; position[maxDiffIndex] += maxIncrement)
          {
             if (pointProcessor.addPoint(raster,position)) break;
             for(int i = 0 ; i < dimension ; ++i)
             {
                if (i == maxDiffIndex) continue;
                relativePosition[i] += intDifferences[i];
                if (relativePosition[i] < maxDifference) continue;
                position[i] += increments[i];
                relativePosition[i] -= maxDifference;
             }
          }
          pointProcessor.addPoint(raster,position);
          return pointProcessor.getValue();
       }
    


  • Aber was ist denn das Problem ich habe meinen code genau nach dem Bresenham Code Aufgebaut und mit der Liste verbunden ich sehe jetzt keine logischen fehler darin

    @gregor:ok danke werds versuchen



  • blizzarac: Naja, ich habe mich längere Zeit nicht mehr mit diesem Algorithmus befasst. Insofern weiß ich nicht, ob folgendes tatsächlich ein Fehler ist, aber überleg dir mal folgendes:

    Du hast da:

    if(dy < dx) { // flach nach oben oder unten

    Der Kommentar passt da zumindest nicht zur Abfrage. Überleg dir mal, was passiert, wenn dx oder dy negativ sind, z.B. dy -10000 und dx = -5. Dann hat die Gerade nicht so eine Steigung, wie sie dein Kommentar wohl beschreiben soll. Du müßtest da wohl eher Absolutbeträge vergleichen.



  • was macht denn die funktion math.abs? und wie setze ich sie in c um?



  • Da gibt es sicherlich entsprechende Funktionen in der Standardbibliothek. Aber da ich mich da nicht auskenne...

    int abs(int x)
    {
    if (x < 0) x = -x;
    return x;
    }

    ...oder auch in einer einfacheren Variante. 🙂



  • jo danke das ist hilfreich da wir sowieso keine befehle benutzen dürfen die wir noch nicht in der vorlesung hatten



  • hmm jetzt bricht das programm bei sonderfällen ab..

    void polygon_zeichnen(Monitor * m, ELEMENT * liste)
    {
        int y, x, int_fehler, delta, schritt, dx, dy, inc_x, inc_y;
    
        ELEMENT *hz = liste;
        ELEMENT *hz2 = liste->next;
        Punkt punkt;
    
        if (hz != NULL && hz2 != NULL)
        {
            while (hz2 != NULL)
            {
                x = hz->inhalt.x;          // Koordinaten retten
                y = hz->inhalt.y;
    
                dy = hz2->inhalt.y - hz->inhalt.y;  // Hoehenzuwachs berechnen
                dx = hz2->inhalt.x - hz->inhalt.x;  // Schrittweite
    
                if (dx > 0)                // Linie nach rechts?
                    inc_x = 1;             // x inkrementieren
                else                       // Linie nach links
                    inc_x = -1;            // x dekrementieren
                if (dy > 0)                // Linie nach unten?
                    inc_y = 1;             // y inkrementieren
                else                       // Linie nach oben
                    inc_y = -1;            // y dekrementieren
    
                if (abs(dy) < abs(dx))
                {                          // flach nach oben oder unten
                    int_fehler = - abs(dx);      // Fehler bestimmen
                    delta = 2 * abs(dy);        // Delta bestimmen
                    schritt = 2 * int_fehler;   // Schwelle bestimmen
                    while (x != hz2->inhalt.x)
                    {                      // Fuer jede x-Koordinate
                        punkt.x = x;
                        punkt.y = y;
                        punkt_setzen(punkt, m); // setze Pixel
                        x = x + inc_x;     // naechste x-Koordinate
                        int_fehler = int_fehler + delta;    // Fehler aktualisieren
                        if (int_fehler > 0)
                        {                  // neue Spalte erreicht?
                            y = y + inc_y; // y-Koord. aktualisieren
                            int_fehler = int_fehler + schritt;  // Fehler aktualisieren
                        }
                    }
                }
                else
                {                          // steil nach oben oder unten
                    int_fehler = -abs(dy);      // Fehler bestimmen
                    delta = 2 * abs(dx);        // Delta bestimmen
                    schritt = 2 * int_fehler;   // Schwelle bestimmen
                    while (y != hz2->inhalt.y)
                    {                      // fuer jede y-Koordinate
                        punkt.x = x;
                        punkt.y = y;
                        punkt_setzen(punkt, m); // setze Pixel
                        y = y + inc_y;     // naechste y-Koordinate
                        int_fehler = int_fehler + delta;    // Fehler aktualisieren
                        if (int_fehler > 0)
                        {                  // neue Zeile erreicht?
                            x += inc_x;    // x-Koord. aktualisieren
                            int_fehler = int_fehler + schritt;  // Fehler aktualisieren
                        }
                    }
                }
                punkt.x = hz2->inhalt.x;
                punkt.y = hz2->inhalt.y;
                punkt_setzen(punkt, m);    // setze Pixel
                hz = hz->next;
                hz2 = hz2->next;
            }
        }
    }
    


  • Nein hab mich geirrt es funktioniert jetzt danke für die hilfe




Anmelden zum Antworten