# Rasterung von Linien

Die Rasterung von Linien ist eine elementare Aufgabe der Computergrafik, bei der eine Linie auf das Punktraster einer Rastergrafik oder eines Raster-Grafikgeräts gezeichnet (gerastert) wird. Dazu werden diejenigen Punkte oder Pixel eingefärbt, die die ideale Strecke möglichst gut annähern.
Grundlegende Algorithmen rastern Linien nur einfarbig. Eine bessere Darstellung mit mehreren Farbabstufungen ergibt sich bei fortgeschrittenen Verfahren, die Antialiasing (Kantenglättung) unterstützen.
Da in der Computergrafik auch komplexere geometrische Figuren wie Polygone und beliebige Kurven häufig aus Liniensegmenten zusammengesetzt werden, bildet das Rastern von Linien gleichzeitig die Ausgangsbasis für deren Rasterung. Eine weitere Anwendung, bei der oft besonders viele Linien gezeichnet werden müssen, ist die Darstellung von Drahtgittermodellen.


## Einfarbige Rasterung
Bei der einfarbigen Rasterung werden Linien mit einer einzigen Vordergrundfarbe auf einen Hintergrund gezeichnet. Sie eignet sich für Geräte mit monochromer Darstellung, zum Beispiel Laserdrucker.
Die Anfangs- und Endpunkte der zu rasternden Linie werden üblicherweise in ganzzahligen Koordinaten angegeben, das heißt, sie liegen direkt auf den Punkten des Rasters. Deshalb werden die meisten Methoden nur für derartige Anfangs- und Endpunkte formuliert. Zur Rasterung dicker Linien gibt es mehrere Möglichkeiten, die auch für andere Kurven geeignet sind, siehe dazu den Artikel Rasterung.


### Einfache Methoden
Die einfachste Möglichkeit der Rasterung ist die direkte Umsetzung der Gleichung, die die Linie definiert. Wenn (xa, ya) der Anfangs- und (xe, ye) der Endpunkt der Linie ist, so erfüllen die Punkte auf der Linie die Geradengleichung 
  
    
      
        y
        =
        m
        (
        x
        −
        
          x
          
            a
          
        
        )
        +
        
          y
          
            a
          
        
      
    
    {\displaystyle y=m(x-x_{a})+y_{a}}
  
, wobei 
  
    
      
        
          m
          =
          
            
              
                Δ
                y
              
              
                Δ
                x
              
            
          
          =
          
            
              
                
                  y
                  
                    e
                  
                
                −
                
                  y
                  
                    a
                  
                
              
              
                
                  x
                  
                    e
                  
                
                −
                
                  x
                  
                    a
                  
                
              
            
          
        
      
    
    {\displaystyle \textstyle m={\frac {\Delta y}{\Delta x}}={\frac {y_{e}-y_{a}}{x_{e}-x_{a}}}}
  
 die Steigung ist.
Die Linie wird gezeichnet, indem in einer Schleife für jedes 
  
    
      
        x
      
    
    {\displaystyle x}
  
 von 
  
    
      
        
          x
          
            a
          
        
      
    
    {\displaystyle x_{a}}
  
 bis 
  
    
      
        
          x
          
            e
          
        
      
    
    {\displaystyle x_{e}}
  
 der entsprechende 
  
    
      
        y
      
    
    {\displaystyle y}
  
-Wert gemäß dieser Formel berechnet und auf die nächstliegende Ganzzahl gerundet wird. Das Pixel (x, y) wird dann eingefärbt.
Dieses Verfahren ist unnötig langsam, da innerhalb der Schleife eine Multiplikation ausgeführt wird, die auf den meisten Computern wesentlich mehr Rechenzeit als eine Addition oder Subtraktion erfordert. Eine schnellere Methode ergibt sich durch die Betrachtung der Differenz zwischen zwei aufeinanderfolgenden Schritten:

Demnach genügt es, mit (xa, ya) zu starten und bei jedem Schleifendurchlauf 
  
    
      
        y
      
    
    {\displaystyle y}
  
 um 
  
    
      
        m
      
    
    {\displaystyle m}
  
 zu erhöhen. Dieses Verfahren wird auch als Digital Differential Analyzer (DDA) bezeichnet.
Da die Rundung von 
  
    
      
        y
      
    
    {\displaystyle y}
  
 zur nächsten Ganzzahl dem Abrunden von 
  
    
      
        y
        +
        0
        
          ,
        
        5
      
    
    {\displaystyle y+0{,}5}
  
 entspricht, lässt sich auch eine zusätzliche Kontrollvariable verwenden, die mit 0,5 initialisiert wird und zu der bei jedem Schleifendurchlauf 
  
    
      
        m
      
    
    {\displaystyle m}
  
 addiert wird. Jedes Mal, wenn die Kontrollvariable den Wert 1,0 erreicht oder übersteigt, wird 
  
    
      
        y
      
    
    {\displaystyle y}
  
 um 1 erhöht und von der Kontrollvariable 1,0 abgezogen. Dadurch ist keine Rundung mehr nötig. Diese Methode kann so umformuliert werden, dass sie nur schnellere Ganzzahl-Operationen verwendet und sich elegant in Assemblersprache implementieren lässt. Dennoch ist weiterhin eine langsame Division (
  
    
      
        Δ
        y
        
          /
        
        Δ
        x
      
    
    {\displaystyle \Delta y/\Delta x}
  
) zu Beginn nötig, die bei kurzen Linien nicht durch die schnelle Schleife aufgewogen werden kann.


