I'm trying to make a scene with POV-ray, where I would like to make several objects of the same type but with different position, rotation and color. The object I want to make looks like
#declare Width = 30;
#declare Length = 120;
#declare Thickness = 4;
#declare TipHeight = 17;
// Single Beam------------
#declare Beam = union{
// beam
box {
<-Width/2, TipHeight, 0>,
< Width/2, TipHeight+Thickness, Length>
}
//Triangle head
prism { TipHeight TipHeight+Thickness , 4
<-Width/2, Length>,
< Width/2, Length>,
< 0, Length+Length/8>,
<-Width/2, Length>
}
// tip
cone {
<0, 0, Length>, 0
<0, TipHeight, Length>, TipHeight/2
}
}
What I do next is to create several of these beam-objects as
// Sine formed beams--------------
#declare EndValue = 20;
#declare MaxTranslation = 100;
#declare MaxRotation = 10; //degrees
#declare BeamsSine = union{
#for (Cntr, 0, EndValue, 1)
#local NormalizedValue = Cntr/EndValue;
object {Beam
rotate y*90
rotate -z*sin(NormalizedValue*2*pi)*MaxRotation
translate z*NormalizedValue*MaxTranslation
texture { pigment {
color Gray
}
}
}
#end
}
Adding #include colors.inc
in the very beginning and
object{ BeamsSine no_shadow }
light_source { <500, 50, 300> color White}
camera {
location <400, 100, 300>
look_at <0, 0, 0>
}
in the end you have a minimun working example.
Now comes my question: I would like to change the color of the tip-cone in the Beam-object by applying a gradient. The problem is that the gradient should be shifted depending on the value of the sine-function (which is used to determine the tilting angle).
From object oriented programming, I would write something like
class MYBEAM(position):
...make the beam
cone {
<0, 0, Length>, 0
<0, TipHeight, Length>, TipHeight/2
pigment{ gradient{cmap_depending_on_variable_"position"} }
}
and then create each object as
for i = 1:10
pos = calculate_position_function(i)
MYBEAM(pos)
...
end
I do not know how to do this in POV-ray! I do not manage to pass extra arguments into my beam-object. The only way I can think of is to use the function-declaration method, but it cannot return an object? (I only manage to get it to return a float).
I also tried to make a variable #declare mypos = 55;
before the definition of my object, and then update it in every loop by redefining it as #declare mypos = calculate_position_function(i)
before a new object is created. This does not work either (always uses the first position...).
Anyone have some idea/solution to my problem?
Defining custom functions, esp vector-valued ones, is somewhat little intuitive in povray; pls attend e.g.
http://povray.org/documentation/3.7.0/r3_3.html#r3_3_1_8_4
Concerning paradigmata, esp OO, and POV-Ray:
I will not dig deeply into that, generally I would advise not to delegate much application logic to POV-Ray, maybe with the exception of CSG, although even for that I'd prefer other tools, e.g. OpenSCAD.
POV-Ray's mesh2 is an excellent interface for a 3D pipeline; the meshes for primitives like Cones, Boxes etc can easily be generated with very little maths from within general purpose languages like C++ or python (the latter esp if used in conjunction with numpy) and with reasonable small effort be exported(A) as a mesh2
http://povray.org/documentation/3.7.0/r3_4.html#r3_4_5_2_4 ,
or, which is more versatile, the arbitrarily meshes exported to a custom XML format and then transformed into POV-Ray source by means of XSLT or programatically (B).
From my experience, implementing (A) takes about one and (B) takes about two working days to code, but that extra day is spent well.
Anyway - this produces a bunch of simplified "beams" in a loop: