<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Algorithmus_von_Cohen-Sutherland</id>
	<title>Algorithmus von Cohen-Sutherland - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Algorithmus_von_Cohen-Sutherland"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Algorithmus_von_Cohen-Sutherland&amp;action=history"/>
	<updated>2026-05-31T06:02:16Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=Algorithmus_von_Cohen-Sutherland&amp;diff=388680&amp;oldid=prev</id>
		<title>2003:E0:F12:C2E3:B419:9B34:8A7A:DCEB: /* Implementierung */</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Algorithmus_von_Cohen-Sutherland&amp;diff=388680&amp;oldid=prev"/>
		<updated>2023-11-20T20:10:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Implementierung&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Der &amp;#039;&amp;#039;&amp;#039;Algorithmus von Cohen-Sutherland&amp;#039;&amp;#039;&amp;#039; ist ein [[Algorithmus]] zum Abschneiden ([[Clipping (Computergrafik)|Clipping]]) von Linien an einem [[Rechteck]]. Er ist nach seinen Erfindern [[Danny Cohen (Ingenieur)|Danny Cohen]] und [[Ivan Sutherland]] benannt. Der Algorithmus gilt als populärster, wenn auch nicht effizientester für seine Zwecke. Er eignet sich besonders für Fälle, in denen ein hoher Anteil der zu clippenden Linien inner- oder außerhalb des Rechtecks liegt.&lt;br /&gt;