### Verallgemeinerung auf beliebige Richtungen
Die soeben beschriebenen Verfahren funktionieren nur bei Liniensteigungen zwischen 0 und 1, was einem Winkel von 0° bis 45° zur Horizontalen entspricht. Bei anderen Steigungen wird die Linie nicht oder falsch gezeichnet. Es genügt jedoch, einen Algorithmus nur für Steigungen zwischen 0 und 1 zu beschreiben, da andere Linien durch die Nutzung von Symmetrien korrekt dargestellt werden können. Dies geschieht durch folgende drei Veränderungen:

Es wird zwischen zwei Fällen unterschieden, je nachdem, ob 
  
    
      
        Δ
        x
        >
        Δ
        y
      
    
    {\displaystyle \Delta x>\Delta y}
  
 (betragsmäßig) oder umgekehrt. Im ersten Fall wird die Schleife wie bisher über 
  
    
      
        x
      
    
    {\displaystyle x}
  
 durchlaufen und im Schleifenrumpf 
  
    
      
        y
      
    
    {\displaystyle y}
  
 berechnet, ansonsten wird sie über 
  
    
      
        y
      
    
    {\displaystyle y}
  
 durchlaufen und 
  
    
      
        x
      
    
    {\displaystyle x}
  
 berechnet.
Innerhalb des Schleifenrumpfs wird 
  
    
      
        y
      
    
    {\displaystyle y}
  
 bzw. 
  
    
      
        x
      
    
    {\displaystyle x}
  
 nicht um 1 erhöht, sondern es wird abhängig vom Vorzeichen von 
  
    
      
        Δ
        y
      
    
    {\displaystyle \Delta y}
  
 bzw. 
  
    
      
        Δ
        x
      
    
    {\displaystyle \Delta x}
  
 der Wert +1 oder −1 addiert.
Falls 
  
    
      
        Δ
        x
        <
        0
      
    
    {\displaystyle \Delta x<0}
  
 bzw. 
  
    
      
        Δ
        y
        <
        0
      
    
    {\displaystyle \Delta y<0}
  
, so muss die Schleife rückwärts durchlaufen werden.
Für m wird der Betrag der Steigung verwendet 
  
    
      
        m
        =
        
          |
          
            
              
                Δ
                y
              
              
                Δ
                x
              
            
          
          |
        
      
    
    {\displaystyle m=\left|{\frac {\Delta y}{\Delta x}}\right|}
  

Durch die Anwendung dieser Verallgemeinerungen kann zur besseren Übersicht die folgende Tabelle erstellt werden:

Wobei i für m <= 1 Werte zwischen 0 und 
  
    
      
        Δ
        x
      
    
    {\displaystyle \Delta x}
  
 und für m > 1 Werte zwischen 0 und 
  
    
      
        Δ
        y
      
    
    {\displaystyle \Delta y}
  
 annimmt. Linien, die parallel zur X- oder Y-Achse sind, werden von dieser Tabelle ebenfalls abgedeckt und müssen nicht gesondert betrachtet werden. Die angegebene Richtung bezieht sich auf die nebenstehende Grafik unter der Annahme, dass x nach rechts größer wird und y nach oben wächst. x1 und y1 sind dabei die Koordinaten des Startpunktes einer Linie und x2 und y2 die Koordinaten des Endpunktes.
Ferner kann nur durch die Veränderung des Vorzeichens folgender Pseudocode erstellt werden, der alle acht beschriebenen Fälle abdeckt:

Wobei ceil() eine Funktion zum Aufrunden ist und drawPixel eine beliebige Funktion zum Setzen eines Pixels sein kann.


### Bresenham-Algorithmus
Die ältesten veröffentlichten Algorithmen zum Rastern von Linien stammen aus den frühen 1960er Jahren. Sie dienten der Steuerung von Digitalplottern, bei denen sich der Stift nur in festen Abständen horizontal, vertikal oder diagonal auf einem Raster bewegen konnte. Dazu gehörte auch der 1963 von Jack Bresenham präsentierte Bresenham-Algorithmus, der nur Ganzzahl-Berechnungen verwendet. Pitteway gab eine äquivalente Herleitung dieses Algorithmus an, die gegenüber Bresenhams eher geometrischen Formulierung den Vorteil hat, dass sie auch auf andere Kurven als Linien angewendet werden kann. Der resultierende Algorithmus, manchmal „Midpoint-Algorithmus“ genannt, ist genau der gleiche wie in Bresenhams Veröffentlichung.

Die Idee des Bresenham-Algorithmus besteht darin, bei jedem Schritt zwischen den beiden Pixeln zu wählen, die rechts („östlich“) und rechts oben („nordöstlich“) vom zuletzt gezeichneten Pixel liegen. Es wird dasjenige Pixel gewählt, das näher an der idealen Linie liegt. Dazu betrachtet man in der Midpoint-Formulierung den Mittelpunkt 
  
    
      
        M
      
    
    {\displaystyle M}
  
 zwischen den Pixeln 
  
    
      
        O
      
    
    {\displaystyle O}
  
 und 
  
    
      
        N
        O
      
    
    {\displaystyle NO}
  
: befindet sich 
  
    
      
        M
      
    
    {\displaystyle M}
  
 über der idealen Linie, so liegt 
  
    
      
        O
      
    
    {\displaystyle O}
  
 näher, ansonsten 
  
    
      
        N
        O
      
    
    {\displaystyle NO}
  
.
Um die Position von 
  
    
      
        M
      
    
    {\displaystyle M}
  
 gegenüber der Linie zu bestimmen, wird eine andere Form der Geradengleichung verwendet:

  
    
      
        F
        (
        x
        ,
        
        y
        )
        =
        a
        x
        +
        b
        y
        +
        c
        =
        Δ
        y
        ⋅
        x
        −
        Δ
        x
        ⋅
        y
        +
        c
        =
        0
      
    
    {\displaystyle F(x,\,y)=ax+by+c=\Delta y\cdot x-\Delta x\cdot y+c=0}
  
