// Last edited on 2022-04-06 23:20:19 by stolfi #macro test_tube( od, ht, hue ) // A test tube with outr diameter {od} and total height {ht}. // Bottom at origin, axis is {Z}-axis. // The {hue} specifies the color of the liquid inside. #local thk = 0.75; // Wall thickness. #local orad = od/2; // Outer radius. #local irad = od/2 - thk; // Inner radius. #local liq_ht = 0.40*ht; // Height of liquid from outer bottom of tube. #local hur = hue*2*pi; #local clr = < 1 + sin(hur), 1 + sin(hur + 2*pi/3), 1 + sin(hur + 4*pi/3) >; #local cmax = max(clr.x, max(clr.y, clr.z)); #local cmin = min(clr.x, min(clr.y, clr.z)); #local clr = (clr - cmin*<1,1,1>)/(cmax - cmin); #local tx_glass = texture_transparent( < 1.000, 1.000, 1.000 >, 0.900 ) #local tx_invis = texture_invisible() #local tube = difference{ merge{ sphere{ < 0, 0, orad >, orad-eps } cylinder{ < 0, 0, orad >, <0, 0, ht-eps >, orad-eps } texture{ tx_glass } } merge{ merge{ sphere{ < 0, 0, orad >, irad+eps } cylinder{ < 0, 0, orad >, <0, 0, liq_ht+eps >, irad+eps } texture{ tx_invis } } cylinder{ < 0, 0, liq_ht-eps >, <0, 0, ht+eps >, irad+eps texture{ tx_glass } } } interior{ ior 1.470 } } #local liquid = merge{ sphere{ < 0, 0, orad >, irad-eps } cylinder{ < 0, 0, orad >, <0, 0, liq_ht-eps >, irad-eps } texture{ tx_invis } interior{ ior 1.333 fade_power 1000 // Exponential absorption. fade_distance irad/2 // Fall to {1/e^4} after crossing tube. fade_color clr } } union{ object{ tube } object{ liquid } } #end