// Povray file to build anamorposes #include "inclusions.inc" global_settings { max_trace_level 255 } /* Variables you can tune */ // rendering=0 : first step --> computing the grid and outputting the coordinates data // rendering=1 : final step --> rendering the anamorphosis #declare rendering=0; // Controls the position of the screen between the eye and the mirror #declare boing=1.5; // Screen size (can be tuned for better overlap with the mirror). #declare hauteurEcran=1; // The position of the eye #declare visionPoint=<2,1,-5>; //The focus point #declare centreObjet=<0,1.5,0>; // appearance of the reflected grid #declare diamCylinder=0.028; #declare diamSphere=2.5*diamCylinder; /* No more tuning beyond this line ! */ //angle of the observer's eye on the y plane (auxiliary value) #declare myAngle=-180/pi*atan2(visionPoint.z,visionPoint.x); // The vector from the eye toward the focus point #declare direc=visionPoint-centreObjet; // Same, but normalized #declare normdirec=vnormalize(direc); sky_sphere { S_Cloud5 rotate 180*x } // a lot of lights #declare ra=0; #declare dd=100; #declare nb=3; #while(ra <0, 0, 4> 5, 5 adaptive 0.2 jitter circular orient translate photons { refraction on reflection on } media_attenuation on shadowless } #declare ra=ra+1; #end #declare ra=0; #declare dd=100; #declare nb=3; #while(ra <0, 0, 4> 5, 5 adaptive 0.2 jitter circular orient translate photons { refraction on reflection on } media_attenuation on shadowless } #declare ra=ra+1; #end // output utility #macro afficheVecteur(vv) concat(" ",str(vv.x,0,-1)," ",str(vv.z,0,-1)," \n") #end // Egg shape from : http://www.lohmueller.business.t-online.de/pov_tut/x_sam/sam_390e.htm #declare Egg_upperpart = intersection{ sphere{<0,0,0>,1 scale<1,1.75,1>} box{<-1,0,-1>,<1,1.75,1>} } #declare Egg_lowerpart = intersection{ sphere{<0,0,0>,1 scale<1,1,1>} box{<-1,-1,-1>,<1,0,1>} } #declare Egg = union{ object{Egg_upperpart } object{Egg_lowerpart} texture{T_Chrome_5E} finish{Metallic_Finish} } // A very thin box where the final image will be mapped #declare image=box{<0,0,0>,<1,0.0000001,1> pigment{ image_map{ // the name of the file containing the distorted image png "/tmp/MonaMod.png" map_type 0 } rotate 90*x } finish{ambient 0.8 diffuse 1} translate<-0.5,0,-0.5> scale 1 } // The plane where the distorted image will be drawn. #declare lePlan=plane{y,0 texture{pigment{color Gray90}} } // the mirror #declare rond=object {Egg rotate 180*x translate 2.5*y } // The transformation which moves the screen from <0,0,0> to its final position #declare tournicotis=transform{ rotate atan2(direc.y,sqrt(direc.x*direc.x+direc.z*direc.z))*180/pi*z rotate -atan2(direc.z,direc.x)*180/pi*y translate centreObjet // boing can be tuned to change the relative position of the screen between the eye and the mirror translate boing*normdirec } // auxiliary definitions for the screen #declare axeEcran1=cylinder{ <0,-hauteurEcran/2,-hauteurEcran/2>, <-0.01,hauteurEcran/2,hauteurEcran/2>,0.015 texture{pigment{color Red}} } #declare axeEcran2=cylinder{ <0,hauteurEcran/2,-hauteurEcran/2>, <-0.01,-hauteurEcran/2,hauteurEcran/2>,0.015 texture{pigment{color Red}} } #declare ecran=box{<0,-hauteurEcran/2,-hauteurEcran/2>,<-0.01,hauteurEcran/2,hauteurEcran/2> texture{pigment{color rgbt<0,1,1,0.8>}} } // ecran // the screen #declare ecranTotal=union{ object{ecran} object{axeEcran1} object{axeEcran2} transform{tournicotis} } // union // the scene object{lePlan } object{rond } // uncomment the following line if you want to verify the position of the screen //object{ecranTotal} #if(rendering=1) object{image // Copy the line output by Anamorphose5.java : scale <325.7535,1,130.3014> rotate (-90)*y } #end #if(rendering=0) // those arrays will be usefull to draw lines between images of point on the plane #declare depart=array[1000]; #declare arrivee=array[1000]; #declare bb=0; #while(bb<1000) #declare depart[bb]=<-1,-1,-1>; #declare arrivee[bb]=<-1,-1,-1>; #declare bb=bb+1; #end // double loop on the grid points #declare imax=hauteurEcran/2; #declare indexy=-imax; // modifying inc changes the resolution of the grid #declare inc=0.05; #declare normy=<1,1,1>; #declare normy2=<1,1,1>; // First line in the data file : size of the screen, distance between adjacent grid points // We can then compute the max number of elementary squares #debug concat(str(hauteurEcran,3,3)," ",str(inc,3,3),"\n") #declare first=1; #declare indicey=0; #while(indexy<=imax) #declare indexz=-imax; #declare indicez=0; #while(indexz<=imax) // A grid point #declare p1=vtransform(<0,indexy,indexz>, transform{tournicotis}); // Direction of the ray #declare punkt=<-visionPoint.x+p1.x,-visionPoint.y+p1.y,-visionPoint.z+p1.z>; // Uncomment if you want to plot the point on the screen //sphere{p1,0.025 texture{pigment{color Green}}} // intersection of the ray and the mirror #declare poInter=trace(rond,visionPoint,punkt,normy); #if(vlength(normy)!=0) // Computing the refleted ray #declare normPlan=vcross(punkt,normy); // definir la rotation // punkt : vecteur incident #declare angola=vdot(punkt,normy); #declare angola=acos(angola/(vlength(punkt)*vlength(normy)))*180/pi; #declare reflechi=vaxis_rotate(normy,normPlan,angola); // Intersection of the reflected ray and the plane #declare onPlane=trace(lePlan,poInter,-reflechi,normy2); #if(vlength(normy2)!=0) // Uncomment if you want to follow the rays (beware ! : too much ray leaves nothing to see) //sphere{p1,0.01 texture{pigment{color Green}}} //cylinder{visionPoint,poInter,0.03 texture{pigment{color Black}}} //cylinder{poInter,onPlane,0.03 texture{pigment{color Black}}} sphere{onPlane,diamSphere texture{pigment{color Yellow}}} #declare depart[indicez]=onPlane; // output coordinates of the point on the plane #debug concat (str(indicey,0,0)," ",str(indicez,0,0)," ",afficheVecteur(depart[indicez])) // Trace lines between points if neighbours exist #if(indicez!=0) #if(depart[indicez-1].y!=-1) cylinder{depart[indicez-1],depart[indicez],diamCylinder texture{pigment{color Green}}} #end #if((indicey!=0)&(arrivee[indicez].y!=-1)) cylinder{arrivee[indicez],depart[indicez],diamCylinder texture{pigment{color Green}}} #end #end #end #end #declare indicez=indicez+1; #declare indexz=indexz+inc; #end #declare bb=0; #while(bb<1000) #if(depart[bb].y!=-1) #declare arrivee[bb]=depart[bb]; #declare depart[bb]=<-1,-1,-1>; #end #declare bb=bb+1; #end #declare indexy=indexy+inc; #declare indicey=indicey+1; #end #end // rendering=0 camera{ location visionPoint look_at centreObjet }