如何摆脱 gnuplot 中相交曲线的小故障?

How to get rid of small glitches in intersecting curves in gnuplot?

这既是一个问题,也是一封写给 theozh 的感谢信,他帮助我在 gnuplot 中创建了我想要的图形。

我试图从他们分享过几次的剧情中找到最漂亮的图片。

这是我的脚本

reset session
set output 'Wavy_curve.svg'

samps = 2500
set samples samps, samps
set isosamples samps, samps

f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
set table $Data01
    splot f(x,y)
unset table

g(x,y) = y
set table $Data02
    splot g(x,y)
unset table

h(x,y) = 0.5*x
set table $Data03
    splot h(x,y)
unset table

Zmin = -3
Zmax= 3

set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]
set hidden3d
set angle degree

Frac(z) = (z-Zmin)/(Zmax-Zmin)
# MyPalette01
Red01(z) = 65536 * ( Frac(z) > 0.75 ? 255 : int(255*abs(2*Frac(z)-0.5)))
Green01(z) = int(255*sin(180*Frac(z)))*256
Blue01(z) = int(255*cos(90*Frac(z)))
MyPalette01(z) =  Red01(z) + Green01(z) + Blue01(z) 

# MyPalette02
Red02(z)   = 65536 * int(255*Frac(z))
Green02(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))
Blue02(z)  = (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
MyPalette02(z) =  Red02(z) + Green02(z) + Blue02(z) 

# MyPalette03
Red03(z)   = 65536 * (Frac(z) > 0.5 ? 255 : int(255*Frac(z)*2))
Green03(z) = 256 * (Frac(z) > 0.333 ? 255 : int(255*Frac(z)*3))  
Blue03(z)  = int(255*Frac(z)) 
MyPalette03(z) =  Red03(z) + Green03(z) + Blue03(z) 

set pm3d
set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2
set pm3d ftriangles
set style fill transparent solid 0.8 noborder 

unset colorbox

set view 44,316
splot $Data01 u 1:2:3:(MyPalette01()) w l lc rgb var notitle, \
      $Data02 u 1:2:3:(MyPalette02()) w l lc rgb var notitle, \
      $Data03 u 1:2:3:(MyPalette03()) w l lc rgb var notitle
### end of code 

结果

我那可怜的笔记本电脑花了 16 个小时才渲染出来,但我对结果很满意。看来我有几个小故障。这些半透明图通常会发生这种情况。左下角有一个较暗的圆圈。几乎不明显,只有较暗的背景。我想我需要更多样本,但一段时间后它变得非常慢。我只用了 2500 来获得尖锐的交叉点,1000 对于单个表面就足够了。当我使用 0.2 作为透明度时,我也得到了看起来缺少纹理的东西,通过将其增加到 0.8 解决了这个问题。

我使用了 svg 终端,因为 qt 终端为这些需要增加透明度的图提供了丑陋的线条,但最终仍会出现波纹图案。 wxt 在没有线条的情况下处理得更好,但它没有提供完全的透明度,似乎只能显示一个交叉点。有什么技巧可以降低获得此类结果的计算成本吗?

编辑:根据 Ethan 的回答,我使用 svg 终端仅用了 30 秒就得到了这个结果。新问题是 Inkscape 真的很难打开最终约为 300MB 的文件,以便将其导出为 png,只有 1.4MB。是否有另一个终端可以提供像 svg 这样好的结果,但可以直接输出为 png? svg终端可以直接输出为png吗?我将尝试在不打开 inkscape gui 的情况下从命令行进行文件转换,但鉴于文件较大,它仍然不理想。

我不知道你对你的情节有什么限制或要求,但我怀疑你使它变得比获得顺利结果所必需的要难得多。

这是大致相同情节的流畅版本,在我不是特别强大的桌面上执行时间不到 2 秒。我已将三个不同的调色板范围堆叠到一个调色板中,以便 splot 命令可以直接使用调色板,而不是像您的示例脚本那样将其分成离散样本。

通过直接使用调色板,您还可以选择通过添加 set pm3d interpolation N,N 来增加平滑度,尽管我认为这里不需要它。

如果此方法未能解决某些要求,请随时修改问题。

set term pngcairo size 700,500
set output 'Waves.png'

samps = 250

set samples samps, samps
set isosamples samps, samps

f(x,y) = sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x)
g(x,y) = y
h(x,y) = 0.5*x

Zmin = -3
Zmax= 3

set xrange[-5:5]
set yrange[-5:5]
set zrange[Zmin:Zmax]

set pm3d depthorder
set pm3d lighting primary 0.5 specular 0.2

set style fill transparent solid 0.8 noborder 

unset colorbox
unset key

set view 44,316

set palette defined (-3 "0x0000df", 0 "0xddff40", 3 "0xdf0000", \
                      3 "gray40", 9 "0x8fffff", \
                      9 "gray40", 15 "0xffff8f")
set cbrange [-3:15]

splot '++' u 1:2:(f(x,y)) with pm3d, \
      '++' u 1:2:(g(x,y)):(6+g(x,y)) with pm3d, \
      '++' u 1:2:(h(x,y)):(12+h(x,y)) with pm3d