/* Chain Generator for POV-Ray by Kevin Reid Based on the chain sample in the POV-Ray 3.1 documentation. Automatically generates segments of chain for use in your scenes. Use the Chain(startPt, numLinks) macro to create a chain. startPt is the origin of the chain and numLinks is the number of links in the chain. To emulate a chain affected by gravity, use several segments. The ChainLen(numLinks) macro will tell you how long each segment will be. You can define these values before including this file: Chain_RodThick Thickness of rod chain links are bent out of. Chain_LinkStretch Non-roundness of links. (Negative values produce an unstable-in-reality but interesting-looking chain.) Chain_LinkWidth Radius of end rounding. Chain_Wobble Randomness in rotation of links (in degrees). Chain_Slop Added to the spacing between links; use to create effects such as non-taut chain (positive slop), separate links (negative slop), and decorative rods (high negative slop). Also, Chain_Link_Length will be the actual spacing between links. */ #ifndef (Chain_RodThick) #declare Chain_RodThick = .13; #end #ifndef (Chain_LinkStretch) #declare Chain_LinkStretch = .5; #end #ifndef (Chain_LinkWidth) #declare Chain_LinkWidth = .27; #end #ifndef (Chain_Wobble) #declare Chain_Wobble = 30; #end #ifndef (Chain_Slop) #declare Chain_Slop = 0; #end // this is distance from inside of one end to inside of other #if (Chain_LinkStretch >= 0) #declare Chain_Link_Length = Chain_LinkStretch + Chain_LinkWidth * 2 - Chain_RodThick * 2 - Chain_Slop; #else #declare Chain_Link_Length = Chain_LinkWidth * 2 - Chain_RodThick * 2 - Chain_Slop; #end #declare Chain_RandSeed = seed(9); #declare Chain_EndSeg = difference { torus { Chain_LinkWidth, Chain_RodThick rotate x*-90 // so we can see it from the top } box { <-30, -30, -Chain_RodThick>, <30, 0, Chain_RodThick> } } #if (Chain_LinkStretch = 0) #declare Chain_Straight = box {-10000, -10001} #else #declare Chain_Straight = cylinder { <0, Chain_LinkStretch / 2, 0>, <0, -Chain_LinkStretch/2, 0>, Chain_RodThick } #end #if (Chain_LinkStretch >= 0) #declare Chain_Link = union { object { Chain_EndSeg translate y* Chain_LinkStretch/2 } object { Chain_EndSeg rotate x*180 translate y* -Chain_LinkStretch/2 } object { Chain_Straight translate x*Chain_LinkWidth } object { Chain_Straight translate -x*Chain_LinkWidth } } #else #declare Chain_Link = union { object { Chain_EndSeg translate y* -Chain_LinkStretch/2 } object { Chain_EndSeg rotate x*180 translate y* Chain_LinkStretch/2 } object { Chain_Straight translate x*Chain_LinkWidth } object { Chain_Straight translate -x*Chain_LinkWidth } rotate z* 90 } #end #macro Chain(startPoint, numLinks) union { #local linkid = 0; #while (linkid < numLinks) object { Chain_Link rotate y * (mod(linkid, 2) * 90) translate y * ( startPoint + Chain_Link_Length * (linkid + .5) ) } #local linkid = linkid + 1; #end } #end #macro ChainTwist(startPoint, numLinks, repTarget) union { #local linkid = 0; #local cangle = 0; #while (linkid < numLinks) #local cangle = cangle + (rand(Chain_RandSeed) - .5) + (sin(clock*6) / 4) * Chain_Wobble; object { Chain_Link rotate y * (mod(linkid, 2) * 90 + cangle) translate y * ( startPoint + Chain_Link_Length * (linkid + .5) ) } #local linkid = linkid + 1; #end } #declare repTarget = cangle; #end #macro ChainLen(numLinks) (numLinks * Chain_Link_Length) #end