/*************************************************************************
        COIL GENERATOR INCLUDE FILE FOR PERSISTENCE OF VISION 3.x
**************************************************************************

Created by Chris Colefax, 15 October 1997
Updated 18 July 1998: updated for POV-Ray 3.1

OVERVIEW: Creates a coil (helix) object between any two points.
USAGE: First specify the two points you wish to connect with the coil, eg:

   #declare coil_point1 = <0, 0, 0>;
   #declare coil_point2 = <0, 10, 0>;

Then include this file within an object {} statement, adding any
textures, transformations, etc. you want:

   object {#include "Coil.inc"
      texture {MyTexture}
      rotate y * clock * 360}

You can use the coils in CSG objects, or declare them and reuse them.

OPTIONS: In addition to the two coil points, you can use the following
options to modify the coil:

 -- OPTION ------- DEFAULT -- DESCRIPTION ---------------------------
  coil_type             3     Sets the style of the coil
                                 (choose from 1, 2, or 3)
  coil_radius           2     Sets the radius of the coil at point1
  coil_radius2          2     Sets the radius of the coil at point2
  coil_thickness        0.2   Sets the thickness of the coil at point1
  coil_thickness2       0.2   Sets the thickness of the coil at point2
  coil_revolutions      5     Sets the number of revolutions in the coil
  coil_smoothness       36    Sets the smoothness of coil types 1 and 2

Setting coil_type to 1 uses spheres to create the coil (which may be
non-continuous).  Setting coil_type to 2 joins the spheres with
cylinders, creating a continuous coil.  Setting coil_type to 3 uses
half-torii sections, which is usually smoother and takes up less memory
than types 1 and 2 (although it's not always as accurate, especially when
animating the coil).  You can set the number of spheres and/or cylinders
used for types 1 and 2 by changing the coil_smoothness option (which sets
the number of objects used *per revolution*).

If you do not specify coil_radius2 and/or coil_thickness2 they will be
the same as coil_radius and coil_thickness, ie. you only need to specify
them when you want to create a conical coil.

Setting coil_revolutions to a positive number creates a clockwise coil;
setting coil_revolutions to a negative number creates an anti-clockwise
coil.  Note that you can only use revolution multiples of .5 if you
are using coil_type 3, eg: coil_revolutions = 1.7 is truncated to 1.5

*************************************************************************/

// CHECK REQUIRED PARAMETERS AND ASSIGN DEFAULTS
// *********************************************
   #declare _CG_tempver = version; #version 3.0;
   #ifndef (coil_point1) #declare _CG_point1 = <0, 0, 0>; #else #declare _CG_point1 = <1, 1, 1> * coil_point1; #end
   #ifndef (coil_point2) #declare _CG_point2 = _CG_point1 + <0, 10, 0>; #else #declare _CG_point2 = <1, 1, 1> * coil_point2; #end
   #ifndef (coil_radius) #declare coil_radius = 2; #end
   #ifndef (coil_radius2) #declare coil_radius2 = coil_radius; #end
   #ifndef (coil_thickness) #declare coil_thickness = .2; #end
   #ifndef (coil_thickness2) #declare coil_thickness2 = coil_thickness; #end
   #ifndef (coil_revolutions) #declare _CG_revs = 5; #else #declare _CG_revs = coil_revolutions; #end
   #ifndef (coil_smoothness) #declare coil_smoothness = 36; #end
   #ifndef (coil_type) #declare coil_type = 3; #end

// CALC COIL POSITIONING VALUES
// ****************************
   #declare _CG_axis = _CG_point2 - _CG_point1;
   #declare _CG_length = vlength(_CG_axis);
   #declare _CG_rotx = vlength(_CG_axis * <1, 0, 1>); #if (_CG_rotx != 0 | _CG_axis.y != 0) #declare _CG_rotx = degrees(atan2(vlength(_CG_axis * <1, 0, 1>), _CG_axis.y)); #end
   #declare _CG_roty = _CG_axis.x; #if (_CG_roty != 0 | _CG_axis.z != 0) #declare _CG_roty = degrees(atan2(_CG_axis.x, _CG_axis.z)); #end
   #if (_CG_revs = 0) #declare _CG_revs = 1; #end
   #if (_CG_revs < 0) #declare _CG_revs = abs(_CG_revs); #declare _CG_flip = -1; #else #declare _CG_flip = 1; #end

