#include "rand.inc" #declare torus_thickness=0.15; // radius of an *untransformed* torus segment #declare num_phi1=36; // number of segments around minor torus axis #declare num_phi2=5*4; // number of segments along 90 degrees of the major torus axis // These functions define the transformation of the 3D Trouchet tiling // Change them if you like #declare point_trans_x=function(x,y,z) { // x*sin(y/4)+z*cos(y/4) x/max(1e-6,x*x+y*y+z*z) } #declare point_trans_y=function(x,y,z) { // y y/max(1e-6,x*x+y*y+z*z) } #declare point_trans_z=function(x,y,z) { // x*cos(y/4)-z*sin(y/4) z/max(1e-6,x*x+y*y+z*z) } // This generates one point on the torus surface (phi1: along major, phi2: along minor axis) #macro _point(phi1,phi2) (vrotate(vrotate(torus_thickness*z,x*phi2)+z*1,y*phi1)) #end // Same for the normals #macro _normal(phi1,phi2) (vrotate(vrotate(z,phi2*x),phi1*y)) #end #declare step_phi1=90/num_phi1; // angular step sizes #declare step_phi2=360/num_phi2; // This generates triangles of one quarter torus // trans,rot is used for positioning the torus whithin the origin tile // trans2,rot2 is used for translating/rotating the final tile #macro _quarter_torus_tris(trans,rot,trans2,rot2) #local _phi1=0; #while (_phi1<90) #local _phi2=0; #while (_phi2<360) #local p1=vrotate(vrotate(_point(_phi1,_phi2),rot)+trans,rot2)+trans2; #local p2=vrotate(vrotate(_point(_phi1+step_phi1,_phi2),rot)+trans,rot2)+trans2; #local p3=vrotate(vrotate(_point(_phi1+step_phi1,_phi2+step_phi2),rot)+trans,rot2)+trans2; #local p4=vrotate(vrotate(_point(_phi1,_phi2+step_phi2),rot)+trans,rot2)+trans2; #local p1=; #local p2=; #local p3=; #local p4=; // This section is commented out, since I have no clue how to transform the normals apropriately /* #local n1=vrotate(vrotate(_normal(_phi1,_phi2),rot),rot2); #local n2=vrotate(vrotate(_normal(_phi1+step_phi1,_phi2),rot),rot2); #local n3=vrotate(vrotate(_normal(_phi1+step_phi1,_phi2+step_phi2),rot),rot2); #local n4=vrotate(vrotate(_normal(_phi1,_phi2+step_phi2),rot),rot2); smooth_triangle{p1,n1,p2,n2,p3,n3} smooth_triangle{p1,n1,p3,n3,p4,n4} */ triangle {p1,p2,p3} triangle {p1,p3,p4} #local _phi2=_phi2+step_phi2; #end #local _phi1=_phi1+step_phi1; #end #end // This generates triangles for one complete tile with 3 quarter tori #macro Trouchet_Tile(trans,rot) _quarter_torus_tris(<-1,0,-1>,0,trans,rot) _quarter_torus_tris(<1,1,0>,<90,180,0>,trans,rot) _quarter_torus_tris(<0,-1,1>,<0,90,90>,trans,rot) #end // One stupid texture... comming up! #declare Tpipes=texture { pigment { color rgbf <0.7,0.9,0.99,00> } finish { specular 1 roughness 0.1 reflection 0.1} } // Boring camera and lighting setup camera { location 3 look_at 0 angle 45 rotate y*20 } light_source { 1000 color rgb 1 rotate y*90 } light_source { 1000 color rgb <1,.6,.6> rotate -y*100 } // The seed for the 3D tiling #declare rotseed=seed(2345443); // This is the size of the tiling in cubes along each axis, // should be multiple of 2 but works with any value #declare _size=4; // now this generates the final mesh #declare Trouchet=mesh{ #declare _x=-_size/2; #while (_x<=_size/2) #declare _y=-_size/2; #while (_y<=_size/2) #declare _z=-_size/2; #while (_z<=_size/2) #declare rx=int(RRand(0,3,rotseed))-1; #declare ry=int(RRand(0,3,rotseed))-1; #declare rz=int(RRand(0,3,rotseed))-1; Trouchet_Tile( <_x,_y,_z>*2 , *90 ) #declare _z=_z+1; #end #declare _y=_y+1; #end #declare _x=_x+1; #end texture{Tpipes} } // and displays it object {Trouchet} // and another dull background background { color rgb <.85,.80,.90>*0.3 }