.
F(x, y) ist 0 für Punkte auf der Linie, positiv für Punkte unterhalb und negativ für Punkte oberhalb der Linie. Wenn in diese Gleichung die Koordinaten von 
  
    
      
        M
      
    
    {\displaystyle M}
  
 eingesetzt werden, so erhält man den Wert

  
    
      
        
          
            d
            
              i
            
          
          =
          F
          (
          
            x
            
              i
            
          
          +
          1
          ,
          
          
            y
            
              i
            
          
          +
          
            
              1
              2
            
          
          )
          =
          Δ
          y
          (
          
            x
            
              i
            
          
          +
          1
          )
          −
          Δ
          x
          (
          
            y
            
              i
            
          
          +
          
            
              1
              2
            
          
          )
          +
          c
        
      
    
    {\displaystyle \textstyle d_{i}=F(x_{i}+1,\,y_{i}+{\frac {1}{2}})=\Delta y(x_{i}+1)-\Delta x(y_{i}+{\frac {1}{2}})+c}
  
.
Je nach Vorzeichen dieser Kontrollvariable 
  
    
      
        
          d
          
            i
          
        
      
    
    {\displaystyle d_{i}}
  
 wird das Pixel 
  
    
      
        O
      
    
    {\displaystyle O}
  
 oder 
  
    
      
        N
        O
      
    
    {\displaystyle NO}
  
 gewählt.
Um einen effizienten Algorithmus zu erhalten, wird die Kontrollvariable inkrementell berechnet, also schrittweise erhöht. Ihre Änderung zwischen zwei aufeinanderfolgenden Schritten hängt davon ab, ob Pixel 
  
    
      
        O
      
    
    {\displaystyle O}
  
 oder 
  
    
      
        N
        O
      
    
    {\displaystyle NO}
  
 gewählt wurde. Für jeden dieser Fälle betrachtet man die Differenz zwischen dem Wert der Kontrollvariable beim übernächsten und beim nächsten Pixel:

  
    
      
        
          
            
              
                
                  
                    Δ
                    
                      O
                    
                  
                
              
              
                
                =
                
                  
                    d
                    
                      i
                      +
                      1
                    
                  
                  −
                  
                    d
                    
                      i
                    
                  
                  =
                  F
                  (
                  
                    x
                    
                      i
                    
                  
                  +
                  2
                  ,
                  
                  
                    y
                    
                      i
                    
                  
                  +
                  
                    
                      1
                      2
                    
                  
                  )
                  −
                  
                    d
                    
                      i
                    
                  
                  =
                  Δ
                  y
                
              
            
            
              
                
                  
                    Δ
                    
                      N
                      O
                    
                  
                
              
              
                
                =
                
                  
                    d
                    
                      i
                      +
                      1
                    
                  
                  −
                  
                    d
                    
                      i
                    
                  
                  =
                  F
                  (
                  
                    x
                    
                      i
                    
                  
                  +
                  2
                  ,
                  
                  
                    y
                    
                      i
                    
                  
                  +
                  
                    
                      3
                      2
                    
                  
                  )
                  −
                  
                    d
                    
                      i
                    
                  
                  =
                  Δ
                  y
                  −
                  Δ
                  x
                
              
            
          
        
      
    
    {\displaystyle {\begin{aligned}\textstyle \Delta _{O}&=\textstyle d_{i+1}-d_{i}=F(x_{i}+2,\,y_{i}+{\frac {1}{2}})-d_{i}=\Delta y\\\textstyle \Delta _{NO}&=\textstyle d_{i+1}-d_{i}=F(x_{i}+2,\,y_{i}+{\frac {3}{2}})-d_{i}=\Delta y-\Delta x\\\end{aligned}}}
  

Bei jedem Schritt wird die Kontrollvariable je nach gewähltem Pixel um 
  
    
      
        
          Δ
          
            O
          
        
      
    
    {\displaystyle \Delta _{O}}
  
 oder 
  
    
      
        
          Δ
          
            N
            O
          
        
      
    
    {\displaystyle \Delta _{NO}}
  
 erhöht. Ist 
  
    
      
        
          d
          
            i
          
        
        ≤
        0
      
    
    {\displaystyle d_{i}\leq 0}
  
, so liegt 
  
    
      
        M
      
    
    {\displaystyle M}
  
 oberhalb der Geraden, weshalb 
  
    
      
        O
      
    
    {\displaystyle O}
  
 gewählt wird, ansonsten 
  
    
      
        N
        O
      
    
    {\displaystyle NO}
  
.
Der Anfangswert der Kontrollvariable 
  
    
      
        d
      
    
    {\displaystyle d}
  
 lässt sich ebenfalls effizient berechnen, wenn 
  
    
      
        F
        (
        
          x
          
            a
          
        
        ,
        
        
          y
          
            a
          
        
        )
        =
        0
      
    
    {\displaystyle F(x_{a},\,y_{a})=0}
  
