Difference between revisions of "TU Wien:Einführung in Visual Computing VU (W. Kropatsch, W. Purgathofer, R. Sablatnig)/Übungen SЅ12 PovRay"

From VoWi
Jump to navigation Jump to search
m (hat „Foobar“ nach „TU Wien:Einführung in Visual Computing VU (W. Kropatsch, W. Purgathofer, R. Sablatnig)/Uebungen SЅ12 Ausarbeitung“ verschoben: moved by 194.24.138.1, see that IPs block log entry)
(Version von 184.18.151.21 wiederhergestellt.)
Line 1: Line 1:
 +
== PovRay ==
  
 +
Nicht direkt kopieren, nur als Referenz verwenden!
 +
 +
Abschreiben führt zu negativer Bewertung!
 +
 +
=== Brucke (5 Punkte) ===
 +
 +
zylinder.mac
 +
 +
<pre>
 +
#macro DreiPunkteZylinder(h, P, w, rOffset)
 +
//Berechnet aus 3 Punkten deren gemeinsamen Kreis und zeichnet ihn als einen Zylinder
 +
 +
//INPUT P      ... der zweite Punkt in 2D, der das Kreis definiert. Der erste Punkt ist immer (0,0).
 +
//      h      ... dient zur Berechnung des dritten Punktes des Kreises: es die maximale Hoehe ueber der
 +
//                  Gerade, die (0,0) mit P verbindet, die das Kreis erreicht.
 +
//      w      ... Hoehe des gezeichneten Zylinders
 +
//      rOffset ... Versatz des Zylinder Radius, soll zum berechneten Radius dazugezaehlt werden
 +
//OUTPUT hat den Praefix result_DreiPunkteZylinder_
 +
//      px, py ... Zentrum des Kreises
 +
//      pr    ... Radius des Kreises
 +
 +
 +
// TODO: Berechne den dritten Punkt 'M' des Kreises
 +
#declare norm = <-P.y, P.x>;
 +
#declare norm = norm / sqrt(pow(P.x,2) + pow(P.y,2));
 +
#declare M = <P.x/2, P.y/2, 0> + h * norm;
 +
 +
// TODO: Berechne aus den drei Punkten O = (0,0), P und M das Zentrum und den Radius des Kreises.
 +
  //      Hint: Schneide die Mittelsenkrechte der zwei geraden OM und MP.
 +
 +
#declare OM = M/2;
 +
#declare norm1 = <M.y, -M.x>;
 +
#declare MP = (M+P)/2;
 +
#declare norm2 = <(P.y-M.y), -(P.x-M.x)>;
 +
#declare mitte_x = OM.x + (norm1.x * norm2.x * (MP.y-OM.y) - norm1.x * norm2.y * (MP.x - OM.x)) / (norm1.y * norm2.x - norm1.x * norm2.y);
 +
#declare mitte_y = OM.y + (norm1.y * norm2.x * (MP.y-OM.y) - norm1.y * norm2.y * (MP.x - OM.x)) / (norm1.y * norm2.x - norm1.x * norm2.y);
 +
 +
#declare Z = <mitte_x, mitte_y, 0>;
 +
#declare r = sqrt(pow(mitte_x,2) + pow(mitte_y,2));
 +
 +
// TODO: Zeichne einen Zylinder mit dem zeichneZylinder Makro
 +
zeichneZylinder(Z.x, Z.y, r + rOffset, w)
 +
 +
// TODO: Berechne die Ausgabewerte und setze sie in den darunterliegenden Deklarationen ein
 +
#declare result_DreiPunkteZylinder_px = Z.x;
 +
#declare result_DreiPunkteZylinder_py = Z.y;
 +
#declare result_DreiPunkteZylinder_r = r;
 +
 +
#end
 +
 +
#macro zeichneZylinder(px, py, r, w)
 +
//Extrudiert einen Kreis entlang der z-Axis zu einem Zylinder
 +
