mit Bresenham...

  • Frage:
    Der von mir geänderte Code (siehe 3 Post weiter oben) funktioniert für die Linie, für das Rechteck, und für den Stern, nicht aber für das Fünfeck.
    Jetzt sollte man meinen, dass wenn der Stern funktioniert, auch das Fünfeck gehen sollte, da im Stern die Linie gezeichnet wird, die im Fünfeck aber fehlt!!!


    Vielleicht kann sich noch jemand damit beschäftigen, ich komme nicht drauf.


    Euer Leadpen

  • Hinweis:


    man braucht garnicht m = dy/dx direkt ausrechnen:


    wenn m > 1 ist, ist dy > dx, wenn m <= 1, ist dy <= dx
    d.h. man braucht nur überprüfen ob dy > dx oder dy <= dx


    den fall dx == dy kann man wahlweise den fällen
    dy <= dx, dy > dx oder dy < dx, dy >= dx zuordnen


    dadurch fält auch das problem wegen der division durch 0
    weg, d.h. man braucht den fall dx == 0 nicht extra behandeln

  • Ich versteh eins nicht:
    Ich hab meinen Code zwar noch nicht fertig, aber er unterstützt nur das Zeichnen von Linien von links nach rechts, von 0 bis 90 Grad.


    Mein Problem ist, beim Stern z.B. zeichnet er auch Linien die von links oben langsam nach rechts unten gehen. Aber das sollte gar nicht möglich sein?! Schließlich ist der Anfangspunkt immer die "linkeste" x-Koordinate, und dann wird x/y dann und wann inkrementiert. Aber es wird niemals dekrementiert - kann mir irgendwer erklären wie zum Geier es dann möglich ist, dass eine Linie im Programmfenster von links nach rechts verläuft und dabei die Richtung ca. 15 Grad nach unten zeigt?


    Nachtrag: ok, ich denke ich weiß weshalb Linien mit negativer Steigung gezeichnet werden, obwohl ich lauter y++ im Code habe:
    Für das Canvas-Programm (oder wie auch immer die Umgebung heißen mag) scheint die obere Kante den y-Wert 0 zu haben. Dadurch dass man das y inkrementiert, kommt man immer weiter runter auf der Zeichenfläche.

  • Hi!


    Toll, dass du das mit der Steigung rausgefunden hast, das hat mich auch schon gewundert.


    Zum anderen Problem. Wenn du genau schaust, dann steht im Buch, das das der Algo fuer Steigung |m| < 1, d.h. fuer einen Winkel kleiner 45 Grad. Wie du das andere machst, liest du weiter oben im Forum. Nach 45 Grad x und y vertauschen, bzw. musst du die Linien in die andere Richtung auch zeichnen.


    lg

  • Zitat

    Original geschrieben von MichiK
    kleiner hinweis:
    die positive richtung auf der x achse geht am canvas nach rechts,
    die positive richtung auf der y achse nach unten


    MfG, Michael


    Danke! Genau das habe ich gebraucht um meinen Fehler zu finden...ich bin wohl der einzige der das Beispiel wie in der Vorlesung erwähnt mit "Finde den linken Punkt gemacht hat"....dadurch habe ich nicht gemerkt, dass sich bei mir die Linien nie negativ gegen die Y-Achse bewegen konnten :thumb:

  • Ich bin mir ziemlich sicher, dass ein Fehler auf jeden Fall mal in folgende Zeilen ist:
    if (y1<y2)
    {
    yAnf=y1;
    yEnd=y2;}
    else
    { yAnf=y2;
    yEnd=y1;}


    Nehmen wir an, Du übergibst der Methode die Punkte (5,8) und (10,2). Dann wäre das xAnf Deinem Code zu folge, das kleinere x, also 5. Und das yAnf wäre dann das kleinere y, nämlich 2. Du hättest dann den Punkt (5,2), was nicht den übergebenen Zahlen entspricht.


    Lösung: Die x-Abfrage ist in Ordnung. Aber die y-Abfrage muss weggelassen werden. Stattdessen setzt Du, wenn Du das xAnf ermittelt hast (eh wie im Code), gleich das yAnf mit. Wenn jetzt das xAnf z.B. x1 ist, dann muss yAnf y1 sein. Denn es ist ausgeschlossen, dass der Methode irgendwelche vermischten Koordinaten übergeben werden, mal das x von einem Punkt, das y vom nächsten, vertauscht mit dem z vom dritten *g*.
    Worauf ich hinaus will, ist, dass Du davon ausgehen kannst/musst, dass die Paare geordnet sind. Das heißt, das x1 gehört zum y1, und das x2 zum y2. Du möchtest in Deinem Code nur herausfinden, welcher davon beiden weiter links oder weiter unten liegt - je nach Deinem Algorithmus.


    Eine Möglichkeit der Darstellung wäre:
    if (x1<x2)
    { xAnf=x1;
    xEnd=x2;
    yAnf=y1;
    yEnd=y2;
    }
    else
    { xAnf=x2;
    xEnd=x1;
    yAnf=y2;
    yEnd=y1;
    }

  • Zitat

    Original geschrieben von Shade
    irgendwie klappt der bresenham nicht.kann mir jemand helfen wieso?hab nur die abfrage x<xEnd wegelassen da ich staat dem x ein xAnf eingeführt hab das immer kleiner als xEnd ist...



    Nur auf den ersten Blick: Dir fehlt die Abfrage, ob dx positiv oder negativ ist, dass gleiche gilt für dy. Ich werd mal schauen ob ich da irgendwas finde, aber ich bin nicht so gut darin....ich kann dir ja mal meins zeigen....12gauges unübertroffen komplizierte, unübersichtliche aber dennoch funktionierende Lösung...du solltest Post haben

  • Zitat

    Original geschrieben von Shade
    irgendwie klappt der bresenham nicht.kann mir jemand helfen wieso?hab nur die abfrage x<xEnd wegelassen da ich staat dem x ein xAnf eingeführt hab das immer kleiner als xEnd ist...


    deine werte-vorverarbeitung ist ein bißchen wirr ...


    beachte, wenn du x1 und y1 vertauschst, mußt du auch y1 und y2 vertauschen.


    bei deinem source:
    z.b. du hast eine linie (x1,y1)-(x2,y2) : (20,100)-(200,50)
    da y1 > y2 vertauschst du nur y1 und y2:
    auf einmal hast du eine linie (20,50)-(200,100)


    Ansich ist eine gesonderte behandlung von dx == 0, dy == 0, dx == dy nicht notwendig.


    es ist auch nicht notwendig die steigung m explizit auszurechnen

  • Ok, der erste Fehler ist:
    Zeile 150:
    p = p +(doubleDeltaY-doubleDeltaX);
    Das gehört umgekehrt, also doubleDeltaX-doubleDeltaY.


    Und wenn Du das richtiggestellt hast, hast Du noch ein geringfügiges Problem, nämlich die while-Bedingung: yAnf < yEnd in Zeile 139.
    Ich gehe mal davon aus, dass xAnf, yAnf jetzt der Punkt ist, der weiter links liegt. Ok, das heißt aber, dass yAnf nicht unbedingt auch der kleinere y-Wert sein muß. Je nachdem ob die Linie hinauf oder hinunter geht, kann yAnf < yEnd sein oder > yEnd.
    D.h. Du mußt da zwischen 2 Fällen unterscheiden. Den einen Fall hast Du bereits berücksichtigt: yAnf < yEnd.
    Nun muss noch eine zweite while-Schleife nach dieser folgen, die den umgekehrten Fall erfasst, also yAnf > yEnd.
    Dabei wird dann jeweils immer yAnf dekrementiert, wenn mich jetzt nicht alles täuscht.


    Nachtrag:
    p = doubleDeltaY - deltaX;
    Diese Initialisierung der Variablen p gilt nur für den Fall, dass m < 1 ist. Bei mehr als 45 Grad, also m > 1, musst Du p mit doubleDeltaX - DeltaY initialisieren.