www.wikidata.de-de.nina.az
Der Bresenham Algorithmus ist ein Algorithmus in der Computergrafik zum Zeichnen Rastern von Geraden oder Kreisen auf Rasteranzeigen Fur Linienalgorithmen gibt es einen eigenen Ubersichtsartikel hier wird mehr die konkrete Implementierung erlautert Der Algorithmus wurde 1962 von Jack Bresenham damals Programmierer bei IBM entwickelt 1 Das Besondere an seinem Algorithmus ist dass er Rundungsfehler die durch die Diskretisierung von kontinuierlichen Koordinaten entstehen minimiert und gleichzeitig einfach implementierbar ist mit der Addition von ganzen Zahlen als komplexeste Operation und somit ohne Multiplikation Division und Gleitkommazahlen auskommt Durch eine geringfugige Erweiterung lasst sich der ursprungliche Algorithmus der fur die Rasterung von Linien entworfen wurde auch fur die Rasterung von Kreisen verwenden Sogar die Quadratterme die beim Kreis vorkommen lassen sich rekursiv ohne jede Multiplikation aus dem jeweils vorhergehenden Term ableiten nach n 1 2 n 2 2 n 1 displaystyle n 1 2 n 2 2 cdot n 1 wobei der Term 2 n displaystyle 2 cdot n nicht als Multiplikation zahlt da er in Hardware bzw auf Assemblerebene als einfache Shift Operation implementiert wird und der Term n 2 displaystyle n 2 im Endeffekt ganz vermieden werden kann Aufgrund obiger Eigenschaften ist die Bedeutung des Bresenham Algorithmus bis heute ungebrochen und er kommt unter anderem in Plottern in 3D Druckern in den Grafikchips moderner Grafikkarten und in vielen Grafikbibliotheken zur Verwendung Dabei ist er so einfach dass er nicht nur in der Firmware solcher Gerate verwendet wird sondern in Grafikchips direkt in Hardware implementiert werden kann Der Name Bresenham wird heute zudem fur eine ganze Familie von Algorithmen verwendet die eigentlich von Anderen spater entwickelt wurden jedoch in der Nachfolge von Bresenham und mit einem verwandten Ansatz siehe Einzelnachweise unten Inhaltsverzeichnis 1 Ansatz 2 Einfache Implementierung 2 1 Vergleich mit der originalen Formulierung von Bresenham 3 Elegantere Implementierungen 3 1 BASIC Implementierung 3 2 C Implementierung 3 3 Kompakte Variante 4 Kreisvariante des Algorithmus 4 1 Herleitung der Fehlerglied Initialisierung 4 1 1 Beispiel 4 2 Zeichnen nicht vollstandiger Oktanten 4 3 Ellipsen 4 3 1 Kompakte Variante 5 Weitere Verallgemeinerungen 6 Siehe auch 7 Weblinks 8 EinzelnachweiseAnsatz Bearbeiten nbsp Rastern einer Linie nach dem Bresenham Verfahren unten der Verlauf der Fehlervariablen nbsp Die Rasterung von Linien kann durch Nutzung von Symmetrieeigenschaften vereinfacht werden Der zulassige Bereich Oktant des Originalverfahrens ist farbig dargestellt durch Fallunterscheidungen der Variablen dx und dy werden auch die anderen Bereiche erschlossen Die hier vorgestellte Variante ist ein sehr praxisnaher Ansatz und wurde zuerst von Pitteway 2 veroffentlicht und von van Aken 3 verifiziert Weiter unten wird die Variante mit der originalen Formulierung von Bresenham verglichen und gezeigt dass die Losungen aquivalent sind Zum Verstandnis des Algorithmus beschrankt man sich auf den ersten Oktanten also eine Linie mit einer Steigung zwischen 0 und 1 vom Startpunkt x s t a r t y s t a r t displaystyle x mathrm start y mathrm start nbsp zum Endpunkt x e n d y e n d displaystyle x mathrm end y mathrm end nbsp Seien d x x e n d x s t a r t displaystyle dx x mathrm end x mathrm start nbsp und d y y e n d y s t a r t displaystyle dy y mathrm end y mathrm start nbsp mit 0 lt d y d x displaystyle 0 lt dy leq dx nbsp Fur andere Oktanten muss man spater Fallunterscheidungen uber Vorzeichen von d x displaystyle dx nbsp und d y displaystyle dy nbsp und die Rollenvertauschung von x displaystyle x nbsp und y displaystyle y nbsp treffen Der Algorithmus lauft dann so dass man in der schnellen Richtung hier die positive x displaystyle x nbsp Richtung immer einen Schritt macht und je nach Steigung hin und wieder zusatzlich einen Schritt in der langsameren Richtung hier die y displaystyle y nbsp Richtung Man benutzt dabei eine Fehlervariable die bei einem Schritt in x displaystyle x nbsp Richtung den hier kleineren Wert d y displaystyle dy nbsp subtrahiert bekommt Bei Unterschreitung des Nullwerts wird ein y displaystyle y nbsp Schritt fallig und der hier grossere Wert d x displaystyle dx nbsp zur Fehlervariablen addiert Diese wiederholten Uberkreuz Subtraktionen und Additionen losen die Division des Steigungsdreiecks m d y d x displaystyle m tfrac dy dx nbsp in elementarere Rechenschritte auf Zusatzlich muss dieses Fehlerglied vorher sinnvoll initialisiert werden Dazu betrachtet man den Fall von d y 1 displaystyle dy 1 nbsp bei dem in der Mitte nach der Halfte von d x displaystyle dx nbsp ein y displaystyle y nbsp Schritt kommen soll Also initialisiert man das Fehlerglied mit d x 2 displaystyle tfrac dx 2 nbsp Ob dabei zu einer ganzen Zahl aufgerundet oder abgerundet wird spielt kaum eine Rolle Mathematisch gesehen wird die Geradengleichung y y s t a r t x x s t a r t d y d x displaystyle y y mathrm start x x mathrm start cdot frac dy dx nbsp aufgelost in 0 d x y y s t a r t d y x x s t a r t displaystyle 0 dx cdot y y mathrm start dy cdot x x mathrm start nbsp und die Null links durch das Fehlerglied ersetzt Ein Schritt um 1 in x displaystyle x nbsp Richtung bewirkt eine Verminderung des Fehlerglieds um 1 d y displaystyle 1 cdot dy nbsp Wenn das Fehlerglied dabei unter Null gerat wird es durch einen Schritt um 1 in y displaystyle y nbsp Richtung um 1 d x displaystyle 1 cdot dx nbsp erhoht was nach der Voraussetzung d x d y displaystyle dx geq dy nbsp das Fehlerglied auf jeden Fall wieder positiv macht bzw mindestens auf Null bringt Der originale Ansatz nach Bresenham siehe unten geht mehr geometrisch vor wodurch in seinen Iterationsformeln auf beiden Seiten bis auf das Fehlerglied ein zusatzlicher Faktor 2 mitgefuhrt wird und auch die Fehlergliedinitialisierung anders hergeleitet wird Der Startpunkt und der Endpunkt des Rasters bilden ein rechteckiges Raster mit den vier Eckpunkten x s t a r t y s t a r t displaystyle x mathrm start y mathrm start nbsp x s t a r t y e n d displaystyle x mathrm start y mathrm end nbsp x e n d y s t a r t displaystyle x mathrm end y mathrm start nbsp x e n d y e n d displaystyle x mathrm end y mathrm end nbsp Wenn 0 lt d y d x displaystyle 0 lt dy leq dx nbsp ist dann befindet sich in jeder Spalte des rechteckigen Rasters genau ein Pixel und die Linie besteht aus d x displaystyle dx nbsp Pixeln Wenn 0 lt d x d y displaystyle 0 lt dx leq dy nbsp ist dann befindet sich in jeder Zeile genau ein Pixel und die Linie besteht aus d y displaystyle dy nbsp Pixeln Der euklidische Abstand zwischen dem Startpunkt und Endpunkt betragt d x e n d x s t a r t 2 y e n d y s t a r t 2 displaystyle d sqrt x mathrm end x mathrm start 2 y mathrm end y mathrm start 2 nbsp Eine gerade Linie mit der Linienstarke 1 musste daher aus d displaystyle d nbsp Pixeln bestehen Die mit dem Bresenham Algorithmus erzeugte Linie besteht jedoch nur aus max d x d y displaystyle max dx dy nbsp Pixeln Setzt man diese Anzahlen ins Verhaltnis dann ergibt sich als Quotient die mittlere Linienstarke w max d x d y d max x e n d x s t a r t y e n d y s t a r t x e n d x s t a r t 2 y e n d y s t a r t 2 displaystyle w frac max dx dy d frac max x mathrm end x mathrm start y mathrm end y mathrm start sqrt x mathrm end x mathrm start 2 y mathrm end y mathrm start 2 nbsp Wenn entweder d x 0 displaystyle dx 0 nbsp oder d y 0 displaystyle dy 0 nbsp ist ist offensichtlich w 1 displaystyle w 1 nbsp Fur d x d y displaystyle dx dy nbsp also fur die Steigung 1 mit dem Winkel 45 Grad ist die mittlere Linienstarke mit w 1 2 0 707 displaystyle w tfrac 1 sqrt 2 approx 0 707 nbsp minimal Einfache Implementierung BearbeitenEine erste Implementierung ist nicht sehr elegant demonstriert das Prinzip des Algorithmus aber sehr gut REM Bresenham Algorithmus fur eine Linie im ersten Oktanten in Pseudo Basic dx xend xstart dy yend ystart REM im ersten Oktanten muss 0 lt dy lt dx sein REM Initialisierungen x xstart y ystart SETPIXEL x y fehler dx 2 REM Pixelschleife immer ein Schritt in schnelle Richtung hin und wieder auch einer in langsame WHILE x lt xend REM Schritt in schnelle Richtung x x 1 fehler fehler dy IF fehler lt 0 THEN REM Schritt in langsame Richtung y y 1 fehler fehler dx END IF SETPIXEL x y WEND Vergleich mit der originalen Formulierung von Bresenham Bearbeiten REM Quasi Bresenham Algorithmus REM Original Bresenham dx xend xstart dx xend xstart dy yend ystart dy yend ystart d 2 dy dx dO 2 dy dNO 2 dy dx x xstart x xstart y ystart y ystart SETPIXEL x y SETPIXEL x y fehler dx 2 fehler d WHILE x lt xend WHILE x lt xend x x 1 x x 1 fehler fehler dy IF fehler lt 0 THEN IF fehler lt 0 THEN fehler fehler dO ELSE y y 1 y y 1 fehler fehler dx fehler fehler dNO END IF END IF SETPIXEL x y SETPIXEL x y WEND WEND Abgesehen von der Anpassung an den verwendeten BASIC Dialekt sind folgende Unterschiede bei der originalen Formulierung zu beachten Das Fehlerglied wird mit umgekehrtem Vorzeichen verwendet Das Fehlerglied wird auf sein Vorzeichen abgefragt bevor es aktualisiert wird dadurch wird die zusatzliche Initialisierung mit dem dy Term notwendig Das Fehlerglied ist um den Faktor 2 erweitert so dass bei der Initialisierung keine Division durch 2 stattfindet dafur aber die Schrittvariablen fur die Fehleraktualisierungen doppelt so gross sind Wenn man diese Unterschiede in der Formulierung berucksichtigt stellt sich heraus dass beide Formulierungen identisch arbeiten und somit aquivalent sind Elegantere Implementierungen BearbeitenAls eleganter formulierte Beispiele folgen als erstes der Quellcode eines BASIC Programmes und anschliessend eines Unterprogramms in C welche die Fallunterscheidung in acht Oktanten nicht ausdrucklich vornehmen mussen Der Algorithmus soll fur alle Oktanten gultig werden Dabei mussen die Vorzeichen der Koordinatendistanzen und die eventuelle Vertauschung der Rollen von x und y berucksichtigt werden Wenn man diese Fallunterscheidungen innerhalb der innersten Schleife treffen wurde also in hoher Anzahl wurde das die Geschwindigkeit der Berechnungen deutlich verringern Eine effiziente Losung versucht all diese Fallunterscheidungen in der Initialisierungsphase des Verfahrens vor der inneren Hauptschleife abzuarbeiten so dass innerhalb der inneren Schleife weiterhin nur die eine Abfrage fur das Bresenham Fehlerglied erfolgen muss Diese Formulierung fuhrt wie schon Stockton 4 indirekt vorschlug diverse Abstraktionen ein Zunachst wird der Schritt in die schnelle Richtung jetzt als Parallelschritt parallel zu einer Koordinatenachse angesehen und wenn zusatzlich ein Schritt in die langsame Richtung erfolgt wird das zu einem Diagonalschritt Dann kann man in der Initialisierung Variablenwerte ermitteln die fur diese Falle die Schrittweiten in den beiden Koordinatenrichtungen vorab festlegen und somit die Verallgemeinerung fur die acht Oktanten erreichen Beispielsweise ist bei einem Parallelschritt die Schrittweite in die dazu senkrechte Richtung eben Null Zweitens rechnet man den Fehlerterm weiterhin wie im ersten Oktanten mit Absolutbetragen der Distanzen In der innersten Schleife wird dann nicht mehr zuerst der Schritt in der schnellen Richtung ausgefuhrt sondern als Erstes der Fehlerterm aktualisiert und danach erst werden die Schrittweiten zu den bisherigen Koordinaten addiert je nachdem ob ein Parallel oder ein Diagonalschritt erfolgen muss BASIC Implementierung Bearbeiten REM Bresenham Algorithmus fur eine Linie in einem beliebigen Oktanten in Pseudo Basic dx xend xstart dy yend ystart REM Initialisierungen adx ABS dx ady ABS dy Absolutbetrage Distanzen sdx SGN dx sdy SGN dy Signum der Distanzen IF adx gt ady THEN x ist schnelle Richtung pdx sdx pdy 0 pd ist Parallelschritt ddx sdx ddy sdy dd ist Diagonalschritt deltaslowdirection ady deltafastdirection adx Delta in langsamer Richtung Delta in schneller Richtung ELSE y ist schnelle Richtung pdx 0 pdy sdy pd ist Parallelschritt ddx sdx ddy sdy dd ist Diagonalschritt deltaslowdirection adx deltafastdirection ady Delta in langsamer Richtung Delta in schneller Richtung END IF x xstart y ystart SETPIXEL x y fehler deltafastdirection 2 REM Pixelschleife immer ein Schritt in schnelle Richtung hin und wieder auch einer in langsame FOR i 1 TO deltafastdirection Anzahl der zu zeichnenden Pixel REM Aktualisierung Fehlerterm fehler fehler deltaslowdirection IF fehler lt 0 THEN fehler fehler deltafastdirection Fehlerterm wieder positiv machen REM Schritt in langsame Richtung x x ddx y y ddy Diagonalschritt ELSE REM Schritt in schnelle Richtung x x pdx y y pdy Parallelschritt END IF SETPIXEL x y NEXT C Implementierung Bearbeiten In dieser Implementierung wird die Signumfunktion verwendet signum function int sgn int x if x gt 0 return 1 if x lt 0 return 1 return 0 void gbham int xstart int ystart int xend int yend Bresenham Algorithmus Linien auf Rastergeraten zeichnen Eingabeparameter int xstart ystart Koordinaten des Startpunkts int xend yend Koordinaten des Endpunkts Ausgabe void SetPixel int x int y setze ein Pixel in der Grafik wird in dieser oder aehnlicher Form vorausgesetzt int x y t dx dy incx incy pdx pdy ddx ddy deltaslowdirection deltafastdirection err Entfernung in beiden Dimensionen berechnen dx xend xstart dy yend ystart Vorzeichen des Inkrements bestimmen incx sgn dx incy sgn dy if dx lt 0 dx dx if dy lt 0 dy dy feststellen welche Entfernung grosser ist if dx gt dy x ist schnelle Richtung pdx incx pdy 0 pd ist Parallelschritt ddx incx ddy incy dd ist Diagonalschritt deltaslowdirection dy deltafastdirection dx Delta in langsamer Richtung Delta in schneller Richtung else y ist schnelle Richtung pdx 0 pdy incy pd ist Parallelschritt ddx incx ddy incy dd ist Diagonalschritt deltaslowdirection dx deltafastdirection dy Delta in langsamer Richtung Delta in schneller Richtung Initialisierungen vor Schleifenbeginn x xstart y ystart err deltafastdirection 2 SetPixel x y Pixel berechnen for t 0 t lt deltafastdirection t t zaehlt die Pixel deltafastdirection ist Anzahl der Schritte Aktualisierung Fehlerterm err deltaslowdirection if err lt 0 Fehlerterm wieder positiv gt 0 machen err deltafastdirection Schritt in langsame Richtung Diagonalschritt x ddx y ddy else Schritt in schnelle Richtung Parallelschritt x pdx y pdy SetPixel x y Kompakte Variante Bearbeiten Der Bresenham Algorithmus kann auch in einer einfachen Variante in C implementiert werden void line int x0 int y0 int x1 int y1 int dx abs x1 x0 sx x0 lt x1 1 1 int dy abs y1 y0 sy y0 lt y1 1 1 int err dx dy e2 error value e xy while 1 setPixel x0 y0 if x0 x1 amp amp y0 y1 break e2 2 err if e2 gt dy err dy x0 sx e xy e x gt 0 if e2 lt dx err dx y0 sy e xy e y lt 0 Das Fehlerglied wird dabei sowohl fur die langsame als auch die schnelle Richtung als Schritterkennung verwendet Die vier Quadranten werden uber das Vorzeicheninkrement sx sy abgedeckt Die Akkumulation des Fehlerglieds lost bei Uberschreitung des Schwellwertes den bedingten Schritt aus im Unterschied zur ursprunglichen Variante simultan in beide Richtungen positive Fehlerwerte fur x und negative fur die y Achse Das Beispiel zeigt damit auch elegant die xy Symmetrie des Bresenham Algorithmus Kreisvariante des Algorithmus Bearbeiten nbsp Rastern einer Kreislinie nach dem Bresenham VerfahrenDer Ansatz fur die Kreisvariante des Bresenham Algorithmus geht auch nicht auf Bresenham selbst zuruck er ahnelt der Methode von Horn aus dem Ubersichtsartikel siehe auch Pitteway und van Aken unten Man geht entsprechend von der Kreisgleichung x 2 y 2 r 2 displaystyle x 2 y 2 r 2 nbsp aus Man betrachtet zunachst wieder nur den ersten Oktanten Hier mochte man eine Kurve zeichnen die beim Punkt r 0 displaystyle r 0 nbsp anfangt und dann nach oben links bis zum Winkel von 45 fortgesetzt wird Die schnelle Richtung ist hier die y displaystyle y nbsp Richtung Man macht immer einen Schritt in die positive y displaystyle y nbsp Richtung und ab und zu muss man auch einen Schritt in die langsame negative x displaystyle x nbsp Richtung machen Die standigen Quadratberechnungen siehe Kreisgleichung oder womoglich sogar trigonometrische oder Wurzelberechnungen vermeidet man wieder durch Auflosen in Einzelschritte und rekursive Berechnung der Terme aus den jeweils vorangehenden Mathematisch Von der Kreisgleichung kommt man zur umgeformten Gleichung 0 x 2 y 2 r 2 displaystyle 0 x 2 y 2 r 2 nbsp wobei r 2 displaystyle r 2 nbsp gar nicht explizit berechnet werden muss x 2 x v o r h e r 1 2 x v o r h e r 2 2 x v o r h e r 1 displaystyle x 2 x mathrm vorher 1 2 x mathrm vorher 2 2 cdot x mathrm vorher 1 nbsp entsprechend fur y displaystyle y nbsp wobei auch hier x v o r h e r 2 displaystyle x mathrm vorher 2 nbsp nicht als eigene Variable mitgefuhrt werden muss sondern nur die Differenz von einem Schritt zum nachsten 2 x v o r h e r 1 displaystyle 2 cdot x mathrm vorher 1 nbsp dem Fehlerglied aufgeschlagen wird Wieder wird die Null in der Gleichung durch das Fehlerglied ersetzt Zusatzlich muss man dann beim Setzen der Pixel noch die Mittelpunktskoordinaten hinzuaddieren Diese standigen Festkommaadditionen schranken die Performance aber nicht merkbar ein da man sich ja Quadrierungen oder gar Wurzelziehungen in der innersten Schleife erspart Durch den Ansatz von der Kreisgleichung aus ist sichergestellt dass die Koordinaten maximal um 1 Pixel den Digitalisierungsfehler von der Idealkurve abweichen Die Initialisierung des Fehlerglieds soll nun bewirken dass der erste Schritt in die langsame Richtung dann erfolgt wenn die echte Kreiskurve um ein halbes Pixel in der langsamen Koordinate nach innen gekommen ist Details zur Rechnung weiter unten es lauft auf eine Initialisierung des Fehlerglieds mit dem Radius r displaystyle r nbsp hinaus Die Pixel der Kreislinie bilden ein rechteckiges Raster mit den vier Eckpunkten r r displaystyle r r nbsp r r displaystyle r r nbsp r r displaystyle r r nbsp r r displaystyle r r nbsp Fur r 2 x r 2 displaystyle tfrac r sqrt 2 leq x leq tfrac r sqrt 2 nbsp also y r 2 displaystyle y leq tfrac r sqrt 2 nbsp oder y r 2 displaystyle y geq tfrac r sqrt 2 nbsp befinden sich in jeder Spalte des rechteckigen Rasters befinden sich genau 2 Pixel Ebenso befinden sich fur r 2 y r 2 displaystyle tfrac r sqrt 2 leq y leq tfrac r sqrt 2 nbsp also x r 2 displaystyle x leq tfrac r sqrt 2 nbsp oder x r 2 displaystyle x geq tfrac r sqrt 2 nbsp in jeder Zeile des rechteckigen Rasters genau 2 Pixel Die Lange der Kreislinie d h der Umfang des Kreises betragt 2 p r displaystyle 2 cdot pi cdot r nbsp Eine Kreislinie mit der Linienstarke 1 musste daher aus etwa 2 p r displaystyle 2 cdot pi cdot r nbsp Pixeln bestehen Die mit dem Bresenham Algorithmus erzeugte Linie besteht jedoch wie gezeigt nur aus etwa 2 2 r 2 r 2 4 2 r displaystyle 2 cdot 2 cdot left tfrac r sqrt 2 left tfrac r sqrt 2 right right 4 cdot sqrt 2 cdot r nbsp Pixeln Setzt man diese Anzahlen ins Verhaltnis dann ergibt sich als Quotient die mittlere Linienstarke w 4 2 r 2 p r 2 2 p 0 900 displaystyle w frac 4 cdot sqrt 2 cdot r 2 cdot pi cdot r frac 2 cdot sqrt 2 pi approx 0 900 nbsp Die Formulierung des Algorithmus wird hier wieder nur fur den ersten Oktanten gezeigt und wieder ergeben sich die anderen Oktanten durch Vorzeichenwechsel in d x displaystyle dx nbsp und d y displaystyle dy nbsp und Rollenvertauschung von x displaystyle x nbsp und y displaystyle y nbsp Die Erweiterung auf den Vollkreis wie sie fur Grafikdisplays aber nicht fur Plotter geeignet ist ist in Kommentaren beigefugt REM Bresenham Algorithmus fur einen Achtelkreis in Pseudo Basic REM gegeben seien r xmittel ymittel REM Initialisierungen fur den ersten Oktanten x r y 0 fehler r REM schnelle Richtung ist hier y SETPIXEL xmittel x ymittel y REM Pixelschleife immer ein Schritt in schnelle Richtung hin und wieder auch einer in langsame WHILE y lt x REM Schritt in schnelle Richtung dy y 2 1 REM bei Assembler Implementierung 2 per Shift y y 1 fehler fehler dy IF fehler lt 0 THEN REM Schritt in langsame Richtung hier negative x Richtung dx 1 x 2 REM bei Assembler Implementierung 2 per Shift x x 1 fehler fehler dx END IF SETPIXEL xmittel x ymittel y REM Wenn es um einen Bildschirm und nicht mechanisches Plotten geht REM kann man die anderen Oktanten hier gleich mit abdecken REM SETPIXEL xmittel x ymittel y REM SETPIXEL xmittel x ymittel y REM SETPIXEL xmittel x ymittel y REM SETPIXEL xmittel y ymittel x REM SETPIXEL xmittel y ymittel x REM SETPIXEL xmittel y ymittel x REM SETPIXEL xmittel y ymittel x WEND Eine mogliche Implementierung des Bresenham Algorithmus fur einen Vollkreis in der Programmiersprache C Hierbei wird fur die quadratischen Terme eine weitere Variable mitgefuhrt die dem Term 2 n 1 displaystyle 2 cdot n 1 nbsp von oben entspricht sie muss von einem Schritt zum nachsten lediglich um 2 erhoht werden void rasterCircle int x0 int y0 int radius int f 1 radius int ddF x 0 int ddF y 2 radius int x 0 int y radius setPixel x0 y0 radius setPixel x0 y0 radius setPixel x0 radius y0 setPixel x0 radius y0 while x lt y if f gt 0 y 1 ddF y 2 f ddF y x 1 ddF x 2 f ddF x 1 setPixel x0 x y0 y setPixel x0 x y0 y setPixel x0 x y0 y setPixel x0 x y0 y setPixel x0 y y0 x setPixel x0 y y0 x setPixel x0 y y0 x setPixel x0 y y0 x Herleitung der Fehlerglied Initialisierung Bearbeiten nbsp Den Schnittpunkt an dem die Kreislinie um 1 2 displaystyle tfrac 1 2 nbsp Pixel nach innen gekommen ist berechnet man nach der Kreisgleichung x 2 y 2 r 2 displaystyle x 2 y 2 r 2 nbsp oder y r 2 x 2 displaystyle y sqrt r 2 x 2 nbsp Am gefragten Punkt x 1 x 2 displaystyle x 1 x 2 nbsp soll gelten x 1 r 1 2 displaystyle x 1 r tfrac 1 2 nbsp also ergibt sich y 1 r 2 r 1 2 2 r 2 r 2 r 1 4 r 1 4 displaystyle y 1 sqrt r 2 left r tfrac 1 2 right 2 sqrt r 2 left r 2 r tfrac 1 4 right sqrt r tfrac 1 4 nbsp Da bis hierhin noch kein x displaystyle x nbsp Schritt stattgefunden haben soll und der Fehler bei y displaystyle y nbsp genau y 1 displaystyle y 1 nbsp Mal angepasst wurde ist das Fehlerglied mit y 0 y 1 1 2 y 1 y 1 2 displaystyle sum y 0 y 1 1 2 cdot y 1 y 1 2 nbsp zu initialisieren wobei y 1 2 displaystyle y 1 2 nbsp durch Runden zu r displaystyle r nbsp wird Beispiel Bearbeiten In der Abbildung rechts ist r 11 displaystyle r 11 nbsp und y 1 3 displaystyle y 1 3 nbsp abgerundet Das Fehlerglied bei y y 1 3 displaystyle y y 1 3 nbsp ist 1 3 5 9 displaystyle 1 3 5 9 nbsp Fehlerglied bei y 4 displaystyle y 4 nbsp ist 1 3 5 7 16 displaystyle 1 3 5 7 16 nbsp Wurde das Fehlerglied mit r 11 displaystyle r 11 nbsp initialisiert so findet der erste Vorzeichenwechsel und damit der erste x displaystyle x nbsp Schritt tatsachlich beim Ubergang von y 1 displaystyle y 1 nbsp zu y 1 1 displaystyle y 1 1 nbsp statt Zeichnen nicht vollstandiger Oktanten Bearbeiten Die obigen Implementierungen zeichnen immer nur komplette Oktanten bzw Kreise Wenn man nur einen bestimmten Kreisbogen von einem Winkel a displaystyle alpha nbsp bis zu einem Winkel b displaystyle beta nbsp zeichnen will muss man das so implementieren dass man sich die x displaystyle x nbsp und y displaystyle y nbsp Koordinaten dieser Endpunkte im Vorhinein berechnet wobei man unvermeidlich auf Trigonometrie oder Berechnung von Quadratwurzeln zuruckgreifen muss siehe Heron Verfahren Dann lasst man den Bresenham Algorithmus uber den kompletten Oktanten bzw Kreis laufen und setzt die Pixel aber nur dann wenn sie in den gewunschten Bereich fallen Nach Beendigung dieses Kurvenstucks kann man den Algorithmus vorzeitig abbrechen Ellipsen Bearbeiten Auch fur Ellipsen gibt es wieder mehrere mogliche Ansatze Man kann bei achsenparallelen Ellipsen von der entsprechenden Gleichung x 2 a 2 y 2 b 2 1 displaystyle frac x 2 a 2 frac y 2 b 2 1 nbsp wobei a displaystyle a nbsp und b displaystyle b nbsp die beiden Halbachsenlangen angeben ausgehen und dann ahnlich wie oben beim Kreis vorgehen Man kann aber auch durch Skalierung der gezeichneten x displaystyle x nbsp und y displaystyle y nbsp Werte und gegebenenfalls horizontaler bzw vertikaler Linienerweiterungen auf Basis des Kreisalgorithmus solche achsenparallele Ellipsen erzeugen Dabei benutzt man den Kreisalgorithmus mit der kleineren Ellipsenachse als Radius und addiert in der anderen Richtung einen Wert hinzu den man wiederum per Bresenham Linienalgorithmus ansteigend vom Pol zum Aquator ermitteln kann Da die Ellipse in die langere Achsenrichtung gestreckt werden muss setzt man dann nicht nur einzelne Pixel sondern muss gegebenenfalls eine Linie allerdings eine einfache horizontale oder vertikale vom vorherigen Punkt zum nachsten ziehen Eine allgemeine Ellipse kann man aus so einer achsenparallelen gewinnen indem man die komplette Grafik zusatzlich einer Scherung unterwirft Wieder benutzt man einen zusatzlichen Bresenham Linienalgorithmus um den Versatz in eine der Achsenrichtungen ansteigend zu ermitteln und ihn bei jeder zu zeichnenden Koordinate einzubeziehen Die Linienstarke einer mit dem Bresenham Algorithmus gezeichneten Ellipse lasst sich nicht so einfach berechnen wie fur einen Kreis weil sich der Umfang einer Ellipse nur naherungsweise mit einem Integral oder einer speziellen Reihenentwicklung berechnen lasst Kompakte Variante Bearbeiten Wie bei dem Algorithmus fur die Linie kann auch die Kreisvariante xy symmetrisch formuliert werden Damit kann also ein kontinuierlicher Viertelkreis gezeichnet werden was bei Ellipsen hilfreich ist void ellipse int xm int ym int a int b int dx 0 dy b im I Quadranten von links oben nach rechts unten long a2 a a b2 b b long err b2 2 b 1 a2 e2 Fehler im 1 Schritt do setPixel xm dx ym dy I Quadrant setPixel xm dx ym dy II Quadrant setPixel xm dx ym dy III Quadrant setPixel xm dx ym dy IV Quadrant e2 2 err if e2 lt 2 dx 1 b2 dx err 2 dx 1 b2 if e2 gt 2 dy 1 a2 dy err 2 dy 1 a2 while dy gt 0 while dx lt a fehlerhafter Abbruch bei flachen Ellipsen b 1 setPixel xm dx ym gt Spitze der Ellipse vollenden setPixel xm dx ym Der Algorithmus testet dabei immer einen Diagonalschritt und korrigiert diesen bei zu grosser Abweichung Die Schritte enden aber immer im nachsten Quadranten und dann wird bei flachen Ellipsen also fur den Fall b 1 displaystyle b 1 nbsp zu fruh abgebrochen In diesen Fallen ist also eine Erganzung notwendig Die Fehlervariable muss den 3 fachen Wertebereich Stellenanzahl Bits vom Radius Halbachsen aufweisen etwa 64 bit oder Gleitkommazahl Die Methode kann auch fur Kreise also fur den Fall a b r displaystyle a b r nbsp verwendet werden Die Vereinfachung indem etwa die Fehlervariable durch 2 r 2 displaystyle 2 cdot r 2 nbsp gekurzt wird fuhrt dann zu den oben gezeigten Kreisbeispielen Aus vier nahtlosen Viertelkreisen wird so ein kontinuierlicher Vollkreis wie es etwa bei Plottern erforderlich ist Weitere Verallgemeinerungen BearbeitenBereits im Jahr 1968 wurde die Idee publiziert den Bresenham Algorithmus fur die Digitalisierung von durch kubische Gleichungen beschriebenen Kurven zu verallgemeinern 5 Wirklich ausgefuhrt wurden die Details erst 1993 unter anderem von Pitteway 6 und unabhangig davon in einem Patent aus dem Jahre 1993 7 Eine Anwendung zur Strukturierung im Sub Mikrometer Bereich von durch rationale kubische Bezierkurven berandeten geometrischen Figuren fand das Verfahren in dem Lithografie Tool LION LV1 8 Siehe auch BearbeitenRasterung von Linien Rasterung von Kreisen Rasterung von PolygonenWeblinks Bearbeiten nbsp Commons Bresenham Algorithmus Sammlung von Bildern Videos und Audiodateien Rosetta Code Bitmap Bresenham s line algorithm Rosetta Code Bitmap Midpoint circle algorithm www javatpoint com Bresenham s Line Algorithm www javatpoint com MidPoint Circle Algorithm GeeksforGeeks Bresenham s Line Generation Algorithm GeeksforGeeks Mid Point Circle Drawing Algorithm Oliver Vornberger Institut fur Informatik Universitat Osnabruck Computergrafik National Institute of Standards and Technology U S Department of Commerce Bresenham s algorithm Alois Zingl Vienna Austria The Beauty of Bresenham s Algorithm Eine einfache Implementierung zum Zeichnen von Linien Kreisen Ellipsen und Bezierkurven Alois Zingl Vienna Austria Rasterizing curves Web Application in JavaScriptEinzelnachweise Bearbeiten J E Bresenham Algorithm for computer control of a digital plotter In IBM Systems Journal 4 1 1965 S 25 30 ISSN 0018 8670 cse iitb ac in PDF 223 kB englisch Bereits 1963 als Vortrag auf der ACM National Conference in Denver prasentiert Die erste Veroffentlichung der Grundidee fur die Kreisgenerierung findet sich in H B Keller J R Swenson Experiments on the lattice problem of Gauss PDF 222 kB In Math Comp 17 1963 S 223 230 Section 3 M L V Pitteway Algorithm for Drawing Ellipses or Hyperbolae with a Digital Plotter In Computer J 10 3 November 1967 S 282 289 englisch J R Van Aken An Efficient Ellipse Drawing Algorithm In CG amp A 4 9 September 1984 S 24 35 englisch F G Stockton XY Move Plotting In Communications of the ACM vol 4 no 6 April 1963 S 161 englisch R J Botting M L V Pitteway Cubic extension of a conic section algorithm In Computer Journal 11 1968 S 120 Fiaz Hussain Michael L V Pitteway Rasterizing the outlines of fonts PDF 162 kB In Electronic Publishing Band 6 1993 Nr 3 S 171 181 Patent EP0954618B1 Verfahren zur Generierung von ebenen technischen Kurven oder Konturen Angemeldet am 23 Dezember 1993 veroffentlicht am 29 September 2004 Erfinder Traugott Schulmeiss R Plontke LION LV1 Ein Lithographie System fur Integrierte Optik und Nanostrukturen In Jenaer Jahrbuch zur Technik und Industriegeschichte Band 9 2006 S 535 566 Abgerufen von https de wikipedia org w index php title Bresenham Algorithmus amp oldid 239388341