, der Startpunkt der Linie also genau auf einem Pixel liegt:

  
    
      
        
          
            d
            
              0
            
          
          =
          F
          
            (
            
              
                x
                
                  a
                
              
              +
              1
              ,
              
              
                y
                
                  a
                
              
              +
              
                
                  1
                  2
                
              
            
            )
          
          =
           
          
            
              
                
                  Δ
                  y
                  ⋅
                  
                    x
                    
                      a
                    
                  
                  −
                  Δ
                  x
                  ⋅
                  
                    y
                    
                      a
                    
                  
                  +
                  c
                
                ⏟
              
            
            
              =
              F
              (
              
                x
                
                  a
                
              
              ,
              
              
                y
                
                  a
                
              
              )
              =
              0
            
          
          
          +
          
          Δ
          y
          −
          
            
              
                Δ
                x
              
              2
            
          
          =
          Δ
          y
          −
          
            
              
                Δ
                x
              
              2
            
          
        
      
    
    {\displaystyle \textstyle d_{0}=F\left(x_{a}+1,\,y_{a}+{\frac {1}{2}}\right)=\ \underbrace {\Delta y\cdot x_{a}-\Delta x\cdot y_{a}+c} _{=F(x_{a},\,y_{a})=0}\,+\,\Delta y-{\frac {\Delta x}{2}}=\Delta y-{\frac {\Delta x}{2}}}
  

Um die Division durch 2 zu beseitigen, werden alle Werte der Kontrollvariable verdoppelt; das entscheidende Vorzeichen bleibt dabei erhalten. Damit lässt sich der Bresenham-Algorithmus für Linien mit einer Steigung zwischen 0 und 1 in nachfolgendem Pseudocode ausdrücken. Der Algorithmus benötigt nur Additionen innerhalb der Schleife; die einfachen Multiplikationen außerhalb der Schleife lassen sich ebenfalls durch eine Addition realisieren.

Eine andere Interpretation des Algorithmus geht von der Feststellung aus, dass die gerasterte Linie 
  
    
      
        m
        =
        Δ
        x
        −
        Δ
        y
      
    
    {\displaystyle m=\Delta x-\Delta y}
  
 Horizontal- und 
  
    
      
        n
        =
        Δ
        y
      
    
    {\displaystyle n=\Delta y}
  
 Diagonalschritte enthält. Um diese beiden Schritttypen zu „mischen“, wird bei jedem Schritt entweder 
  
    
      
        m
      
    
    {\displaystyle m}
  
 von der Kontrollvariable abgezogen oder 
  
    
      
        n
      
    
    {\displaystyle n}
  
 addiert. Es wird der entsprechende Schritttyp ausgeführt, bei dem der resultierende Betrag der Kontrollvariable geringer ist. Dies wird auch aus obiger Grafik deutlich, bei der die Kontrollvariable stets so nahe wie möglich an der Nullachse liegt. Thompson beschrieb einen Algorithmus nach dieser Formulierung 1964, auf die Wahl des korrekten Anfangswerts der Kontrollvariable ging er allerdings nicht ein. Noch vor Bresenham hatte Fred Stockton 1963 einen Algorithmus zur Rasterung von Linien veröffentlicht, der ebenfalls nur Ganzzahl-Berechnungen verwendet, aber unnötig kompliziert ist.
Linien, deren Endpunkte mit nicht-ganzzahligen Koordinaten angegeben werden, lassen sich ebenfalls mit dem Bresenham-Algorithmus rastern. Hierzu muss der Anfangswert der Kontrollvariable gemäß ihrer ursprünglichen Definition berechnet werden; pauschale Vereinfachungen sind nicht möglich. Der restliche Algorithmus bleibt gültig.


### Pixelreihen
Obwohl der Bresenham-Algorithmus recht effizient ist, zeichnet er nur ein Pixel pro Schleifendurchlauf und benötigt dazu eine Addition. Eine Methode, die alle Pixel einer „Reihe“ – das heißt, Pixel mit gleicher y-Koordinate – auf einmal zeichnet, wurde zum ersten Mal von Reggiori entwickelt. Reihen mit nur einem Pixel wurden dabei gesondert behandelt. Später stellte Bresenham einen allgemeineren Algorithmus vor, der ohne Tests für diesen Spezialfall auskam.
Bei Bresenhams Pixelreihen-Algorithmus wird nicht 
  
    
      
        x
      
    
    {\displaystyle x}
  
 schrittweise erhöht, sondern 
  
    
      
        y
      
    
    {\displaystyle y}
  
. Für jedes 
  
    
      
        y
      
    
    {\displaystyle y}
  
 wird das Ende der aktuellen Reihe berechnet. Das geschieht durch Betrachtung der Punkte, in denen die ideale Linie eine durch den Mittelpunkt zwischen zwei vertikal benachbarten Pixeln verlaufende Horizontale schneidet. Das Ende der Pixelreihe ist der abgerundete Wert der x-Koordinate dieses Schnittpunkts:

Die Endpunkt-Koordinaten der Pixelreihen lassen sich auch inkrementell berechnen. Da hier bei bestimmten Steigungen einige Punkte falsch berechnet werden können, nutzt der Algorithmus eine Symmetrie zur Geraden der Steigung ½ aus.
In der innersten Schleife von Bresenhams neuem Algorithmus sind keine Additionen erforderlich, denn alle Pixel einer Reihe werden auf einmal eingefärbt. Allerdings ist eine Division zur Initialisierung erforderlich. Fung ersetzte sie durch ein Suchverfahren und nahm einige weitere Optimierungen vor.


