【问题标题】:gnuplot - plot random points inside an ellipsoidgnuplot - 在椭球内绘制随机点
【发布时间】:2013-09-14 21:22:07
【问题描述】:

我想使用 gnuplot 在椭球边界内创建和绘制一组随机点。是否可以直接在 gnuplot 中执行此操作,还是需要在外部程序中生成随机数据点?

最终我想制作一个类似于ellipse figure 的椭球体。

有一些使用randcylindrical/spherical coordinates 的示例,但我不确定如何在椭球边界内生成随机点。

【问题讨论】:

    标签: math random geometry gnuplot ellipse


    【解决方案1】:

    在您展示的参数绘图示例中,我没有找到重用 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 留给读者作为练习(继续这些表达式)

    【讨论】:

      【解决方案2】:

      根据@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
      

      结果:

      然而,这会导致点的明显分布不均(请参阅椭圆末端的聚集,请参阅@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
      

      这会产生更好的结果:

      将此扩展到三个维度:

      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
      

      结果:

      【讨论】:

      • 哇,我不知道你可以在using 部分中创建变量!
      • @Bernhard 我第一次看到这个是在running average demo。参见例如我对How do I create a 3d phase-space plot in gnuplot?gnuplot matrix or palette using one linePlotting different columns on the same file using boxes 的回答,好吧,我们称它们为“用例”;)。
      • @Bernhard 我也更喜欢使用外部工具进行预处理。但是对于一些简单的情况,或者当您不能依赖可用的外部工具时,它可能会很好。虽然它变得非常快非常令人困惑。
      • 我似乎注意到椭圆末端有更多点,我想知道这些点是否不是随机分布的,因为 rand 函数用于给出笛卡尔点,然后将这些点转换为椭圆。它可能会提供更随机的分布来生成随机 (x,y) 对,然后将它们过滤到椭圆的范围内(如果这很重要的话)。
      • @andyras 好点!请参阅我的更新答案。这看起来好多了。
      猜你喜欢
      • 1970-01-01
      • 2019-01-17
      • 1970-01-01
      • 2016-06-19
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多