Parametric spline functions© Mike Williams 2002, 2003, 2004 

I've created all the images on this page both with Ingo's param.inc macro. (See param.inc for details), and more slowly, by using real parametric isosurfaces. The zip file at the end of the page contains both sets of source files.  
#declare Fx = function(x,y) {S(u).x + sin(v)} #declare Fy = function(x,y) {S(u).y + cos(v)} #declare Fz = function(x,y) {S(u).z} #include "param.inc" object {Parametric(Fx,Fy,Fz, <0,pi>,<17,pi>,100,20,"") pigment {rgbt <1,1,1,0.4>} finish {phong 0.5 phong_size 10} no_shadow } 
The spline technique shown on the previous page doesn't work with splines that have loops in them.
The problem is that we were using the spline control points as our x coordinate
and expressing y and z in terms of that x.
The sequence of control points can't loop back on itself. The way to follow 3d splines that contain loops is to use all three of the spline dimensions to specify the path of the spline, and express x, y, and z in terms of a fourth variable, call it "u", which follows the control points. So what we need is a parametric isosurface. In this case "u" follows the spline control points, and x, y, z are expressed in terms of u like S(u).x, S(u).y, S(u).z. On its own that would give an infinitely thin string that follows the spline path. We can fatten it out by adding some terms in a second variable "v" which describe how far the surface is from the path. Once again I have made the isosurface transparent and drawn the actual spline path inside it in yellow. 
#declare Fx = function(x,y) {u} #declare Fy = function(x,y) {S(u).y + S2(v).y} #declare Fz = function(x,y) {S(u).z + S2(v).z} 
Bent prismThis parametric isosurface is equivalent to taking a prism object and bending it to follow an open spline path.In this case, the prism is a five pointed star with cubic interpolation, given by the spline function S2(). The curved path along which the prism is bent is given by the spline function S(). 
#declare Fx = function(x,y) {(S(u).x * sin(v)/2)} #declare Fy = function(x,y) {u} #declare Fz = function(x,y) {(S(u).x * cos(v)/2)} 
LatheThe following examples will be based on this goblet.I could have created this goblet as a lathe object, as a sor object or I could have used a nonparametric isosurface. However, I've used a parametric isosurface so that I can perform the alterations shown in the later examples. The spline function S() is a onedimensional spline which gives the profile of the goblet. 
#declare Fx = function(x,y) {u} #declare Fy = function(x,y) {S(u).y * S2(v).y} #declare Fz = function(x,y) {S(u).y * S2(v).z} 
Prismatic latheThis example is a combination of a prism and a lathe.The profile of the goblet is given by the onedimensional spline function S(), and the starshaped cross section is given by the twodimensional spline function S2(). 
#declare Fx = function(x,y) {(S(u).x * sin(v)/2) + S2(u).x} #declare Fy = function(x,y) {u} #declare Fz = function(x,y) {(S(u).x * cos(v)/2) + S2(u).z} 
Bent latheIn the same way that a prism can be bent along a curved spline, it's possible to bend a lathe.The profile of the goblet is given by the onedimensional spline function S(), and it is then bent along the twodimensional spline S2(). 
#declare Fx = function(x,y) {(S(u).x * sin(v)/2)} #declare Fy = function(x,y) {u} #declare Fz = function(x,y) {(S(u).z * cos(v)/2)} 
Twoway latheIn this scene, the object almost looks like a lathe, but it has a different profile in the x direction from the z direction.The x profile is given by the x component of the twodimensional spline function S(), and the z profile is given by the z component of the same spline function. 
Fourway latheIt's possible to extend this idea to a shape that uses four different splines to control the profile in the +x, x, +z and z directions.This is achieved by mutiplying one x spline function by (v<=pi) and the other by (v>pi). The comparison operators return 0 for false and 1 for true, so the sum switches from being one spline to the other when v becomes pi.
Similarly the z spline functions are multiplied by (cos(v)<=0) and (cos(v)>0), which switch
when v=pi/2 and switch back when v=3*pi/2. #declare Fx = function(x,y) {sin(v)/2 * (S(u).x*(v<=pi) + S2(u).x*(v>pi)) } #declare Fy = function(x,y) {u} #declare Fz = function(x,y) {cos(v)/2 * (S(u).z*(cos(v)<=0) + S2(u).z*(cos(v)>0))}I've drawn in the four splines on one copy of the surface.  

Download a zip file containing the POV source files for all the images that appear on this page. 