&lt;br /&gt;
== Schritte ==&lt;br /&gt;
Zuerst werden jeweils für die beiden Endpunkte der zu zeichnenden Linie vier [[Flag (Informatik)|Flags]] ermittelt, die gesetzt werden, wenn sich der Endpunkt links des Rechtecks, rechts davon, darunter oder darüber befindet. Ist keines der Flags gesetzt, dann liegen beide Endpunkte innerhalb des Rechtecks, es ist kein Clipping notwendig und die Linie kann einfach gezeichnet werden.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Cohen.sutherland.png|mini|300px|Illustration Clipping Maske]]&lt;br /&gt;
&lt;br /&gt;
Wenn dieser triviale Fall nicht eintritt, werden im nächsten Schritt die einander entsprechenden Flags beider Endpunkte angesehen. Ist mindestens eines dieser Flags bei beiden Endpunkten gesetzt, so befindet sich die gesamte Linie außerhalb des Rechtecks und die Linie braucht nicht gezeichnet zu werden.&lt;br /&gt;
&lt;br /&gt;
Wenn auch dieser einfache Fall nicht auftritt, wird der Schnittpunkt einer (beliebigen) Rechteck-Seite mit dem Liniensegment berechnet und der überlappende Teil erneut getestet (und eventuell gekürzt), bis schließlich beide Punkte innerhalb des Rechtecks liegen.&lt;br /&gt;
&lt;br /&gt;
== Implementierung ==&lt;br /&gt;
Das folgende Programm gibt ein Beispiel einer [[Implementierung]] des Cohen-Sutherland-Algorithmus in C++, anhand dessen man die Funktionsweise gut nachvollziehen kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt; /*----------------------------------------------------------------------------------------&lt;br /&gt;
 Clipping der zwei X,Y Koordinaten einer Linie innerhalb eines zweidimensionalen&lt;br /&gt;
 Clipping Rechtecks XMin,YMin,XMax,YMax nach Cohen Sutherland.&lt;br /&gt;
&lt;br /&gt;
 Nach Ablauf der Funktion sind die Koordinaten der beiden Punkte so geclippt, dass sie&lt;br /&gt;
 innerhalb des Clipping Rechtecks liegen und der Linie entsprechen, die übrig bleibt,&lt;br /&gt;
 wenn man die außerhalb liegenden Teile abschneidet.&lt;br /&gt;
&lt;br /&gt;
 Falls kein Teil der Linie das Clipping Rechteck überstreicht, liefert die Funktion den&lt;br /&gt;
 Wert FALSE zurück.&lt;br /&gt;
&lt;br /&gt;
 x1,y1   : Koordinate des Anfangspunktes der Linie&lt;br /&gt;
 x2,y2   : Koordinate des Endpunktes     der Linie&lt;br /&gt;
 return  : FALSE Linie ist komplett geclippt und braucht nicht gezeichnet zu werden.&lt;br /&gt;
           TRUE  Die Koordinaten sind geclippt und die Linie kann jetzt gezeichnet werden&lt;br /&gt;
 ------------------------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
 #define CLIPLEFT  1  // Binär   0001&lt;br /&gt;
 #define CLIPRIGHT 2  //         0010&lt;br /&gt;
 #define CLIPLOWER 4  //         0100&lt;br /&gt;
 #define CLIPUPPER 8  //         1000&lt;br /&gt;
&lt;br /&gt;
 bool clipline(int &amp;amp;x1,int &amp;amp;y1,int &amp;amp;x2,int &amp;amp;y2)&lt;br /&gt;
 {&lt;br /&gt;
 int K1=0,K2=0;             // Variablen mit je 4 Flags für rechts, links, oben, unten.&lt;br /&gt;
 int dx,dy;&lt;br /&gt;
&lt;br /&gt;
  dx=x2-x1;                 // Die Breite der Linie vorberechnen für spätere Koordinaten Interpolation&lt;br /&gt;
  dy=y2-y1;                 // Die Höhe   der Linie vorberechnen für spätere Koordinaten Interpolation&lt;br /&gt;
&lt;br /&gt;
 // Die folgende Abfrage setzt die Flags CLIPLEFT,CLIPRIGHT,CLIPUPPER,CLIPLOWER, falls die Koordinate&lt;br /&gt;
 // auf einer oder zwei Seiten außerhalb des Clip Rechtecks liegt. Ein Punkt kann nicht gleichzeitig&lt;br /&gt;
 // rechts und links (bzw. oben und unten) außerhalb liegen, daher können nur maximal 2 Flags gesetzt sein.&lt;br /&gt;
 // Es gibt 9 Möglichkeiten. Davon sind 8 ungleich 0 und zeigen an, dass die Koordinate geclippt werden muss.&lt;br /&gt;
&lt;br /&gt;
 if(y1&amp;lt;YMin) K1 =CLIPLOWER;  // Ermittle, wo der Anfangspunkt außerhalb des Clip Rechtecks liegt.&lt;br /&gt;
 if(y1&amp;gt;YMax) K1 =CLIPUPPER;  // Es werden entweder CLIPLOWER oder CLIPUPPER und/oder CLIPLEFT oder CLIPRIGHT gesetzt&lt;br /&gt;
 if(x1&amp;lt;XMin) K1|=CLIPLEFT;   // Es gibt 8 zu clippende Kombinationen, je nachdem in welchem der 8 angrenzenden&lt;br /&gt;
 if(x1&amp;gt;XMax) K1|=CLIPRIGHT;  // Bereiche des Clip Rechtecks die Koordinate liegt.&lt;br /&gt;
&lt;br /&gt;
 if(y2&amp;lt;YMin) K2 =CLIPLOWER;  // Ermittle, wo der Endpunkt außerhalb des Clip Rechtecks liegt.&lt;br /&gt;
 if(y2&amp;gt;YMax) K2 =CLIPUPPER;  // Wenn keines der Flags gesetzt ist, dann liegt die Koordinate&lt;br /&gt;
 if(x2&amp;lt;XMin) K2|=CLIPLEFT;   // innerhalb des Rechtecks und muss nicht geändert werden.&lt;br /&gt;
 if(x2&amp;gt;XMax) K2|=CLIPRIGHT;&lt;br /&gt;
&lt;br /&gt;
 // Schleife nach Cohen Sutherland, die maximal zweimal durchlaufen wird&lt;br /&gt;
&lt;br /&gt;
  while(K1 || K2)    // muss wenigstens eine der Koordinaten irgendwo geclippt werden?&lt;br /&gt;
  {&lt;br /&gt;
&lt;br /&gt;
 // wenn beide Koordinaten entweder links, rechts, über oder unter dem Clipping Rechteck liegen&lt;br /&gt;
 // ist kein Teil der Linie sichtbar, daher ist keine weitere Berechnung notwendig.&lt;br /&gt;
 // Die geclippte Linie ist unsichtbar.&lt;br /&gt;
&lt;br /&gt;
    if(K1 &amp;amp; K2)      // logisches AND der beiden Koordinaten Flags ungleich 0?&lt;br /&gt;
      return FALSE;  // beide Punkte liegen jeweils auf der gleichen Seite außerhalb des Rechtecks&lt;br /&gt;
&lt;br /&gt;
    if(K1)                       // schnelle Abfrage, muss Koordinate 1 geclippt werden?&lt;br /&gt;
    {&lt;br /&gt;
      if(K1 &amp;amp; CLIPLEFT)          // ist Anfangspunkt links außerhalb?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        y1+=(XMin-x1)*dy/dx;     // berechne y1 durch lineare Interpolation, dx kann hier nie 0 sein&lt;br /&gt;
        x1=XMin;                 // setze x1 an den linken Rand des Clip Rechtecks&lt;br /&gt;
      }&lt;br /&gt;
      else if(K1 &amp;amp; CLIPRIGHT)    // ist Anfangspunkt rechts außerhalb?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        y1+=(XMax-x1)*dy/dx;     // berechne y1 durch lineare Interpolation, dx kann hier nie 0 sein&lt;br /&gt;
        x1=XMax;                 // setze x1 an den rechten Rand des Clip Rechtecks&lt;br /&gt;
      }&lt;br /&gt;
      if(K1 &amp;amp; CLIPLOWER)         // ist Anfangspunkt unterhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        x1+=(YMin-y1)*dx/dy;     // berechne x1 durch lineare Interpolation, dy kann hier nie 0 sein&lt;br /&gt;
        y1=YMin;                 // setze y1 an den unteren Rand des Clip Rechtecks&lt;br /&gt;
      }&lt;br /&gt;
      else if(K1 &amp;amp; CLIPUPPER)    // ist Anfangspunkt oberhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        x1+=(YMax-y1)*dx/dy;     // berechne x1 durch lineare Interpolation, dy kann hier nie 0 sein&lt;br /&gt;
        y1=YMax;                 // setze y1 an den oberen Rand des Clip Rechtecks&lt;br /&gt;
      }&lt;br /&gt;
      K1 = 0;                    // Erst davon ausgehen, dass der Punkt jetzt innerhalb liegt,&lt;br /&gt;
                                 // falls das nicht zutrifft, wird gleich korrigiert.&lt;br /&gt;
      if(y1&amp;lt;YMin) K1 =CLIPLOWER; // ermittle erneut, wo der Anfangspunkt jetzt außerhalb des Clip Rechtecks liegt&lt;br /&gt;
      if(y1&amp;gt;YMax) K1 =CLIPUPPER; // Für einen Punkt, bei dem im ersten Durchlauf z. B. CLIPLEFT gesetzt war,&lt;br /&gt;
      if(x1&amp;lt;XMin) K1|=CLIPLEFT;  // kann im zweiten Durchlauf z. B. CLIPLOWER gesetzt sein&lt;br /&gt;
      if(x1&amp;gt;XMax) K1|=CLIPRIGHT;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // muss hier nochmal getestet werden, sonst werden Linien, die über Eck außerhalb liegen nicht korrekt behandelt&lt;br /&gt;
    if(K1 &amp;amp; K2)      // logisches AND der beiden Koordinaten Flags ungleich 0?&lt;br /&gt;
      return FALSE;  // beide Punkte liegen jeweils auf der gleichen Seite außerhalb des Rechtecks&lt;br /&gt;
&lt;br /&gt;
    if(K2)                       // schnelle Abfrage, muss Koordinate 2 geclippt werden?&lt;br /&gt;
    {                            // ja&lt;br /&gt;
      if(K2 &amp;amp; CLIPLEFT)          // liegt die Koordinate links außerhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        y2+=(XMin-x2)*dy/dx;     // berechne y durch lineare Interpolation, dx kann hier nie 0 sein&lt;br /&gt;
        x2=XMin;                 // setze die x Koordinate an den linken Rand&lt;br /&gt;
      }&lt;br /&gt;
      else if(K2 &amp;amp; CLIPRIGHT)    // liegt die Koordinate rechts außerhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        y2+=(XMax-x2)*dy/dx;     // berechne y durch lineare Interpolation, dx kann hier nie 0 sein&lt;br /&gt;
        x2=XMax;                 // setze die x Koordinate an den rechten Rand&lt;br /&gt;
      }&lt;br /&gt;
      if(K2 &amp;amp; CLIPLOWER)         // liegt der Endpunkt unten außerhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        x2+=(YMin-y2)*dx/dy;     // berechne x durch lineare Interpolation, dy kann hier nie 0 sein&lt;br /&gt;
        y2=YMin;                 // setze die y Koordinate an den unteren Rand&lt;br /&gt;
      }&lt;br /&gt;
      else if(K2 &amp;amp; CLIPUPPER)    // liegt der Endpunkt oben außerhalb des Rechtecks?&lt;br /&gt;
      {                          // ja&lt;br /&gt;
        x2+=(YMax-y2)*dx/dy;     // berechne x durch lineare Interpolation, dy kann hier nie 0 sein&lt;br /&gt;
        y2=YMax;                 // setze die y Koordinate an den oberen Rand&lt;br /&gt;
      }&lt;br /&gt;
      K2 = 0;                    // Erst davon ausgehen, dass der Punkt jetzt innerhalb liegt,&lt;br /&gt;
                                 // falls das nicht zutrifft, wird gleich korrigiert.&lt;br /&gt;
      if(y2&amp;lt;YMin) K2 =CLIPLOWER; // ermittle erneut, wo der Endpunkt jetzt außerhalb des Clip Rechtecks liegt&lt;br /&gt;
      if(y2&amp;gt;YMax) K2 =CLIPUPPER; // Ein Punkt, der z. B. zuvor über dem Clip Rechteck lag, kann jetzt entweder&lt;br /&gt;
      if(x2&amp;lt;XMin) K2|=CLIPLEFT;  // rechts oder links davon liegen. Wenn er innerhalb liegt wird kein&lt;br /&gt;
      if(x2&amp;gt;XMax) K2|=CLIPRIGHT; // Flag gesetzt.&lt;br /&gt;
    }&lt;br /&gt;
  }             // Ende der while Schleife, die Schleife wird maximal zweimal durchlaufen.&lt;br /&gt;
  return TRUE;  // jetzt sind die Koordinaten geclippt und die gekürzte Linie kann gezeichnet werden&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [https://www.cs.helsinki.fi/group/goa/viewing/leikkaus/lineClip.html Beschreibung] (englisch)&lt;br /&gt;
* [https://pastehtml.com/view/awhhmf14g.html JavaScript-Implementierung] (mit Quelltext)&lt;br /&gt;
* [https://min.nl/cs426/classes/clip.html Java-Applet]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Algorithmus (Computergrafik)]]&lt;/div&gt;</summary>
		<author><name>2003:E0:F12:C2E3:B419:9B34:8A7A:DCEB</name></author>
	</entry>
</feed>