### N-Schritt-Verfahren
Eine andere, erstmals von Wu und Rokne vorgestellte Möglichkeit der Rasterung besteht darin, Schritte von mehreren Pixeln entlang der x-Achse zu machen und alle dazwischen liegenden Pixel der Linie auf einmal einzufärben. Dazu wird zwischen den verschiedenen möglichen „Pixelmustern“ ausgewählt. Bresenhams Algorithmus kann als Spezialfall dieser Methode angesehen werden, bei dem nur Schritte von je einem Pixel gemacht werden und bei dem nur zwischen zwei „Mustern“ (Pixel rechts oder rechts oben) gewählt wird.
Um zwischen den beim Doppelschrittverfahren vier möglichen Mustern unterscheiden zu können, wird zunächst die letzte Pixelspalte des Musters betrachtet. Befindet sich das zu rasternde Pixel unten oder oben, lässt sich trivial auf das Muster 1 beziehungsweise 4 schließen. Befindet sich das Pixel hingegen in der Mitte, so ist ein zusätzlicher Test der mittleren Spalte nötig, um zwischen den Mustern 2 und 3 wählen zu können.
Diese Tests werden dadurch vereinfacht, dass bei einer Steigung m ≤ ½ Muster 4 und bei m ≥ ½ Muster 1 nicht auftreten kann. Ähnlich wie beim Bresenham-Algorithmus lässt sich auch beim Doppelschrittverfahren die Kontrollvariable für die Tests inkrementell berechnen. Im Endeffekt kommt der Algorithmus nur mit Additionen und einer einfachen Multiplikation, die sich mit einer schnellen Bitverschiebung realisieren lässt, aus.
Es wurden auch Algorithmen für Dreifach- und Vierfachschritte entwickelt, die nach dem gleichen Prinzip arbeiten, aber erheblich komplizierter und länger sind. Ein anderer Vierfachschritt-Algorithmus verwendet eine etwas abweichende Formulierung, die systematisch die Bedingungen untersucht, unter denen ein bestimmtes Muster auftritt, und die sich auf beliebig viele Schritte verallgemeinern lässt.


### Bidirektionale Rasterung
Um die Geschwindigkeit der Rasterung weiter zu erhöhen, liegt es nahe, die Linie bidirektional, also gleichzeitig vom Anfangs- und vom Endpunkt aus bis zum Mittelpunkt zu zeichnen. Hierbei läuft die Schleife nur über eine Hälfte der Linie; bei jedem Schritt werden die beiden beteiligten Pixel auf jeder Seite der Linie eingefärbt. Sowohl der Bresenham-Algorithmus als auch andere Verfahren lassen sich so umändern.
Dabei muss aber beachtet werden, dass die mit den normalen Methoden gerasterte Linie nicht unbedingt in sich punktsymmetrisch ist. Das liegt daran, dass es bei der Rasterung uneindeutige Situationen gibt, in denen die ideale Linie genau durch den Mittelpunkt zweier vertikal benachbarter Pixel verläuft, zwischen denen beliebig gewählt werden kann. Der oben aufgeführte Bresenham-Algorithmus zum Beispiel wählt in solchen Fällen (
  
    
      
        d
        =
        0
      
    
    {\displaystyle d=0}
  
) immer das Pixel mit kleinerer y-Koordinate aus. Beim Zeichnen von rechts nach links hingegen wird, bedingt durch die Nutzung der Symmetrie, das Pixel mit größerer y-Koordinate ausgewählt. Wenn die Linie bidirektional oder von rechts nach links gezeichnet wird, kann sich daher das Erscheinungsbild gegenüber dem normalen Algorithmus ändern, sofern nicht separat auf die uneindeutigen Fälle getestet wird.


### Sonstige Techniken
Periodizität
Es lässt sich beweisen, dass sich die Werte der Kontrollvariable beim Bresenham-Algorithmus a-mal wiederholen, wobei a der größte gemeinsame Teiler von 
  
    
      
        Δ
        x
      
    
    {\displaystyle \Delta x}
  
 und 
  
    
      
        Δ
        y
      
    
    {\displaystyle \Delta y}
  
 ist. Das bedeutet, dass die Werte der Kontrollvariable nur für einen Teil der Linie berechnet werden müssen und dann auf die anderen Teile angewandt werden können. Hierzu muss allerdings der ggT berechnet werden. Diese Methode lässt sich auch mit der bidirektionalen Rasterung kombinieren.

Hierarchische Pixelreihen
Die Länge der Pixelreihen in einer gerasterten Linie folgt einem bestimmten Muster. Rosenfeld bewies, dass die Länge aller Pixelreihen, außer möglicherweise der ersten und der letzten, höchstens um ein Pixel abweicht. Er stellte außerdem fest, dass die Folge der Pixelreihen selbst diese Struktur aufweist, ebenso wie die Folge dieser Folgen, und so weiter. Gerasterte Linien sind also hierarchisch aus Reihen „n-ter Ordnung“ aufgebaut, die jeweils nur bestimmte Längen annehmen können. Stephenson beschrieb praktikable Algorithmen, die eine Linie ausgehend von Reihen beliebig hoher Ordnung zeichnen können, sowie einen rekursiven Algorithmus, der von der Reihe höchstmöglicher Ordnung ausgeht. Dadurch wird sowohl der Bresenham-Algorithmus als auch der Pixelreihen-Algorithmus verallgemeinert. Der Algorithmus für Reihen „nullter Ordnung“, bei dem die Pixelreihen ignoriert werden, entspricht dem gewöhnlichen Bresenham-Algorithmus.
Strukturelle Algorithmen
Es wurden noch weitere Algorithmen zur Rasterung vorgeschlagen, die aber nicht inkrementell arbeiten, sondern sich die strukturellen Eigenschaften der gerasterten Linien direkt zunutze machen. Sie basieren auf Überlegungen aus der Bildverarbeitung oder digitalen Geometrie und erreichen in der Praxis nicht die Geschwindigkeit der herkömmlichen Methoden, da sie Zeichenketten manipulieren oder andere langsame Operationen erfordern.
Brons’ Algorithmus etwa repräsentiert die gerasterte Linie durch eine Zeichenkette aus Nullen und Einsen, wobei 0 für einen Horizontal- und 1 für einen Diagonalschritt steht. Der Algorithmus geht von einer Zeichenkette aus, die eine erste Annäherung an die Linie darstellt, fasst Folgen von Nullen und Einsen zusammen und verteilt sie gleichmäßig. Der gleiche Prozess wird auf die resultierende Folge angewandt. Das wiederholt sich so lange, bis keine Verbesserung mehr erzielt werden kann. Die so gerasterte Linie ist allerdings nicht optimal; um die gleiche Linie wie beim Bresenham-Algorithmus zu erhalten, sind zusätzliche Anpassungen nötig.


### Eigenschaften und Vergleich
Obwohl zahlreiche Algorithmen entdeckt wurden, die weniger komplex als der Bresenham-Algorithmus sind, ist deren praktischer Geschwindigkeitsvorteil gering. Das liegt daran, dass die Befehle zum Einfärben von Pixeln auf heutiger Hardware verglichen mit der Ausführung des Rasteralgorithmus selbst sehr langsam sind. Einige Grafikkarten stellen jedoch etwas schnellere Funktionen zum Einfärben mehrerer Pixel auf einmal bereit, etwa die rectwrite-Funktion auf SGI-Systemen. Dies ist von Vorteil für Pixelreihen-Algorithmen, die so eine Reihe schnell auf einmal zeichnen können.
Die Ausführungsgeschwindigkeit der verschiedenen Algorithmen hängt von der Länge der zu rasternden Linie ab. Algorithmen, deren innere Schleife schnell ist, die aber viel Zeit zur Initialisierung benötigen, können nur bei langen Linien einen Geschwindigkeitsvorteil verbuchen. Es wurde daher vorgeschlagen, in Abhängigkeit von der Länge der Linie den jeweils effizientesten Algorithmus zu wählen. Eine statistische Analyse der Linienlängen in verschiedenen Anwendungen wie der Darstellung von Drahtgittermodellen, Kurvensegmenten und Schriftzeichen kam zu dem Ergebnis, dass knapp drei Viertel aller gerasterten Linien weniger als zehn Pixel lang waren. Demnach lohnt es sich, für den Spezialfall der kurzen Linien zu optimieren. Algorithmen, die eher bei der Rasterung langer Linien vorteilhaft sind, eignen sich besser für Ausgabegeräte mit höherer Auflösung als Bildschirme und damit im Durchschnitt längeren Linien, etwa Laserdrucker. Bei manchen Algorithmen hängt die Geschwindigkeit außerdem von der Steigung der Linie ab – Pixelreihen-Algorithmen zum Beispiel sind weniger effizient bei diagonalen Linien, da hier nur ein Pixel pro Reihe gezeichnet werden kann.
Ein anderer Faktor bei der Wahl eines Algorithmus ist die Programmlänge. Hersteller von Grafikprozessoren, die die Rasterung direkt auf Hardwareniveau implementieren und daher Platz sparen müssen, bevorzugen kurze Algorithmen wie den Bresenham-Algorithmus. Bei Softwareimplementierungen ist dieser Faktor weniger kritisch.


### Probleme
Alle Algorithmen zur einfarbigen Rasterung können in bestimmten Situationen Probleme verursachen:
Unterschiedliche Helligkeit
Beim Rastern von Linien gleicher Länge, aber unterschiedlicher Steigung wird nicht unbedingt die gleiche Anzahl von Pixeln eingefärbt. Im nebenstehenden Beispiel ist die diagonale Linie länger als die waagrechte, dennoch werden in beiden Fällen die gleiche Anzahl von Pixeln eingefärbt. Dies führt dazu, dass beide Linien auf dem Ausgabegerät unterschiedlich hell erscheinen. Bei monochromen Geräten kann dieses Problem nicht umgangen werden.
Linienstile
Die Nutzung der Symmetrie zum Rastern von Linien mit beliebigem Anfangs- und Endpunkt kann unerwünschte Effekte verursachen, falls bestimmte Linienstile verwendet werden. Wenn gestrichelte oder gepunktete Linien gezeichnet werden sollen, so fängt das jeweilige Muster beim Anfangspunkt der Linie an. Solche Linien werden anders gezeichnet, wenn Anfangs- und Endpunkt vertauscht werden. Sofern die Striche eines Linienstils durch eine bestimmte Anzahl einzufärbender Pixel definiert sind, variiert außerdem die tatsächliche Strichlänge je nach Steigung.
Clipping
Das Clipping ist eine Operation, die die Rasterung auf einen bestimmten, meist rechteckigen Bereich einschränkt. Dies geschieht, indem vor der Rasterung die Anfangs- und Endpunkte der zu rasternden Linie zu den Kanten des rechteckigen Bereichs hin verschoben werden, sofern sie herausragen. Im Allgemeinen führt das dazu, dass die Koordinaten dieser Punkte nicht mehr ganzzahlig sind. Wenn diese Koordinaten dennoch gerundet werden, ergibt sich eine Linie mit anderer Steigung und damit möglicherweise auch anderem Erscheinungsbild. Um dies zu vermeiden, sind zusätzliche Tests nach dem Clipping nötig. Der Bresenham-Algorithmus kann auch mit einem Clipping-Algorithmus kombiniert werden.


## Antialiasing
Das größte Problem bei einfarbig gerasterten Linien ist ihr im Allgemeinen „treppenartiges“ Aussehen, auch Treppeneffekt genannt. Auf Grafikgeräten, die zur Darstellung mehrerer Helligkeitsstufen fähig sind, kann diesem Effekt durch Antialiasing entgegengewirkt werden. Hierbei wird die zu rasternde Linie üblicherweise nicht mehr als eindimensionale Strecke, sondern als zweidimensionale Form, im einfachsten Fall als Rechteck mit gewünschter Dicke, betrachtet. Für die Rasterung müssen die Farbwerte der Pixel, die in der Nähe des Rechtecks liegen, ermittelt werden.


