// Persistence of Vision Ray Tracer Scene Description File // File: elliptic_torus.pov // Vers: 3.5 // Desc: Sample scene for elliptic torus macros, as spere_sweep, and as blob. // Date: 03/2006 // Auth: Bruno Cabasson // #version 3.5; #include "colors.inc" #include "glass.inc" global_settings { assumed_gamma 1.0 } // ---------------------------------------- camera { location <0.0, 0.5, -4.0> direction 1.5*z right x*image_width/image_height look_at <0.0, 0.0, 0.0> } sky_sphere { pigment { gradient y color_map { [0.0 rgb <0.6,0.7,1.0>] [0.7 rgb <0.0,0.1,0.8>] } } } light_source { <0, 0, 0> // light's position (translated below) color rgb <1, 1, 1> // light's color translate <-30, 30, -30> } // ---------------------------------------- plane { y, -2 pigment { color rgb <0.7,0.5,0.3> } } // -------------------------------------------------------------------------------------- #macro SW_GenerateEllipticSplinePoints ( _center_point, _major, _minor, _radius, _normal, _major_dir, _start_angle, _end_angle, // These are the 'parametric angles' (used to sample the ellipse) _nb_points ) #local delta_angle = _end_angle - _start_angle; #local major_dir = vnormalize(_major_dir); #local i=0; #while (i<=_nb_points) // Find position of current point #local rel_time = i/_nb_points; #local cur_angle = _start_angle + rel_time*delta_angle; #local cur_angle_rad = radians(cur_angle); #local cur_x = _major*cos(cur_angle_rad); #local cur_y = _minor*sin(cur_angle_rad); #local cur_radius = vlength(); #local theta = degrees(atan2(cur_y, cur_x)); #declare p = _center_point + vaxis_rotate(cur_radius*major_dir, _normal, theta); #debug str(i, 0, 0) // Generate the spline control point #if (i < _nb_points) p, _radius, #else p, _radius #end #local i=i+1; #end #end // -------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------- #macro sw_elliptical_torus (_major, _minor, _radius, _tolerance) sphere_sweep { #local NB_POINTS = 20; // Enough to sample an ellipse. A lower value would not yield an accurate sphere_sweep #declare OFFSET = degrees(2*pi/NB_POINTS); cubic_spline NB_POINTS+3, SW_GenerateEllipticSplinePoints (0, _major, _minor, _radius, y, x, -OFFSET, 360+OFFSET, NB_POINTS+2) tolerance _tolerance } #end // -------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------- #macro elliptical_torus (_major, _minor, _radius) blob { // We use the parametric equation of an ellipse to sample the perimeter and deposit pheres // where needed. #local THRES = 0.65; #local DENSITY_PER_RADIUS = 20; // density per curved length unit #declare OVERSAMPLING_FACTOR = 10; // For instance... // First, determine the radius of the spheres #local k_ = 1.2185; // Determined by hand so that a true sphere with radius R is about to disappear when .... #local radius_ = k_*_radius; // Second, compute the number of samples for the perimeter. #local perimeter_ = 2*pi*sqrt((_major*_major + _minor*_minor)/2); #local nb_spheres_ = int(perimeter_/_radius)*DENSITY_PER_RADIUS; #local nb_samples_ = nb_spheres_ * OVERSAMPLING_FACTOR; // Determine length of segment between spheres #local segment_ = radius_/DENSITY_PER_RADIUS; // Third: loop over the samples and intergrate perimeter. Drop a sphere where needed. #local l_ = 0; // length of protion of perimeter travelled so far. #local delta_ = 2*pi/nb_samples_; #local p0_ = <1, 0>; #local i=0; #while (i; // Compute length travelled so far #local sample_ = vlength (p1_ - p0_); #local l_ = l_ + sample_; // Check if segment_ has been travelled. If so, drop a sphere #if (l_ >= segment_) sphere {, radius_, 1} #local l_ = mod(l_, segment_); #end // Prepare next loop #local p0_ = p1_; #local i=i+1; #end threshold THRES sturm } #end // -------------------------------------------------------------------------------------- object {elliptical_torus(1.2, 0.3, 0.025) pigment {Red} rotate -90*x translate -0.7*y} object { elliptical_torus(0.3, 0.3, 0.1) hollow pigment {rgbt 1} interior { media { scattering {0, 1} } } rotate -90*x } object { elliptical_torus(0.25, 0.3, 0.1) hollow pigment {rgbf 0.98} finish {F_Glass8} interior { ior 1.3 fade_color color Col_Ruby_05 fade_power 1001 fade_distance 0.05 } rotate 90*x translate x/2+y/2-2*z } object { sw_elliptical_torus(0.25, 0.3, 0.1, 0.01) hollow pigment {rgbf 0.98} finish {F_Glass8} interior { ior 1.3 fade_color Col_Sapphire_03 fade_power 1001 fade_distance 0.05 } rotate 90*x translate -x/2+y/2-2*z }