将参数传递给POV-ray对象



我正在尝试用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>
}

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

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

在面向对象编程中,我会写像

这样的东西
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中做到这一点!我没有设法传递额外的参数到我的光束对象。我能想到的唯一方法是使用函数声明方法,但它不能返回对象?(我只设法让它返回一个浮点数)。

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

谁对我的问题有什么想法/解决办法?
#declare mypos = calculate_position_function(i)

定义自定义函数,特别是向量值函数,在povray中有点不直观;请出席

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


关于范式,特别是OO和POV-Ray:

我不会深入研究这个问题,通常我建议不要将太多的应用程序逻辑委托给POV-Ray,也许除了CSG,尽管我更喜欢其他工具,例如OpenSCAD。

POV-Ray的mesh2是一个很好的3D管道接口;像锥体,盒子等原语的网格可以很容易地从通用语言(如c++或python)中生成很少的数学(后者特别是如果与numpy结合使用),并通过合理的小努力导出(A)作为mes2

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

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

根据我的经验,实现(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

最新更新