//INPUT:
 +
//      px, py, r ... Mitte und Radius des Zylinders
 +
//      w ... Tiefe des Zylinders
 +
cone
 +
{
 +
    <px, py, -w/2>, r
 +
    <px, py, w/2>, r
 +
}
 +
#end
 +
 +
</pre>
 +
 +
 +
brucke.pov
 +
 +
<pre>
 +
 +
#include "math.inc"
 +
#include "zylinder_vowi.mac"
 +
#include "bruckeTexturen.inc"
 +
 +
#macro Brucke(A, h, B, bridgeWidth, innerWidth, innerHeight)
 +
//INPUT:
 +
//      A und B entsprechen den Punkten in der Web-Angabe
 +
//      h entspricht der maximalen Hoehe der Bruecke ueber der Linie, die A mit B verbindet
 +
//      bridgeWidth ... aeussere Breite der Bruecke
 +
//      innerWidth ... Breite der strasse auf der Bruecke
 +
//      innerHeight ... Hoehe des Randes der Bruecke
 +
 +
// arc ... Anzahl der Arkaden
 +
// space ... Abstand zwischen Brueckenoberflaeche und Arkaden
 +
#declare arc = 33;
 +
#declare space = 3.5;
 +
 +
// WICHTIG: Die zu verwendende Texturen befinden sich in der Datei
 +
//          "bruckeTexturen.inc".
 +
//          Fuer den begehbaren Teil der Bruecke ist die Textur TT_Bridge,
 +
//          fuer die Brueckenseiten -  die Textur TT_Bridge_Sides und
 +
//          fuer die Marker - die Textur TT_Decor zu nehmen.
 +
 +
    // TODO: Verschiebe und drehe die Bruecke, so dass sich A in Koordinatenursprung befindet und B in der xy-Halbebene, wo x>=0, liegt.
 +
    //      Nicht vergessen: das erstellte Modell ist am Ende zurueckzutransformieren.
 +
    #declare ANew = A - A;
 +
   
 +
    #local abw = atan2d((B-A).z, (B-A).x);
 +
 +
    // TODO: Berechne die Koordinaten von B nach der Transformation und speichere sie in P.
 +
    // Hint: Es ist der projizierte Abstand zwischen A und B (finde heraus in welcher Ebene!) zu nutzen.
 +
    #declare P = vrotate(B-A, <0, -abw, 0>);
 +
 +
    // TODO: Baue den Brueckenkoerper auf. Dazu sollte das DreiPunkteZylinder
 +
    //      Makro zur Berechnung von der Mitte und dem Radius aufgerufen werden, zur mehrfachen
 +
    //      Zeichnung verwende das zeichneZylinder Makro. Benutze die oben berechnete
 +
    //      Variable P und den Inputparameter h. Die Ergebnisse aus dem Aufruf
 +
    //      werden ueber folgende global deklarierte Variablen erreichbar sein:
 +
    //      result_DreiPunkteZylinder_px
 +
    //      result_DreiPunkteZylinder_py
 +
    //      result_DreiPunkteZylinder_r
 +
   
 +
    // TODO: Schneide die Arkaden aus dem Brueckenkoerper aus.
 +
    //      Benutze das weiter unten definierte Makro lineArcIntersection,
 +
    //      um die Reichweite der Arkaden zu berechnen. An Stelle der
 +
    //      ersten und letzten soll nichts ausgeschnitten werden, deshalb
 +
    //      rechne mit 2 zusaetzlichen (fiktiven) Arkaden bei der Verteilung.
 +
 +
union{
 +
 
