// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Copyright 2002-2003 by Tor Olav Kristensen // Email: t o r . o l a v . k [_A_T_] g m a i l . c o m // http://subcube.com // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 #version 3.5; #include "colors.inc" #include "functions.inc" // For f_torus() #include "textures.inc" // For New_Penny and Soft_Silver global_settings { assumed_gamma 2.2 ambient_light color 0.5*White } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Transformation macros and blobbing function #macro Tilt_Trans(vTilt) #local v0 = vnormalize(vTilt); #local X = v0.x; #local Y = v0.y; #local Z = v0.z; #if (abs(Y) = 1) #if (Y = 1) #local Transform = transform { } #else #local Transform = transform { rotate 180*z } #end // if #else #local T = (Y - 1)/(X*X + Z*Z); #local Transform = transform { matrix } #end // if transform { Transform } #end // macro Tilt_Trans #macro TransformFunction(Fn, Transform) #local TT = function { transform { Transform inverse } } function { Fn(TT(x, y, z).x, TT(x, y, z).y, TT(x, y, z).z) } #end // macro TransformFunction #declare SquashFn = function(Fn, S) { select(S, -1, 1)*(1/(1 + exp(-abs(S)*Fn)) - 1) } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // The torus functions #declare MajR = 20; #declare MinR = 6; #declare MicR = 1.1; #declare MidR = 0.8; #declare MieR = 0.70; #declare NrOfRings = 4; #declare TorusFnArray1 = array[NrOfRings]; #declare TorusFnArray2 = array[NrOfRings]; #declare TorusFnArray3 = array[NrOfRings]; #declare TorusFnArray4 = array[NrOfRings]; #declare dAngle = 360/NrOfRings; #declare Cnt = 0; #while (Cnt < NrOfRings) #declare TorusFnArray1[Cnt] = TransformFunction( function { f_torus(x, y, z, MajR, MicR) }, transform { Tilt_Trans(< MinR, MajR, 0>) translate MinR*z rotate Cnt*dAngle*y } ) #declare TorusFnArray2[Cnt] = TransformFunction( function { f_torus(x, y, z, MajR, MicR) }, transform { Tilt_Trans(<-MinR, MajR, 0>) translate MinR*z rotate Cnt*dAngle*y } ) #declare TorusFnArray3[Cnt] = TransformFunction( function { f_torus(x, y, z, MajR, MidR) }, transform { Tilt_Trans(< MinR, MajR, 0>) translate MinR*z rotate Cnt*dAngle*y } ) #declare TorusFnArray4[Cnt] = TransformFunction( function { f_torus(x, y, z, MajR, MidR) }, transform { Tilt_Trans(<-MinR, MajR, 0>) translate MinR*z rotate Cnt*dAngle*y } ) #declare Cnt = Cnt + 1; #end // while // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // The two isosurfaces isosurface { function { SquashFn(f_torus(x, y, z, MajR, MinR), 6) #declare Cnt = 0; #while (Cnt < NrOfRings) +SquashFn(TorusFnArray1[Cnt](x, y, z), -6) +SquashFn(TorusFnArray2[Cnt](x, y, z), -6) #declare Cnt = Cnt + 1; #end // while } threshold -0.5 max_gradient 5 accuracy 1e-8 contained_by { box { -, } } texture { New_Penny } } isosurface { function { 0 #declare Cnt = 0; #while (Cnt < NrOfRings) +SquashFn(TorusFnArray3[Cnt](x, y, z), 6) +SquashFn(TorusFnArray4[Cnt](x, y, z), 6) #declare Cnt = Cnt + 1; #end // while } threshold -0.5 max_gradient 5 accuracy 1e-8 contained_by { box { -, } } texture { Soft_Silver } } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 light_source { <-5, 2, -8>*40 color White shadowless } sky_sphere { pigment { gradient y color_map { [ 0.0 color rgb <0.7, 0.7, 1.0> ] [ 1.0 color blue 0.5 ] } } } camera { location <0, 1, -1>*50 look_at <0, -2, 0> } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10