// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Copyright 2000 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" default { finish { ambient color Black diffuse 1 } } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Parameters that controls the shapes #declare Res = 2; #declare Xspacing = 1/Res; #declare Zspacing = 1/Res; #declare Xnr = 50*Res; #declare Znr = 50*Res; #declare CylRadius = 0.2/Res; #declare G_CylRadius = CylRadius*1.2; #declare Ampl = 10; #declare Freq = 1; #declare Damp = 3; // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Some tools #declare SquashFn = function(T, S) { select(S, -0.5, 0.5)*(tanh(abs(S)*T) - 1) } #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 // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Patterns and shape functions #declare AgateFn = TransformFunction( function { pattern { agate } }, transform { scale <1, 1, 1>*70 } ) #declare SinFn = function(R) { Ampl*sin(R)/(R + Damp) } #declare Fn = function(x, z) { SinFn(Freq*f_r(x, 0, z)) + 2*AgateFn(x, 0, z) } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // Differentiated function #declare H = 1E-5; #declare H2 = H*2; #declare DerZ_Fn = function(x, z) { (Fn(x, z + H) - Fn(x, z - H))/H2 } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // The many "hoses" #declare XmodFn = function(X) { mod(X, Xspacing) + select(X, 0.5, -0.5)*Xspacing } #declare CylZ_Fn = function(x, y, z, Xmod) { f_sphere( Xmod, (y - Fn(x, z)) /sqrt(1 + pow(DerZ_Fn(x, z), 2)), // Correct the cross section 0, CylRadius ) } isosurface { function { CylZ_Fn(x - XmodFn(x), y, z, XmodFn(x)) } max_gradient 4 contained_by { box { -*, * } } pigment { color rgb <0.90, 0.85, 0.90> } } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // The "groovy" surface below #declare G_CylZ_Fn = function(x, y, z, Xmod) { f_sphere( Xmod, (y - Fn(x, z)) /sqrt(1 + pow(DerZ_Fn(x, z), 2)), // Correct the cross section 0, G_CylRadius ) } #declare G_TempZ_Fn = function(x, y, z, Xmod) { G_CylZ_Fn(x - Xmod, y, z, Xmod) } #declare G_ZFn = function { G_CylZ_Fn(x - XmodFn(x), y, z, XmodFn(x)) } isosurface { function { SquashFn(y - Fn(x, z), 15) // Add surface +SquashFn(G_ZFn(x, y, z), -15) // Subtract "grooves" } threshold -0.5 max_gradient 10 contained_by { box { -*, * } } pigment { color White } } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // A lonely little sphere sphere { <3.3, 3.7, 1>, 0.4 pigment { color White } } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10 // The photo gear light_source { <4, 4, 7>*15 color rgb <0.87, 0.80, 0.60> shadowless } light_source { < -1, 4, -2>*40 color rgb <0.25, 0.25, 0.40> shadowless } camera { location < 4, 4, -5>*2.5 look_at < 0, 0.5, 0> angle 55 } background { color rgb <0.3, 0.8, 1.0> } // ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7 ======= 8 ======= 9 ======= 10