【问题标题】:Passing arguments into POV-ray objects将参数传递给 POV 射线对象
【发布时间】:2020-04-05 00:03:43
【问题描述】:

我正在尝试使用 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) 来更新它。这也不起作用(总是使用第一个位置...)。

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

【问题讨论】:

    标签: povray


    【解决方案1】:
    #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) 大约需要 1 个工作日,(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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-23
      相关资源
      最近更新 更多