### Methode von Gupta und Sproull
Beim Antialiasing lässt sich der Farbwert eines Pixels ermitteln, indem ein so genannter Glättungskern oder Rekonstruktionsfilter über das Pixel gelegt wird. Gupta und Sproull schlugen als Glättungskern einen Kegel mit einem Radius von einem Pixel vor. Der Farbwert des Pixels ist proportional zum Volumen des Kegelteils, der die zu rasternde Linie (hier also das zu rasternde Rechteck) überlappt. Dieses Volumen wiederum hängt von der Distanz 
  
    
      
        D
      
    
    {\displaystyle D}
  
 zwischen der Mittellinie des Rechtecks und dem Pixel ab.

Der Gupta-Sproull-Algorithmus basiert auf dem Bresenham-Algorithmus, berechnet aber zusätzlich 
  
    
      
        D
      
    
    {\displaystyle D}
  
 für jedes der Pixel, deren Glättungskern die Linie überlappt. Bei einer Linienstärke von einem Pixel sind dies maximal drei Pixel pro Spalte. Aus Effizienzgründen werden die Distanzen nicht exakt berechnet, sondern nur 24 mögliche Distanzen betrachtet. Die Intensitätswerte, die diesen Distanzen entsprechen, wurden im Voraus berechnet und in einer Tabelle (Lookup-Tabelle) gespeichert, sodass sie schnell abgerufen werden können.
Die Linienenden müssen gesondert behandelt werden, da hier mehr als drei Pixel, insgesamt bis zu sechs, beteiligt sind. Die Intensitäten dieser Pixel hängen von der Steigung der Linie ab. Sie werden für einige Steigungen im Voraus berechnet und auch hier wieder in einer Tabelle gespeichert. Es sind auch andere Formen für die Linienenden denkbar, zum Beispiel abgerundete Endpunkte; die Intensitäten der beteiligten Pixel ändern sich dementsprechend.
Der Gupta-Sproull-Algorithmus eignet sich für Linien mit beliebiger Linienstärke, wobei sich allerdings auch die Lookup-Tabelle ändert. Bei einer Linienstärke größer als einem Pixel muss beachtet werden, dass möglicherweise die Glättungskerne von mehr als drei Pixeln die Linie überlappen.
Ein Problem des Gupta-Sproull-Algorithmus ist, dass gerasterte Linien oftmals an verschiedenen Stellen unterschiedlich hell zu sein scheinen. Dieses „seilartige“ Aussehen ist vor allem auf die Unzulänglichkeit des Kegels als Glättungskern zurückzuführen.
Eine optimierte Variante des Gupta-Sproull-Algorithmus kann wie folgt in Pseudocode notiert werden:

DrawLineChen(x1, y1, x2, y2)
{
    x = x1;
    y = y1;
    dx = x2 − x1;
    dy = y2 − y1;
    d = 2 * dy − dx; // discriminator
    D = 0; // Euklidischer Abstand des Punkts (x, y) von der Linie (mit Vorzeichen)
    length = sqrt(dx * dx + dy * dy); // Euklidischer Abstand zwischen den Punkten (x1, y1) und (x2, y2)
    sin = dx / length;
    cos = dy / length;
    while (x <= x2)
    {
        IntensifyPixel(x, y − 1, D + cos);
        IntensifyPixel(x, y, D);
        IntensifyPixel(x, y + 1, D − cos);
        x = x + 1;
        if (d <= 0)
        {
            D = D + sin;
            d = d + 2 * dy;
        }
        else
        {
            D = D + sin − cos;
            d = d + 2 * (dy − dx);
            y = y + 1;
        }
    }
}

Die Funktion IntensifyPixel(x, y, r) verwendet eine radiale Linientransformation und setzt die Intensität des Pixel (x, y) mit dem Wert eines kubischen Polynoms, das vom Abstand r des Pixels von der Linie abhängt.


### Methode von Wu
Wu wählte einen anderen Ansatz für das Antialiasing, der nicht auf der Nutzung eines bestimmten Glättungskerns, sondern auf einem Fehlermaß basiert. Die Methode ist in der Grundform nur auf ideale, unendlich dünne Linien anwendbar.
Beim Bresenham-Algorithmus wird versucht, eine Annäherung an die ideale Linie zu erreichen, indem der „Fehler“, also der Abstand zwischen der idealen Linie und zwei möglichen Pixeln minimiert wird. Wu schlug ein anderes Fehlermaß vor, das auf beliebige Kurven anwendbar ist. Der Fehler im Sinne dieses Fehlermaßes lässt sich vollständig beseitigen, sofern beliebige Farbwerte zugelassen werden. Dazu müssen die beiden Pixel, die direkt über und unter der idealen Linie liegen, Farbwerte proportional zur vertikalen Distanz zur idealen Linie annehmen.
Für Linien gab Wu einen besonders schnellen Algorithmus an. Dank trickreicher Ganzzahl-Operationen benötigt er nur eine Kontrollvariable, die schrittweise verändert wird und sowohl die Position der zwei beteiligten Spaltenpixel als auch deren Intensität bestimmt.


