gnuplot - 绘制椭球内的随机点

4
我想使用gnuplot创建和绘制一组随机点,这些点在椭球体的边界内。是否可以直接在gnuplot中完成此操作,还是需要在外部程序中生成随机数据点?
最终,我想生成类似于此椭圆图形的椭球体图形。
有一些关于rand柱面/球面坐标使用的示例,但我不确定如何在椭球体边界内生成随机点。
2个回答

4

基于@Bernhard的回答,以下是如何仅使用gnuplot来实现。要重用随机数,可以将两个rand调用和变量赋值放在using语句的第一个参数中,用逗号分隔。 using语句从左到右评估,因此您可以在所有后续的using参数中访问这些变量。

为了演示这一点,请参见以下示例:

set samples 1000
plot '+' using (x=rand(0), y=rand(0), x):(y)

应用于椭球体,这是该脚本的内容:
a=3
b=2
phi=30*pi/180

max(x,y) = (x > y ? x : y)
set xrange[-max(a,b):max(a,b)]
set yrange[-max(a,b):max(a,b)]

set offset 0.1,0.1,0.1,0.1
set samples 2000

ex(x, y) = a*(2*x-1)
ey(x, y) = b*(sqrt(1-((2*x-1))**2))*(2*y-1)

unset key    
plot '+' using (x=rand(0), y=rand(0), ex(x,y)*cos(phi)-ey(x,y)*sin(phi)):\
               (ey(x,y)*cos(phi)+ex(x,y)*sin(phi)) pt 7 ps 0.5

结果如下:

enter image description here

然而,这会导致点的分布似乎不均匀(请看椭圆两端的凝聚点,参见@andyras的评论)。为了避免这种情况,以下是如何筛选等分布的随机点以使其位于椭球内:

a=3
b=2
set angles degree
phi=30

max(x,y) = (x > y ? x : y)
set xrange[-max(a,b):max(a,b)]
set yrange[-max(a,b):max(a,b)]

set offset 0.1,0.1,0.1,0.1
set samples 2000
set size ratio 1

check(x, y) = (((x/a)**2 + (y/b)**2) <= 1)
unset key
plot '+' using (x=2*a*(rand(0)-0.5), y=2*b*(rand(0)-0.5), \
     check(x,y) ? x*cos(phi)-y*sin(phi) : 1/0):\
     (x*sin(phi)+y*cos(phi)) pt 7 ps 0.5

这样会得到更好的结果:

enter image description here

将其扩展到三维:
a=3
b=1
c=1
set angles degree
phi=30

mx(x,y) = (x > y ? x : y)
max(x,y,z) = mx(mx(x,y), mx(x,z))
set xrange[-max(a,b,c):max(a,b,c)]
set yrange[-max(a,b,c):max(a,b,c)]
set zrange[-max(a,b,c):max(a,b,c)]

set offset 0.1,0.1,0.1,0.1
set samples 2000
set size ratio 1

set ticslevel 0
set view 60, 330

check(x, y, z) = (((x/a)**2 + (y/b)**2 + (z/c)**2) <= 1)
unset key
splot '+' using (x = 2*a*(rand(0)-0.5), \
                 y = 2*b*(rand(0)-0.5), \
                 z=2*c*(rand(0)-0.5), \
                 check(x,y,z) ? x*cos(phi)-y*sin(phi) : 1/0):\
                 (x*sin(phi)+y*cos(phi)):(z) pt 7 ps 0.5

带着以下结果:

在此输入图片描述


1
@Bernhard 我第一次看到这个是在running average demo中。例如,可以参考我的回答:How do I create a 3d phase-space plot in gnuplot?gnuplot matrix or palette using one line,以及Plotting different columns on the same file using boxes等,这些都是“使用案例”;)。 - Christoph
1
@Bernhard 我也更喜欢使用外部工具进行预处理。但对于一些简单的情况,或者当你不能依赖外部工具可用时,这也是不错的选择。尽管它会变得非常快速和混乱。 - Christoph
2
我似乎注意到椭圆的端点更多,我想知道这些点是否不是随机分布的,因为rand函数用于提供笛卡尔坐标点,然后将其转换为椭圆。如果需要的话,生成随机(x,y)对并过滤它们以在椭圆边界内可能会给出更随机的分布。 - andyras
1
@andyras 好观点!看看我的更新答案。这看起来好多了。 - Christoph
我终于有时间来看这个了。感谢你们两位提供答案。我可能会投票支持这个答案,因为它可以跨平台使用。是否可以通过使用球坐标(椭圆的极坐标)来避免椭球体内点的非随机/不均匀分布?哦,我还以为我对gnuplot很了解呢... - tommy.carstensen
显示剩余6条评论

2

我没有找到一种方法可以在参数绘图示例中重复使用你展示的rand(0),但是通过内部调用命令行工具,你可以进行一些修改来实现这个功能:

unset key
a=3
b=2

set xrange [-a:a]
set yrange [-b:b]
set style function dots
plot "<seq 1000 | awk '{print rand(), rand()}'" using (a*(2*$1-1)):(b*(sqrt(1-((2*$1-1))**2))*(2*$2-1))

将此转换为3D留给读者作为练习(只需继续这些表达式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接