1

我正在尝试使用 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 对象中尖端锥体的颜色。问题是梯度应该根据正弦函数的值(用于确定倾斜角)进行移动。

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

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)在创建新对象之前一样。这也不起作用(总是使用第一个位置......)。

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

4

1 回答 1

0
#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)作为网格2

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
于 2014-06-20T08:52:36.090 回答