// CREATE COIL
// ***********
   union { #switch (coil_type)

// CREATE COIL FROM SPHERES
// ************************
      #case (1)
         #declare _CG_heightint = _CG_length / (_CG_revs * coil_smoothness);
         #declare _CG_height = 0; #while (_CG_height <= _CG_length)
            #declare _CG_curpos = _CG_height / _CG_length;
            sphere {,
               coil_thickness + (_CG_curpos * (coil_thickness2 - coil_thickness))
               rotate y * _CG_curpos * 360 * _CG_revs}
            #declare _CG_height = _CG_height + _CG_heightint; #end
         #break

// CREATE COIL FROM SPHERES AND CYLINDERS
// **************************************
      #case (2)
         #declare _CG_heightint = _CG_length / (_CG_revs * coil_smoothness);
         #declare _CG_height = 0; #while (_CG_height <= _CG_length)
            #declare _CG_curpos = _CG_height / _CG_length;
            #if (_CG_height > 0)
               #declare _CG_oldpoint = _CG_curpoint;
               #declare _CG_oldradius = _CG_curradius;
            #end
            #declare _CG_curpoint = vrotate (
               ,
                y * _CG_curpos * 360 * _CG_revs)
            #declare _CG_curradius = coil_thickness + (_CG_curpos * (coil_thickness2 - coil_thickness));

            sphere {_CG_curpoint, _CG_curradius}
            #if (_CG_height > 0) cylinder {_CG_oldpoint, _CG_curpoint, _CG_oldradius} #end
            #declare _CG_height = _CG_height + _CG_heightint; #end
         #break

// CREATE COIL FROM TORII SECTIONS
// *******************************
      #else
         #declare _CG_height = 0; #while (_CG_height <= _CG_revs * 2)
            #declare _CG_curpos = _CG_height / (_CG_revs * 2);
            #if (_CG_height > 0)
               #declare _CG_oldpoint = _CG_curpoint;
               #declare _CG_oldradius = _CG_curradius;
            #end
            #declare _CG_curpoint = vrotate (
               ,
                y * _CG_curpos * 360 * _CG_revs);
            #declare _CG_curradius = coil_thickness + (_CG_curpos * (coil_thickness2 - coil_thickness));

            #if (_CG_height = 0)
               sphere {_CG_curpoint, _CG_curradius}
            #else
               sphere {_CG_curpoint, _CG_oldradius}
               #declare _CG_toraxis = _CG_curpoint - _CG_oldpoint;
               #declare _CG_torradius = vlength(_CG_toraxis) / 2;
               intersection {
                  torus {_CG_torradius, _CG_oldradius}
                  box {<-(_CG_torradius + _CG_oldradius), -_CG_oldradius, -(_CG_torradius + _CG_oldradius)>,
                       <(_CG_torradius + _CG_oldradius), _CG_oldradius, 0>
                       #if (mod(_CG_height, 2) = 0) scale <1, 1, -1> #end
                       }
                  translate x * _CG_torradius
                  rotate z * degrees(atan2(_CG_toraxis.y, _CG_toraxis.x))
                  translate _CG_oldpoint}
            #end
         #declare _CG_height = _CG_height + 1; #end
      #end

// POSITION COIL
// *************
   scale <1, 1, _CG_flip>
   rotate <_CG_rotx, _CG_roty, 0>
   translate _CG_point1}

   #version _CG_tempver;

    Source: geocities.com/siliconvalley/lakes/1434/download

               ( geocities.com/siliconvalley/lakes/1434)                   ( geocities.com/siliconvalley/lakes)                   ( geocities.com/siliconvalley)