将参数传递给POV-ray对象

时间:2014-06-04 12:03:30

标签: povray

我正在尝试用POV-ray创建一个场景,我想制作几个相同类型但具有不同位置,旋转和颜色的物体。我想要制作的对象看起来像

#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
  }
}

接下来我要做的是创建几个梁对象

// 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              
} 

在开头添加#include colors.inc

object{ BeamsSine no_shadow }
light_source { <500, 50, 300> color White} 
camera {
    location <400, 100, 300>
    look_at  <0, 0,  0>
}

最后你有一个最小化的工作例子。

现在我的问题是:我想通过应用渐变来改变Beam-object中尖锥的颜色。问题是应该根据正弦函数的值(用于确定倾斜角度)来移动梯度。

从面向对象的编程,我会写类似

的东西
class MYBEAM(position):
    ...make the beam
    cone {
        <0, 0, Length>, 0
        <0, TipHeight, Length>, TipHeight/2
        pigment{ gradient{cmap_depending_on_variable_"position"}  }
         }

然后将每个对象创建为

for i = 1:10
    pos = calculate_position_function(i)
    MYBEAM(pos)
    ...
end

我不知道如何在POV-ray中做到这一点!我没有设法将额外的参数传递给我的beam-object。我能想到的唯一方法是使用函数声明方法,但它不能返回一个对象? (我只是设法让它返回浮动)。

我还尝试在定义对象之前创建变量#declare mypos = 55;,然后在创建新对象之前通过将其重新定义为#declare mypos = calculate_position_function(i)来在每个循环中更新它。这也不起作用(总是使用第一个位置......)。

任何人对我的问题都有一些想法/解决方案吗?

1 个答案:

答案 0 :(得分:0)

#declare mypos = calculate_position_function(i)

定义自定义函数,尤其是向量值函数,在povray中有点直观;请参加,例如。

http://povray.org/documentation/3.7.0/r3_3.html#r3_3_1_8_4


关于paradigmata,esp OO和POV-Ray:

我不会深入研究,通常我会建议不要将很多应用程序逻辑委托给POV-Ray,可能除了CSG之外,尽管如此,我更喜欢其他工具,例如OpenSCAD。

POV-Ray的mesh2是3D流水线的绝佳界面;像Cones,Boxes等基元的网格很容易用C ++或python等通用语言中的非常少的数学生成(后者esp如果与numpy一起使用)并且合理的小努力被导出(A)作为mesh2

http://povray.org/documentation/3.7.0/r3_4.html#r3_4_5_2_4

或更通用的,任意网格导出为自定义XML格式,然后通过XSLT或编程(B)转换为POV-Ray源。

根据我的经验,实施(A)需要大约一个,而(B)需要大约两个工作日来编码,但是额外的一天花得很好。


无论如何 - 这会在循环中产生一堆简化的“光束”:

#include "colors.inc"
#declare BEAM_LENGTH = 200;
#declare CUT_RADIUS = 10;
#declare NUM_BEAMS = 11;

camera { 
    perspective
    location <0, 1.8, -100> 
    look_at  0
    up y
    angle 30 
}

sky_sphere {
    pigment {
        color Blue
    }
    emission rgb <0.5,0.5,1>
}

light_source { 
    <0, 100, -100>, 
}

plane { 
    +y, 0 
    texture {
        pigment { color Green }
    }
}


#declare Beam =  cone  { 
    // top
    0, 0,
    // bottom
    -y * BEAM_LENGTH, CUT_RADIUS
}

#for (i, 0, NUM_BEAMS-1, 1)
    #declare q = i/NUM_BEAMS;
    #declare r = 100;
    #declare theta = pi/8; 
    #declare phi = q*2*pi;
    #declare pos = <r*sin(theta)*cos(phi), r*cos(theta), r*sin(theta)*sin(phi)>;

    #switch (mod(i,3))
        #case (0) 
            #declare d = <q,.1,.1,0>; 
        #break
        #case (1) 
            #declare d = <.1,q,.1,0>;  
        #break
        #case (2) 
            #declare d = <.1,.1,q,0>;  
        #break
    #end // switch

    object { Beam
        translate pos
        texture {
            pigment {
                rgbt d + <0,0,0,q/2>
            }
        }
    }
#end // for