
// Glenn's POV-Ray Shapes Include File
// first concept 2-June-97
// last update 29-Aug-02
// copyright 1997-2002 Glenn McCarter (glenn@mccarters.net)
// This file does not render.  #include "GShapes31.inc" in another .pov file
//
// A collection of various shapes:
//     RoundedBox(Roundedness)  unit box; centered on origin; all corners and edges rounded
//     RoundedHalfBox(Roundedness) same, but bottom (-Z) is flat
//     RoundedBox2(Xlength,Ylength,Zlength,Radius) starts at <0,0,0> extending into positive zone
//     RoundedHalfBox2(Xlength,Ylength,Zlength,Radius) starts at <0,0,0> extending into positive zone
//     FlatEgg(Radius1,Radius2,Distance,Height)
//        two cylinders, connected with flat sides, like two pulleys with belt
//        lies on XY plane
//     CurveTube(Major,Minor,Arc) // extends into +X, curves towards +Z
//
// Uses RH coordinate reference system
// For POV-Ray version 3.1+

//===============================================
//             Textures
//===============================================


//===============================================
//       Objects
//===============================================

// --------- Rounded Box --------------
// Usage: copy these lines to your .pov file:
//
// #include "GShapes31.inc"
// object { RoundedBox(.2) texture...} // roundness, range 0 to .5, larger = more rounded
//
// The default size is always 1x 1y 1z, regardless of
// the Roundness factor.

// set defaults
//#ifndef ( Roundness )
//#declare Roundness = .2;
//#end

//#declare RA = Roundness/2; // sph/cyl rads
//#declare RB = .5-Roundness/2; // higher roundness = smaller sph/cyl centers

#macro RoundedBox(Roundness)
	#local RA = Roundness/2; // sph/cyl rads
	#local RB = .5-Roundness/2; // higher roundness = smaller sph/cyl centers

	merge {
		box { <-RB,-RB,-.5>,<RB,RB,.5> }
		box { <-RB,-.5,-RB>,<RB,.5,RB> }
		box { <-.5,-RB,-RB>,<.5,RB,RB> }

		sphere { <-RB,-RB,-RB>, RA }
		sphere { < RB,-RB,-RB>, RA }
		sphere { <-RB, RB,-RB>, RA }
		sphere { <-RB,-RB, RB>, RA }

		sphere { < RB, RB,-RB>, RA }
		sphere { < RB,-RB, RB>, RA }
		sphere { <-RB, RB, RB>, RA }
		sphere { < RB, RB, RB>, RA }

		cylinder { <-RB,-RB,-RB>,<-RB,-RB, RB>,RA }
		cylinder { <-RB, RB,-RB>,<-RB, RB, RB>,RA }
		cylinder { < RB,-RB,-RB>,< RB,-RB, RB>,RA }
		cylinder { < RB, RB,-RB>,< RB, RB, RB>,RA }

		cylinder { <-RB,-RB,-RB>,<-RB, RB,-RB>,RA }
		cylinder { < RB,-RB,-RB>,< RB, RB,-RB>,RA }
		cylinder { <-RB,-RB, RB>,<-RB, RB, RB>,RA }
		cylinder { < RB,-RB, RB>,< RB, RB, RB>,RA }

		cylinder { <-RB,-RB,-RB>,< RB,-RB,-RB>,RA }
		cylinder { <-RB, RB,-RB>,< RB, RB,-RB>,RA }
		cylinder { <-RB,-RB, RB>,< RB,-RB, RB>,RA }
		cylinder { <-RB, RB, RB>,< RB, RB, RB>,RA }
	}
