Bresenham Algorithmus



  • hi,
    ich habe hier den Bresenham Algorithmus mit einer liste verbunden
    jedoch funktionieren die Sonderfälle nicht richtig d.h. er zeichnet nicht von
    oben nach unten und nicht von rechts nach links ich kann den Fehler einfach nicht finden.

    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;
    	}}}
    


  • oO



  • 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