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

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