#end
#macro RoundedHalfBox(Roundness)
	#local RA = Roundness/2; // sph/cyl rads
	#local RB = .5-Roundness/2; // higher roundness = smaller sph/cyl centers
	union {
		box { <-RB,-RB,-.5>,<RB,RB,.5> }
		box { <-RB,-.5,-.5>,<RB,.5,RB> }
		box { <-.5,-RB,-.5>,<.5,RB,RB> }

//		sphere { <-RB,-RB,-RB>, RA }
//		sphere { < RB,-RB,-RB>, RA }
//		sphere { <-RB, RB,-RB>, RA }
		sphere { <-RB,-RB, RB>, RA }

//		sphere { < RB, RB,-RB>, RA }
		sphere { < RB,-RB, RB>, RA }
		sphere { <-RB, RB, RB>, RA }
		sphere { < RB, RB, RB>, RA }

		cylinder { <-RB,-RB,-.5>,<-RB,-RB, RB>,RA }
		cylinder { <-RB, RB,-.5>,<-RB, RB, RB>,RA }
		cylinder { < RB,-RB,-.5>,< RB,-RB, RB>,RA }
		cylinder { < RB, RB,-.5>,< RB, RB, RB>,RA }

//		cylinder { <-RB,-RB,-RB>,<-RB, RB,-RB>,RA }
//		cylinder { < RB,-RB,-RB>,< RB, RB,-RB>,RA }
		cylinder { <-RB,-RB, RB>,<-RB, RB, RB>,RA }
		cylinder { < RB,-RB, RB>,< RB, RB, RB>,RA }

//		cylinder { <-RB,-RB,-RB>,< RB,-RB,-RB>,RA }
//		cylinder { <-RB, RB,-RB>,< RB, RB,-RB>,RA }
		cylinder { <-RB,-RB, RB>,< RB,-RB, RB>,RA }
		cylinder { <-RB, RB, RB>,< RB, RB, RB>,RA }
	}
#end


#macro RoundedBox2(XX,YY,ZZ,Radius)
	#local X2 = XX/2;
	#local Y2 = YY/2;
	#local Z2 = ZZ/2;
	#local RA = Radius; // sph/cyl rads
	#local RX = XX-Radius; // higher roundness = smaller sph/cyl centers
	#local RY = YY-Radius;
	#local RZ = ZZ-Radius;
	merge {
		box { <RA,RA,0>,<RX,RY,ZZ> }
		box { <RA,0,RA>,<RX,YY,RZ> }
		box { <0,RA,RA>,<XX,RY,RZ> }

		sphere { < RA, RA, RA>, RA } // Y=0 plane
		sphere { < RA, RA, RZ>, RA }
		sphere { < RX, RA, RA>, RA }
		sphere { < RX, RA, RZ>, RA }

		sphere { < RA, RY, RA>, RA } // rear plane
		sphere { < RA, RY, RA>, RA }
		sphere { < RX, RY, RZ>, RA }
		sphere { < RX, RY, RZ>, RA }

		cylinder { < RA, RA, RA>,< RX, RA, RA>, RA } // Y=0 plane
		cylinder { < RA, RA, RZ>,< RX, RA, RZ>, RA }
		cylinder { < RA, RA, RA>,< RA, RA, RZ>, RA }
		cylinder { < RX, RA, RA>,< RX, RA, RZ>, RA }

		cylinder { < RA, RY, RA>,< RX, RY, RA>, RA } // rear plane
		cylinder { < RA, RY, RZ>,< RX, RY, RZ>, RA }
		cylinder { < RA, RY, RA>,< RA, RY, RZ>, RA }
		cylinder { < RA, RY, RA>,< RA, RY, RZ>, RA }

		cylinder { < RA, RA, RA>,< RA, RY, RA>, RA } // Y-axis connectors
		cylinder { < RA, RA, RZ>,< RA, RY, RZ>, RA }
		cylinder { < RX, RA, RA>,< RX, RY, RA>, RA }
		cylinder { < RX, RA, RZ>,< RX, RY, RZ>, RA }
	}
#end