 +
    difference{
 +
DreiPunkteZylinder(h, P, bridgeWidth, 0)
 +
 +
        #declare breite = P.x/((arc+2)*2);
 +
        #declare idx = 3;
 +
   
 +
#while(idx<(arc+1)*2)
 +
    lineArcIntersection(idx*breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r);
 +
   
 +
    union{
 +
      cone{
 +
  <idx*breite, result_lineArcIntersection - space - breite/2, -bridgeWidth>, breite/2
 +
  <idx*breite, result_lineArcIntersection - space - breite/2,  bridgeWidth>, breite/2
 +
      }
 +
      box{
 +
  <idx*breite + breite/2, result_lineArcIntersection - space - breite/2 , -bridgeWidth>
 +
  <idx*breite - breite/2, -100, bridgeWidth>
 +
      }
 +
    }
 +
   
 +
    #declare idx = idx + 2;
 +
#end
 +
 +
texture{
 +
    TT_Bridge_Sides
 +
}
 +
    }
 +
   
 +
    // TODO: Zeichne die Bruecke. Markiere die Punkte A, B und
 +
    //      den Punkt, der am hoechsten ueber der Gerade liegt,
 +
    //      die A mit B verbindet, mit kleinen Saeulen, Lampen
 +
    //      oder anderen zur Bruecke passenden Objekten nach eigener Wahl.
 +
   
 +
    difference{
 +
        zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r + innerHeight, bridgeWidth)
 +
       
