// ///////////////////////////////////////////////////////////////////////////// #include "colors.inc" #include "textures.inc" #include "math.inc" #declare random1=0; #declare random2=0; // DAS HIER IST DAS ZIEL / DER FEIND #declare feind = union{ sphere { <-0,5,-120> 10 texture { pigment{ color rgb<0.1,0.1,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } } } object{feind } #declare wand = union{ /* */ box { <-0, -0, -0> // one corner position < 100, 10, 10> // other corner position rotate <0,0,0> scale 3 translate<-40,0,50> } box { <-0, -0, -0> // one corner position < 100, 10, 10> // other corner position rotate <0,45,> scale 3 translate<0,0,80> } box { <-0, -0, -0> // one corner position < 100, 10, 10> // other corner position rotate <0,90,> scale 3 translate<120,0,120> } box { <-0, -0, -0> // one corner position < 100, 10, 10> // other corner position rotate <0,-90,0> scale 3 translate<-30,0,-40> } pigment{ hexagon color Red color Yellow color Orange } } object{wand } //################################ //### MACRO AMEISE //################################ #macro Make_ant(a_size, startpos, startrichtung,startvelocity) #if(clock=0) #declare pos = startpos; #declare richtung = startrichtung; #declare velocity = startvelocity; #else // LESEN DER LETZTEN DATEN #fopen ipc "letztepos.txt" read //ipc =interactive POV-ray control file #read(ipc,pos,richtung,velocity) #fclose ipc #end #declare pseudozufall = clock*vlength(pos-richtung)*10; //#################################### // BEWEGUNG DER AMEISE //################################### #declare bewegungsgrad = 5; #declare schrittweite = 2*19.647*sin(bewegungsgrad)*a_size ; //#declare bewegung_delta = vlength(richtung) ; //#declare v_real = bewegung_delta/clock_delta; //#declare v_normal = schrittweite/tau; //#declare v_factor = abs(v_real/v_normal); #declare v_factor = velocity; #if (richtung.z<0) #declare winkel_delta = -VAngleD(richtung*100000, <-1,0,0>); #else #declare winkel_delta = VAngleD(richtung*100000, <-1,0,0>); #end #declare arg = (2*pi*tt/tau)/a_size*v_factor; #if (sin(arg + pi/2)<0) #declare beinbewegunga = <0,2*bewegungsgrad*sin(arg),0> ; #declare beinbewegungb = ; #else #declare beinbewegunga = ; #declare beinbewegungb = <0,-2*bewegungsgrad*sin(arg),0>; #end //#################################### // KÖRPER DER AMEISE //################################### #declare mittelteil = union{ sphere { <0,0,0> 6 texture { pigment{ color rgb<0.1,0.1,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } scale <1,0.6,0.6> } } #declare hinterteil = union{ sphere { <0,0,0> 10 texture { pigment{ color rgb<0.1,0.1,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } scale <1,0.6,0.7> } } #declare mund= union{ sphere{ <0,0,0> 1 pigment { color Red } scale <2,1,3> rotate<0,0,20> translate<-3,-2,0> } } #declare fuehler = union{ // create a curved tube object translating a sphere along a certain path sphere_sweep { linear_spline // linear curve //cubic_spline // alternative spline curves //b_spline 3, // number of specified sphere positions <0, 0,0>, 0.3 <-1, 13,0>,0.3 // position, radius <-8, 9,0>, 0.1 // ... //tolerance 0.001 // optional texture { pigment{ color rgb<0.1,0.1,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } } } #declare diefuehler = union{ object{fuehler rotate<30,30,0> } object{fuehler rotate<-30,-30,0>} } #declare augerechts = union{ sphere { <0,0,0> 1 pigment { color White } scale <0.5,1.5,1> rotate<0,28,-30> translate<-3.5,2.2,2.2> } sphere { <0,0,0> 0.5 pigment { color Black } scale <0.5,1.5,1> rotate<0,28,-30> translate<-3.9,2.2,2.5> } } #declare augelinks = union{ sphere { <0,0,0> 1 pigment { color White } scale <0.5,1.5,1> rotate<0,-28,-30> translate<-3.5,2.2,-2.2> } sphere { <0,0,0> 0.5 pigment { color Black } scale <0.5,1.5,1> rotate<0,-28,-30> translate<-3.9,2.2,-2.5> } } #declare kopfkugel = union{ sphere { <0,0,0> 5 texture { pigment{ color rgb<0.1,0.1,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } scale <1,1,1> } } #declare kopf = union{ difference{ union{ object{kopfkugel} object{augerechts} object{augelinks} object{diefuehler} } object{mund} } } #declare bein = union{ // create a curved tube object translating a sphere along a certain path sphere_sweep { linear_spline // linear curve //cubic_spline // alternative spline curves //b_spline 5, // number of specified sphere positions <0, 0, 0>, 0.8 <0, 1,-3>,0.8 // position, radius <0, 6, -11>, 0.8 // ... <0, -3, -16>, 0.8 <0, -5, -19>, 0.3 //tolerance 0.001 // optional texture { pigment{ color rgb<0.9,0.9,0.0>} //normal {bumps 0.5 scale 0.05} finish { diffuse 0.75 specular 0.3 phong 0.3 reflection 0.07} } } } #declare beine = union{ object{bein rotate (<0,0,0> +beinbewegunga) } object{bein rotate (<0,30,0> +beinbewegungb) } object{bein rotate (<0,-50,0>+beinbewegungb) } object{bein rotate (<0,180,0>+beinbewegunga) } object{bein rotate (<0,230,0>+beinbewegungb) } object{bein rotate (<0,150,0>+beinbewegungb) } } #declare koerper = union { object{mittelteil} object{hinterteil translate<16,0,0> rotate<0,0,10 > } object{kopf rotate<0,0,-20 > translate<-11,0,0> rotate<0,0,-10 > } } #declare ameise = union{ object{koerper} object{beine} } #declare lego = union { box { <-5, 0, -2> // one corner position < 5, 0.5, 2> // other corner position } pigment{ hexagon color Red color Yellow color Orange } } //############################## //### DARSTELLUNG DER AMEISE ### //############################## object{ameise rotate<0,winkel_delta,0> scale <1,1,1>*a_size translate pos+<0,5*a_size,0> } //object{lego rotate<0,winkel_delta,0> scale <1,1,1>*a_size translate pos+<0,5*a_size,0> } //#################################################################### // Wahrnehmung der Ameise // Und Bestimmung der neuen Laufrichtung und Geschwindigkeit //#################################################################### #declare norm = <0, 0, 0>; #declare ausweichvektor = <0,0,0>; #declare zielvektor = <0,0,0>; #declare modus = 0; // MODUS 0: Erkunden // MODUS 1: Hindernis // MODUS 2: Feind in Sicht // Modus 3: Ziel erreicht //#################################################################### // Hindernis testen und gleichzeitig einen ausweichvektor zurückgeben // Gibt es ein Hindernis geht der Modus auf 1 #macro testehindernis() #declare kritischeentfernung = 30; #declare norm = <0, 0, 0>; #declare i = 0; #while (i < 20) #declare guckinrichtung = vaxis_rotate(richtung,<0,1,0>,i*18); #declare schnittpunkt = trace ( wand, // object to test pos+<0,10,0>, // starting point guckinrichtung, // direction norm ); // normal #declare entfernung = vlength(schnittpunkt-pos); #if (norm.x != 0 | norm.y != 0 | norm.z != 0) #if (entfernung < kritischeentfernung ) #declare modus = 1; #end // Wenn die Entfernung sehr groß ist, wird der schnittpunkt näher rangeholt #if (entfernung > 10*kritischeentfernung ) #declare schnittpunkt = 10*kritischeentfernung*guckinrichtung; #end #else // Wenn es keinen Schnittpunkt gab wird ein schnittpunkt simuliert #declare schnittpunkt = 10*kritischeentfernung*guckinrichtung; #end #declare ausweichvektor = ausweichvektor + schnittpunkt-pos; #declare i = i+1; // increment our counter #end #declare ausweichvektor = vnormalize(ausweichvektor); #end // of testehindernis //#################################################################### // Feind testen und gleichzeitig einen zielvektor zurückgeben // Gibt es einen Feind geht der Modus auf 2 bzw 3, wenn der Feind erreicht ist #macro testefeind() #declare kritischefeindentfernung = 18; #declare sichtweite = 80; #declare norm = <0, 0, 0>; #declare i = 0; #declare tempmodus = 1; #while (i < 72) #declare entfernung = 0; #declare guckinrichtung = vaxis_rotate(richtung,<0,1,0>,i*5); #declare feindpos = trace ( feind, // object to test pos+<0,5,0>, // starting point guckinrichtung, // direction norm ); // normal #declare entfernung = abs(vlength(-feindpos+pos)) ; #if ((norm.x != 0 | norm.y != 0 | norm.z != 0)&(entfernung,random2) ; #else #declare richtungneu = richtung ; #end #declare velocity = startvelocity; #if (velocity < 0.85*startvelocity) // Wenn Ameise langsamer als 0,85*startgeschwindigkeit ist, beschleunigt sie mit faktor 1,2 #declare velocity = 1.2*velocity; #else #declare velocity = startvelocity; #end #if (velocity < 1.15*startvelocity) // Wenn Ameise schneller als 1,15*startgeschwindigkeit ist, bremst sie mit faktor 0,8 ab #declare velocity = 0.8*startvelocity; #else #declare velocity = startvelocity; #end #declare modusname = "Normal"; #break #case (1) // AUSWEICHEN! #declare kreuz = vcross(richtung,ausweichvektor); // Wenn kreuz nach unten zeigt, zeigt der ausweichvektor in Richtung Links relativ zur Laufrichtung #if(kreuz.y<0) #declare richtungsanderungswinkel = -10; #else #declare richtungsanderungswinkel = 10; #end #declare richtungneu = vaxis_rotate(richtung,<0,1,0>,richtungsanderungswinkel) ; #if (velocity > 0.5*startvelocity) // Wenn Ameise schneller als 0,5*startgeschwindigkeit ist, bremst sie mit faktor 0,8 ab #declare velocity = 0.8*velocity; #else #declare velocity = 0.5*startvelocity; #end #declare modusname = "Ausweichen"; #break #case (2) // Verfolgen! #declare kreuz = vcross(richtung,zielvektor) ; // Wenn kreuz nach unten zeigt, zeigt der zielvektor in Richtung Links relativ zur Laufrichtung #declare maxx = 10; // maximal mögliche Richtungänderung pro Zeiteinheit #if( VAngleD(richtung,zielvektor) < maxx) // Wenn der Winkel zum Ziel kleiner als 10° ist, ändert sich die Laufrichtung nur um diesen Wert #declare maxx = VAngleD(richtung,zielvektor)/2; #end #if(kreuz.y<0) #declare richtungsanderungswinkel = -maxx; #else #declare richtungsanderungswinkel = maxx; #end #declare richtungneu = vaxis_rotate(richtung,<0,1,0>,richtungsanderungswinkel) ; #if (velocity < 2*startvelocity) // Wenn Ameise langsamer als 2*startgeschwindigkeit ist, beschleunigt sie mit faktor 1,2 ab #declare velocity = 1.2*velocity; #else #declare velocity = 2*startvelocity; #end #declare modusname = "Verfolgen"; #break #case (3) // ENDE #declare ende=1; #declare richtungneu = richtung; #declare velocity = 0; #declare modusname = "ENDE"; // Hier wird noch "THE END" angezeigt text{ttf "arial.ttf" concat("THE END ") ,0.1,0 pigment{White} rotate<90,0,0> scale 9 translate<-12,120,-4> +pos } box{ <-0, -0, -0> // one corner position < 7.8, 0.1, 1.7> // other corner position pigment{Black transmit 0.8} rotate<0,0,0> scale 5.3 translate<-13,119,-5> +pos } #break #else #declare richtungneu = richtung; #end // End of switch statement #declare posneu=pos+richtungneu*velocity; // SPEICHERN DER AKTUELLEN DATEN #fopen interframe "letztepos.txt" write #write (interframe, posneu,",", richtungneu,",",velocity, " geschrieben von POVRay Frame # ",frame_number) #fclose interframe //################################# //####### DEBUGGING ############### //################################# text{ttf "arial.ttf" concat("MODUS: ",modusname) ,0.1,0 no_shadow pigment{Black} rotate<90,0,0> scale 5 translate<-50,120,30> +pos } box{ <-0, -0, -0> // one corner position < 10, 0.1, 1.1> // other corner position no_shadow pigment{White} rotate<0,0,0> scale 5.3 translate<-51,119,29> +pos } #declare debugging = false; #if (debugging = true) #declare punkte = union{ sphere{schnittpunkt, 2} sphere{schnittpunkt + norm*10,2} pigment{ color rgb<1,1,1>} } object{ punkte } text{ttf "arial.ttf" concat("pszu=",str(pseudozufall,2,1) ),0.1,0 pigment{Red} rotate<90,0,0> scale 5 translate<-0,60,-5> +pos } text{ttf "arial.ttf" concat("ran1=",str(random1,2,1) ),0.1,0 pigment{Red} rotate<90,0,0> scale 5 translate<-0,60,-10> +pos } text{ttf "arial.ttf" concat("ran2=",str(random2,2,1) ),0.1,0 pigment{Red} rotate<90,0,0> scale 5 translate<-0,60,-15>+pos } text{ttf "arial.ttf" concat("ri.x=",str(richtung.x,2,1), " ri.z=",str(richtung.z,2,1) ),0.1,0 pigment{Red} rotate<0,0,0> scale 5 translate<-10,25,10> +posneu } text{ttf "arial.ttf" concat("no.x=",str(norm.x,2,1), " no.z=",str(norm.z,2,1) " no.y=",str(norm.y,2,1) ),0.1,0 pigment{Red} rotate<0,0,0> scale 5 translate<-13,20,10> +posneu } /* #if(aufprallwinkel) text{ttf "arial.ttf" concat("aufprallwinkel=",str(aufprallwinkel,2,1)),0.1,0 pigment{Red} rotate<0,0,0> scale 5 translate<-13,10,10> +posneu } text{ttf "arial.ttf" concat("kreuz.y=",str(kreuz.y,2,1)),0.1,0 pigment{Red} rotate<0,0,0> scale 5 translate<-40,5,10> +posneu } text{ttf "arial.ttf" concat("abstand=",str(abstand,2,1)),0.1,0 pigment{Red} rotate<0,0,0> scale 5 translate<-50,0,10> +posneu } #end */ #end // of debugging #end // End of Make_ant #declare X=final_frame; #declare dauer = 50; #declare te = dauer; #declare tt = dauer*clock; #declare ttminus1 = tt-1/X; #declare r = 2; #declare w = 360; #declare tau = 1 ; //Es werde Licht light_source { <0,200,1> color White } plane { y, 0 texture{ pigment{ color rgb<0.35,0.65,0.0>*0.9 } normal { bumps 1 scale <1,0,0> } finish { phong 0.1 } } // end of texture } // end of plane // Create an infinite sphere around scene and allow any pigment on it sky_sphere { pigment { gradient y color_map { [0.0 color rgb <0.7,0.7,1.0>] [1.0 color blue 0.5] } } } Make_ant(0.5,<0,0,0>,<0,0,1>,0.5) camera { location <0,200,-0>+pos look_at <0,0,0> +pos }