#macro RoundedHalfBox2(XX,YY,ZZ,Radius)
	#local X2 = XX/2;
	#local Y2 = YY/2;
	#local Z2 = ZZ/2;
	#local RA = Radius; // sph/cyl rads
	#local RX = XX-Radius; // higher roundness = smaller sph/cyl centers
	#local RY = YY-Radius;
	#local RZ = ZZ-Radius;
	merge {
		box { <RA,RA,0>,<RX,RY,ZZ> }
		box { <RA,0,RA>,<RX,YY,RZ> }
		box { <0,RA,RA>,<XX,RY,RZ> }

//		sphere { < RA, RA, RA>, RA } // Y=0 plane
		sphere { < RA, RA, RZ>, RA }
//		sphere { < RX, RA, RA>, RA }
		sphere { < RX, RA, RZ>, RA }

//		sphere { < RA, RY, RA>, RA } // rear plane
//		sphere { < RA, RY, RA>, RA }
		sphere { < RX, RY, RZ>, RA }
		sphere { < RX, RY, RZ>, RA }

//		cylinder { < RA, RA, RA>,< RX, RA, RA>, RA } // Y=0 plane
		cylinder { < RA, RA, RZ>,< RX, RA, RZ>, RA }
		cylinder { < RA, RA, RA>,< RA, RA, RZ>, RA }
		cylinder { < RX, RA, RA>,< RX, RA, RZ>, RA }

//		cylinder { < RA, RY, RA>,< RX, RY, RA>, RA } // rear plane
		cylinder { < RA, RY, RZ>,< RX, RY, RZ>, RA }
		cylinder { < RA, RY, RA>,< RA, RY, RZ>, RA }
		cylinder { < RA, RY, RA>,< RA, RY, RZ>, RA }

//		cylinder { < RA, RA, RA>,< RA, RY, RA>, RA } // Y-axis connectors
		cylinder { < RA, RA, RZ>,< RA, RY, RZ>, RA }
//		cylinder { < RX, RA, RA>,< RX, RY, RA>, RA }
		cylinder { < RX, RA, RZ>,< RX, RY, RZ>, RA }
	}
#end


// --------- FlatEgg --------------
/*
FlatEgg(Radius1,Radius2,Distance,Height)
Usage: copy these lines to your .pov file:

#include "GShapes31.inc"
// FlatEgg(Radius1,Radius2,Distance,Height)
object { FlatEgg(2.0,1.3,2.0,0.2) texture...}

*/
// Note, the structure sits on the XY plane,
// with the first cylinder at the origin,
// the second cylinder in the +X direction,
// and height extending into +Z

/*
// set defaults
#ifndef ( Radius1 )
#declare Radius1 = 1;
#end
#ifndef ( Radius2 )
#declare Radius2 = 1;
#end
*/

#macro FlatEgg(Radius1,Radius2,Distance,Height)
	#local D = Distance;
	#local R1 = Radius1; // cyl rad
	#local R2 = Radius2; // cyl rad
	#local RD = R1 - R2;
	#local KeyL = sqrt(D*D-RD*RD);
	#local Alpha = degrees( asin(RD/D) );
	merge {
		cylinder { <0,0,0>,<0,0,Height>,R1 }
		cylinder { <0,0,0>,<0,0,Height>,R2 translate <D,0,0> }
		difference {
			box {
				<0,-RD,0>,<KeyL,R2,Height+.2>
				translate <-KeyL,0,0> rotate <0,0,-Alpha> translate <D,0,0>
			}
			box { <-R1,-R1,-1>,<D,0,Height> }
		}
		difference {
			box {
				<0,RD,0>,<KeyL,-R2,Height>
				translate <-KeyL,0,0> rotate <0,0,Alpha> translate <D,0,0>
			}
			box { <-R1,R1,-1>,<D,0,Height+1> }
		}
	}
#end


// --------- CurveTube --------------

#macro CurveTube(Major,Minor,Arc)
	difference {
		torus { Major,Minor translate <0,0,Major> }
		box { <0,-Minor-1,-Minor-1>,<-Major-Minor-1,Minor+1,Major*2+Minor+1> } // cut off -X
		box { <0,-Minor-1,-Major-Minor-1>,
			<Major+Minor+1,Minor+1,Major+Minor+1>
			rotate <0,-Arc,0>
			translate <0,0,Major>
		} // cut off arc angle
	} // end difference
#end