 +
        union{
 +
    zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r, bridgeWidth + 1)
 +
    zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r + innerHeight + 1, innerWidth)
 +
        }
 +
       
 +
        texture{
 +
    TT_Bridge
 +
    rotate <90, 0, 0>
 +
    translate <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py>
 +
}
 +
    }
 +
 
 +
    sphere{
 +
lineArcIntersection(breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
lineArcIntersection((arc + 2) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
        }
 +
    }
 +
    sphere{
 +
lineArcIntersection(((arc + 2) * 2 - 1) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
lineArcIntersection(breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
lineArcIntersection((arc + 2) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
        }
 +
    }
 +
    sphere{
 +
lineArcIntersection(((arc + 2) * 2 - 1) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
 +
<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
    sphere{
 +
<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
 +
texture{
 +
    TT_Decor
 +
}
 +
    }
 +
}   
 +
    rotate < 0, abw, 0>
 +
    translate(A)
 +
#end
 +
 +
// TODO: Hier sind andere notwendigen Makros zu definieren.
 +
 +
// Dises Makro berechnet den Schnittpunkt zwischen einem Bogen
 +
// und einer vertikalen Geraden in 2D, die durch einen bestimmten
 +
// Punkt laeuft.
 +
#macro lineArcIntersection(px, cM, cR)
 +
// INPUT
 +
//      px: ... die Gerade laeuft vertikal durch den Punkt (px,0)
 +
//      cM: ... das Zentrum vom Bogen (Bruecke)
 +
//      cR: ... der Radius vom Bogen (Bruecke)
 +
// OUTPUT
 +
//      result_lineArcIntersection ... die groessere y-Koordinate der (2) Schnittpunkte
 +
//                                    der vertikalen Geraden durch (px,0) mit dem Bogen
 +
    #declare result_lineArcIntersection = cM.y + sqrt(pow(cR,2) - pow(cM.x-px,2));
 +
#end
 +
 +
/////////////////////////////////////////////////////////////////////////
 +
//Detailansicht der Bruecke. Deaktiviert, wenn aus Terrain.pov aufgerufen.
 +
/////////////////////////////////////////////////////////////////////////
 +
 +
#ifndef (TERRAIN)
 +
    #include "colors.inc"
 +
    background { White }
 +
    camera
 +
    {
 +
        //orthographic
 +
        location <-60, 20, -80>
 +
        look_at <0, 0, 0>
 +
    }
 +
 +
    light_source {<30, 100, 0> color Gray75 }
 +
    light_source {<300, 10, -100> color Gray75 }
 +
    light_source {<-30, 50, -30> color Gray75 }
 +
    light_source {<-10, 40, -100> color Gray75 }
 +
    light_source {<-10, 40, 100> color Gray75 }
 +
 +
    #declare PP0 = <-40, 0, 0>;
 +
    #declare PP1 = <40, 15, 0>;
 +
    #declare h = 5;
 +
   
 +
    object {Brucke(PP0, h, PP1, 8, 6, 1)}
 +
 +
    sphere {PP0 2 pigment {Red}} // markiert Punkt A
 +
    sphere {PP1 2 pigment {Red}} // markiert Punkt B
 +
 +
#end</pre>
 +
 +
 +
[[Kategorie:Materialien]]

Revision as of 12:19, 24 June 2012

PovRay

Nicht direkt kopieren, nur als Referenz verwenden!

Abschreiben führt zu negativer Bewertung!

Brucke (5 Punkte)

zylinder.mac

#macro DreiPunkteZylinder(h, P, w, rOffset)
//Berechnet aus 3 Punkten deren gemeinsamen Kreis und zeichnet ihn als einen Zylinder

//INPUT P       ... der zweite Punkt in 2D, der das Kreis definiert. Der erste Punkt ist immer (0,0).
//      h       ... dient zur Berechnung des dritten Punktes des Kreises: es die maximale Hoehe ueber der
//                  Gerade, die (0,0) mit P verbindet, die das Kreis erreicht.
//      w       ... Hoehe des gezeichneten Zylinders
//      rOffset ... Versatz des Zylinder Radius, soll zum berechneten Radius dazugezaehlt werden
//OUTPUT hat den Praefix result_DreiPunkteZylinder_
//       px, py ... Zentrum des Kreises
//       pr     ... Radius des Kreises


// TODO: Berechne den dritten Punkt 'M' des Kreises
#declare norm = <-P.y, P.x>;
#declare norm = norm / sqrt(pow(P.x,2) + pow(P.y,2));
#declare M = <P.x/2, P.y/2, 0> + h * norm;

// TODO: Berechne aus den drei Punkten O = (0,0), P und M das Zentrum und den Radius des Kreises.
  //       Hint: Schneide die Mittelsenkrechte der zwei geraden OM und MP.

#declare OM = M/2;
#declare norm1 = <M.y, -M.x>;
#declare MP = (M+P)/2;
#declare norm2 = <(P.y-M.y), -(P.x-M.x)>;
#declare mitte_x = OM.x + (norm1.x * norm2.x * (MP.y-OM.y) - norm1.x * norm2.y * (MP.x - OM.x)) / (norm1.y * norm2.x - norm1.x * norm2.y);
#declare mitte_y = OM.y + (norm1.y * norm2.x * (MP.y-OM.y) - norm1.y * norm2.y * (MP.x - OM.x)) / (norm1.y * norm2.x - norm1.x * norm2.y);

#declare Z = <mitte_x, mitte_y, 0>;
#declare r = sqrt(pow(mitte_x,2) + pow(mitte_y,2));

// TODO: Zeichne einen Zylinder mit dem zeichneZylinder Makro
zeichneZylinder(Z.x, Z.y, r + rOffset, w)

// TODO: Berechne die Ausgabewerte und setze sie in den darunterliegenden Deklarationen ein
#declare result_DreiPunkteZylinder_px = Z.x;
#declare result_DreiPunkteZylinder_py = Z.y;
#declare result_DreiPunkteZylinder_r = r;

#end

#macro zeichneZylinder(px, py, r, w)
//Extrudiert einen Kreis entlang der z-Axis zu einem Zylinder
//INPUT:
//       px, py, r ... Mitte und Radius des Zylinders
//       w ... Tiefe des Zylinders
cone
{
    <px, py, -w/2>, r
    <px, py, w/2>, r
}
#end


brucke.pov


#include "math.inc"
#include "zylinder_vowi.mac"
#include "bruckeTexturen.inc"

#macro Brucke(A, h, B, bridgeWidth, innerWidth, innerHeight)
//INPUT:
//       A und B entsprechen den Punkten in der Web-Angabe
//       h entspricht der maximalen Hoehe der Bruecke ueber der Linie, die A mit B verbindet
//       bridgeWidth ... aeussere Breite der Bruecke
//       innerWidth ... Breite der strasse auf der Bruecke
//       innerHeight ... Hoehe des Randes der Bruecke

//	 arc ... Anzahl der Arkaden
//	 space ... Abstand zwischen Brueckenoberflaeche und Arkaden
	#declare arc = 33;
	#declare space = 3.5;

// WICHTIG: Die zu verwendende Texturen befinden sich in der Datei
//          "bruckeTexturen.inc".
//          Fuer den begehbaren Teil der Bruecke ist die Textur TT_Bridge,
//          fuer die Brueckenseiten -  die Textur TT_Bridge_Sides und
//          fuer die Marker - die Textur TT_Decor zu nehmen.

    // TODO: Verschiebe und drehe die Bruecke, so dass sich A in Koordinatenursprung befindet und B in der xy-Halbebene, wo x>=0, liegt.
    //       Nicht vergessen: das erstellte Modell ist am Ende zurueckzutransformieren.
    #declare ANew = A - A;
    
    #local abw = atan2d((B-A).z, (B-A).x);

    // TODO: Berechne die Koordinaten von B nach der Transformation und speichere sie in P.
    // Hint: Es ist der projizierte Abstand zwischen A und B (finde heraus in welcher Ebene!) zu nutzen.
    #declare P = vrotate(B-A, <0, -abw, 0>);

    // TODO: Baue den Brueckenkoerper auf. Dazu sollte das DreiPunkteZylinder
    //       Makro zur Berechnung von der Mitte und dem Radius aufgerufen werden, zur mehrfachen 
    //       Zeichnung verwende das zeichneZylinder Makro. Benutze die oben berechnete
    //       Variable P und den Inputparameter h. Die Ergebnisse aus dem Aufruf
    //       werden ueber folgende global deklarierte Variablen erreichbar sein:
    //       result_DreiPunkteZylinder_px
    //       result_DreiPunkteZylinder_py
    //       result_DreiPunkteZylinder_r
    
    // TODO: Schneide die Arkaden aus dem Brueckenkoerper aus.
    //       Benutze das weiter unten definierte Makro lineArcIntersection,
    //       um die Reichweite der Arkaden zu berechnen. An Stelle der 
    //       ersten und letzten soll nichts ausgeschnitten werden, deshalb 
    //       rechne mit 2 zusaetzlichen (fiktiven) Arkaden bei der Verteilung.

union{
  
    difference{
	DreiPunkteZylinder(h, P, bridgeWidth, 0)

        #declare breite = P.x/((arc+2)*2);
        #declare idx = 3;
    
	#while(idx<(arc+1)*2)
	    lineArcIntersection(idx*breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r);
	    
	    union{
	      cone{
		  <idx*breite, result_lineArcIntersection - space - breite/2, -bridgeWidth>, breite/2
		  <idx*breite, result_lineArcIntersection - space - breite/2,  bridgeWidth>, breite/2
	      }
	      box{
		  <idx*breite + breite/2, result_lineArcIntersection - space - breite/2 , -bridgeWidth>
		  <idx*breite - breite/2, -100, bridgeWidth>
	      }
	    }
	    
	    #declare idx = idx + 2;
	#end

	texture{
	    TT_Bridge_Sides
	}
    }
    
    // TODO: Zeichne die Bruecke. Markiere die Punkte A, B und
    //       den Punkt, der am hoechsten ueber der Gerade liegt,
    //       die A mit B verbindet, mit kleinen Saeulen, Lampen
    //       oder anderen zur Bruecke passenden Objekten nach eigener Wahl.
    
    difference{
        zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r + innerHeight, bridgeWidth)
        
        union{
	    zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r, bridgeWidth + 1)
	    zeichneZylinder(result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, result_DreiPunkteZylinder_r + innerHeight + 1, innerWidth)
        }
        
        texture{
	    TT_Bridge
	    rotate <90, 0, 0>
	    translate <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py>
	}
    }
   
    sphere{
	lineArcIntersection(breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
	texture{
	    TT_Decor
	}
    }
    sphere{
	<breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
	texture{
	    TT_Decor
	}
    }
    sphere{
	lineArcIntersection((arc + 2) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
	texture{
	    TT_Decor
	}
    }
    sphere{
	<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
 	texture{
	    TT_Decor
        }
    }
    sphere{
	lineArcIntersection(((arc + 2) * 2 - 1) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 1, -bridgeWidth/2 + 0.5>, 1
	texture{
	    TT_Decor
	}
    }
    sphere{
	<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 1, bridgeWidth/2 - 0.5>, 1
	texture{
	    TT_Decor
	}
    }
    sphere{
	lineArcIntersection(breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
	texture{
	    TT_Decor
	}
    }
    sphere{
	<breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
	texture{
	    TT_Decor
	}
    }
    sphere{
	lineArcIntersection((arc + 2) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
	texture{
	    TT_Decor
	}
    }
    sphere{
	<(arc + 2) * breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
 	texture{
	    TT_Decor
        }
    }
    sphere{
	lineArcIntersection(((arc + 2) * 2 - 1) * breite, <result_DreiPunkteZylinder_px, result_DreiPunkteZylinder_py, 0>, result_DreiPunkteZylinder_r)
	<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 2.3, -bridgeWidth/2 + 0.5>, 0.3
	texture{
	    TT_Decor
	}
    }
    sphere{
	<((arc + 2) * 2 - 1) * breite, result_lineArcIntersection + innerHeight + 2.3, bridgeWidth/2 - 0.5>, 0.3
	texture{
	    TT_Decor
	}
    }
}    
    rotate < 0, abw, 0>
    translate(A)
#end

// TODO: Hier sind andere notwendigen Makros zu definieren.

// Dises Makro berechnet den Schnittpunkt zwischen einem Bogen
// und einer vertikalen Geraden in 2D, die durch einen bestimmten
// Punkt laeuft.
#macro lineArcIntersection(px, cM, cR)
// INPUT 
//      px: ... die Gerade laeuft vertikal durch den Punkt (px,0)
//      cM: ... das Zentrum vom Bogen (Bruecke)
//      cR: ... der Radius vom Bogen (Bruecke)
// OUTPUT
//      result_lineArcIntersection ... die groessere y-Koordinate der (2) Schnittpunkte
//                                     der vertikalen Geraden durch (px,0) mit dem Bogen
    #declare result_lineArcIntersection = cM.y + sqrt(pow(cR,2) - pow(cM.x-px,2));
#end

/////////////////////////////////////////////////////////////////////////
//Detailansicht der Bruecke. Deaktiviert, wenn aus Terrain.pov aufgerufen.
/////////////////////////////////////////////////////////////////////////

#ifndef (TERRAIN)
    #include "colors.inc"
    background { White } 
    camera
    {
        //orthographic
        location <-60, 20, -80>
        look_at <0, 0, 0>
    }

    light_source {<30, 100, 0> color Gray75 }
    light_source {<300, 10, -100> color Gray75 }
    light_source {<-30, 50, -30> color Gray75 }
    light_source {<-10, 40, -100> color Gray75 }
    light_source {<-10, 40, 100> color Gray75 }

    #declare PP0 = <-40, 0, 0>;
    #declare PP1 = <40, 15, 0>;
    #declare h = 5;
    
    object {Brucke(PP0, h, PP1, 8, 6, 1)} 

    sphere {PP0 2 pigment {Red}} // markiert Punkt A
    sphere {PP1 2 pigment {Red}} // markiert Punkt B

#end