首页 > 解决方案 > gnuplot:如何避免依赖视角的半透明 3D 表面?

问题描述

我偶然发现了以下内容。如果我绘制一个立方体,例如使用pm3d并将边定义为半透明的立方体,我希望立方体看起来相同,如果我将它旋转 90 度的倍数。然而,显然取决于视角,特定表面看起来比其他表面更亮或更暗。在下面的示例中,30 度和 120 度的视图具有 3 种不同的红色阴影,而 210 度和 300 度的视图只有 2 种红色阴影。没有pm3d lighting涉及。

问题: 如何解释?如何避免这种情况?我对立方体的定义有问题吗?我是否遗漏了help pm3dorhelp pm3d algorithm或下的文档中的任何内容help pm3d color_assignment?我使用的是太旧的 gnuplot 版本(5.2.8)还是“错误”的终端(wxt)?

代码:

### semitransparent 3D surfaces
reset session

$Cube <<EOD
0 0 0
0 0 1
0 1 1
0 1 0
0 0 0

1 0 0
1 0 1
1 1 1
1 1 0
1 0 0

0 0 0
1 0 0
1 1 0
0 1 0
0 0 0

0 0 1
1 0 1
1 1 1
0 1 1
0 0 1
EOD

set view equal xyz
set cbrange [0.9:1]
set palette defined (1 'red')
set pm3d depthorder hidden3d
set pm3d implicit
unset hidden3d
unset label
unset tics
unset border
unset key
unset colorbox

set multiplot layout 2,3
    a=75
    b=30
    r=1.3
    set title sprintf("opaque view: %d, %d",a,b)
    set view a,b,r
    set style fill transparent solid 1
    splot $Cube u 1:2:3:(1) w l lw 0.5 lc "black"
    
    set style fill transparent solid 0.3
    do for [i=30:300:90] {
        set title sprintf("transparent view: %d, %d",a,i)
        set view a,i
        replot
    }
unset multiplot
### end of code

结果:

在此处输入图像描述

标签: 3dgnuplottransparency

解决方案


这里发生了很多事情

  1. 最初,我认为您所看到的部分证据表明,在您使用的任何终端中,图形渲染的合成操作都是不可传递的。但是我认为没有这个就可以解释大部分或所有的影响。

      (background ∘ 0.3red) ∘ 0.3red  ?=?  background ∘ (0.3red ∘ 0.3red)
    
  2. 一个关键是你的“立方体”并不是真正的立方体;它缺少 2 张面孔。如果将它们绘制为多边形,则视角的差异效果会更加明显:

    unset pm3d
    splot $Cube u 1:2:3 w polygons
    
  3. 因为您使用with pm3d的是 ,所以程序试图将顶点解释为一组定义曲面的扫描线。这真的行不通。我不完全确定它最终会是什么,但我怀疑有些区域被绘制了两次。您可以通过再次绘制它来了解这里出了什么问题

     set pm3d interpolate 2,2
    

在此处输入图像描述

如果添加立方体缺少的两个面并绘制面with polygons,效果将完全消失。

set view equal xyz
unset hidden3d
unset tics
unset border
unset key

set multiplot layout 2,3
    a=75
    b=30
    r=1.3
    set title sprintf("opaque view: %d, %d",a,b)
    set view a,b,r
    set style fill transparent solid 1
    set pm3d border lw 0.5 lc "black"
    splot $Cube u 1:2:3 w polygons fc "red"
    
    set style fill transparent solid 0.3
    do for [i=30:300:90] {
        set title sprintf("transparent view: %d, %d",a,i)
        set view a,i
        replot
    }
unset multiplot

在此处输入图像描述


推荐阅读