### Sonstige Techniken
Eine andere Möglichkeit des Antialiasing ist die ungewichtete Flächenabtastung (unweighted area sampling). Hierbei entspricht der Farbwert eines Pixels dem Flächenanteil der Linie innerhalb eines Quadrats von einem Pixel Kantenlänge um das betreffende Pixel, der Glättungskern ist in diesem Fall also ein Würfel. Für diese Methode sind schnelle Algorithmen entwickelt worden. Nachteilig an der ungewichteten Flächenabtastung ist das verschwommene Erscheinungsbild der Linien.
Wie auch bei der einfarbigen Rasterung kann die Struktur der Pixelreihen dazu genutzt werden, die Geschwindigkeit der Rasterung zu erhöhen.
Neben den speziell für Linien optimierten Antialiasing-Verfahren können auch allgemeine Verfahren genutzt werden, etwa Whitteds Methode, bei der eine hochaufgelöste Rastergrafik als „Pinsel“ entlang der Linie bewegt wird.


## Besondere Optimierungen
Die Rasterung von Linien lässt sich durch Näherungsverfahren, Nutzung von oder direkte Implementierung in Hardware sowie Parallelisierung noch effizienter gestalten. Dies ist erforderlich, wenn eine sehr große Zahl von Linien in Echtzeit gerastert werden muss.


### Näherungsverfahren
Boyer und Bourdin stellten ein Näherungsverfahren vor, das immer die direkt unter der idealen Linie liegenden Pixel einfärbt. Eine derartig gerasterte Line verfügt über einige besondere Eigenschaften, die ausgenutzt werden können. So etwa sind in diesem Fall nicht nur die Bresenham-Kontrollvariable, sondern auch die Linienabschnitte periodisch. Zusammen mit weiteren Optimierungen ergibt sich ein Algorithmus, der insbesondere bei längeren Linien erheblich schneller als die präzisen Verfahren ist. Eine Qualitätsverschlechterung ist bei Linien mit sehr geringer Steigung feststellbar.


### Parallelisierung
Eine einfache Methode zur Parallelisierung der einfarbigen Rasterung lässt verschiedene Algorithmen parallel laufen, die – jeweils etwas verschoben – mehrere Pixel in bestimmten Abständen zeichnen. Eine andere Möglichkeit besteht darin, die Linie in mehrere ungefähr gleich große Teile aufzuteilen, die jeweils einem Prozessor zur Rasterung zugewiesen werden. Jeder Teil wird mit Hilfe des Bresenham-Algorithmus gerendert; das Hauptproblem ist die Berechnung der korrekten Anfangswerte der Variablen. Weiterhin ist es möglich, mehrere Prozessoren die Endpunkt-Koordinaten der Reihen bei Bresenhams Pixelreihen-Algorithmus berechnen zu lassen. Auch für massiv parallel arbeitende Vektorrechner mit über 1000 Prozessoren wurden Algorithmen vorgestellt. Jedes Pixel der Rastergrafik wird dabei einem Prozessor zugewiesen, der entscheidet, ob dieses Pixel eingefärbt werden soll oder nicht.
Um die langsamen Speicherzugriffe bei der Rasterung zu beschleunigen, wurden spezielle Speicherarchitekturen entwickelt, etwa solche, bei denen der Speicher in Zellen unterteilt wird, in denen unabhängig voneinander ein Teil der Linie gezeichnet werden kann. Auch die Rasterung mit Antialiasing kann durch Hardware unterstützt werden.


## Verwandte Probleme
Linien können nicht nur wie normalerweise üblich 8-verbunden, sondern auch 4-verbunden (4-connected) gerastert werden. Das bedeutet, dass keine Diagonal-, sondern nur noch Horizontal- und Vertikalschritte erlaubt sind. Wenn man sich das Punktraster in Quadrate unterteilt denkt, so werden hierbei alle Quadrate, die von der Linie überlappt werden, ausgewählt. Eine Verallgemeinerung dieser Technik auf drei Dimensionen findet bei Voxelgittern, einer Beschleunigungstechnik des Raytracing, Verwendung. Sie dient der Bestimmung der Voxel, durch die ein Strahl beim Raytracing wandert.
Bei gerasterten Linien sind die diagonalen Pixelschritte möglichst gleichmäßig verteilt. Algorithmen zum Rastern von Linien lassen sich daher auch dazu verwenden, Punkte mit ganzzahligen Koordinaten gleichmäßig in einem bestimmten Intervall zu verteilen. Mögliche Anwendungen sind die lineare Interpolation oder das Downsampling in der Signalverarbeitung.  Weitere Parallelen ergeben sich zum Euklidischen Algorithmus sowie Farey-Reihen und einigen anderen mathematischen Konstrukten.


## Siehe auch
Bresenham-Algorithmus
Rasterung von Kreisen
Rasterung von Polygonen


## Literatur
James D. Foley u. a.: Computer Graphics: Principles and Practice in C. Addison-Wesley, Reading (Massachusetts) 1995, ISBN 978-0-201-84840-3.  (Behandelt den Bresenham-Algorithmus, Probleme bei der Rasterung sowie Gupta-Sproull-Antialiasing)


## Weblinks
Rosetta Code: Bitmap/Bresenham's line algorithm
www.javatpoint.com: Bresenham's Line Algorithm
GeeksforGeeks: Bresenham’s Line Generation Algorithm
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 Bézierkurven
Alois Zingl, Vienna, Austria: Rasterizing curves - Web Application in JavaScript
Rasterung von Linien, Kreisen, Ellipsen (Uni Magdeburg, Institut für Simulation und Graphik) – Java-Applet zum Nachvollziehen des Bresenham-Algorithmus
Project: Line Statistics (George Mason University Computer Graphics Lab) – Untersuchung zur Verteilung von Linienlängen und -steigungen (englisch)


## Einzelnachweise