【问题标题】:Trying to generate random x,y coordinates within a ring in python尝试在python中的环内生成随机x,y坐标
【发布时间】:2017-06-14 05:01:15
【问题描述】:

我正在尝试在一个环内生成随机 x 和 y 坐标,该环的外半径为 3.5,内半径为 2。因此,x 和 y 必须满足以下条件:

x**2 + y**2 < 12.25 and x**2 + y**2 > 4

我写了以下函数:

def meteorites():
    circle = False
    while circle == False:        
        r = np.array([uniform(-6., 6.), uniform(-6., 6.)])
        # we will regenerate random numbers untill the coordinates
        # are within the ring x^2+y^2 < 3,5^2 and x^2+y^2 > 2^2
        if (r[0]**2+r[1]**2 < 12.25) and (r[0]**2+r[1]**2 > 4.):
            circle = True

       else :
            circle = False

    return r[0], r[1]

x = np.zeros(1000)
y = np.zeros(1000)
for i in range(1000):
    x[i] = meteorites()[0]
    y[i] = meteorites()[1]
plt.scatter(x,y)
plt.show()  

当我绘制结果坐标时,我得到一个从 -3.5 到 3.5 的正方形。我似乎找不到问题所在。我也不确定这是一个编码错误,还是一些愚蠢的数学问题。既然你们通常两者都擅长,你能看出我在这里做错了什么吗?

【问题讨论】:

  • 为什么不生成一个随机的角度和距离,然后将其转换为 x、y 对?
  • @MartijnPieters 如果您均匀生成距离,则内环中的点会更密集。

标签: python python-2.7 numpy math


【解决方案1】:

在两个约束之间取一个随机角度和一个随机距离;你需要生成一个uniform distribution in a circle:

from math import sin, cos, radians, pi, sqrt

def meteorites():
    angle = uniform(0, 2 * pi)  # in radians
    distance = sqrt(uniform(4, 12.25))
    return distance * cos(angle), distance * sin(angle)

【讨论】:

  • 完美。 Dank je wel!
  • 是的,当我看到时间安排时我意识到了。由于我正忙于研究整个圈子的正确分布,我没有看到您的评论;-)
【解决方案2】:

您可以尝试以下方法来使用 numpy 生成 1000 个样本:

import numpy 
n = 1000
phi = numpy.random.uniform(0, 2*numpy.pi, n)
r = numpy.random.uniform(2, 3.5, n)

那么x,y坐标可以通过从径向坐标到笛卡尔坐标的变换构造如下:

x = r * numpy.cos(phi)
y = r * numpy.sin(phi)

这显示了 numpy 的强大功能,因为 x 和 y 现在是数组,无需遍历 n。

【讨论】:

    【解决方案3】:

    你得到的随机点不会落在你的戒指上,因为这两条线没有做你想做的事:

    x[i] = meteorites()[0]
    y[i] = meteorites()[1]
    

    这些将环上一个点的x 值分配给x[i],并将y从环上的不同点分配给y[i]。因为您调用了两次meteorites(),所以您从不同的点获取坐标。

    相反,您可能希望调用该函数一次,然后分配给每个坐标,或者使用可迭代解包进行分配,其中两个目标都在等号的左侧:

    x[i], y[i] = meteorites()
    

    【讨论】:

      【解决方案4】:

      正如@Martijn Pieters 建议的那样,只需在您需要的范围内均匀地绘制极坐标即可。

      theta = uniform(0,2*np.pi)
      r = uniform(2.,3.5)
      x = r*np.cos(theta)
      y = r*np.sin(theta)
      

      编辑:环中每个点发生的概率都是相等的。

      但实际上,对于给定的theta,像素越少,r 越接近下限。所以r更小的“陨石”出现的概率会更大。

      我认为这种影响可以忽略不计。

      编辑 2: MBo 的答案更好。代码:

      theta = uniform(0, 2 * np.pi)
      r = np.sqrt(uniform(2.0 ** 2, 3.5 ** 2)) # draw from sqrt distribution
      x = r * np.cos(theta)
      y = r * np.sin(theta)
      

      【讨论】:

      • 一个圆有2pi弧度;您在 一半 环上布置位置。
      【解决方案5】:

      我也宁愿通过一个循环,在你的戒指范围内选择一个随机的角度和一个随机的距离。然后从中计算坐标。

      但在你的代码中,第一个问题是应该写:

      x[i],y[i] = meteorites()
      

      而不是

      x[i] = meteorites()[0] 
      y[i] = meteorites()[1]
      

      在您的示例中,您被称为 meteorites() 两次,导致 x 和 y 是两个不同的陨石。

      【讨论】:

        【解决方案6】:

        为了使随机点在环中均匀分布,应考虑薄圆形区域的相对面积。 How it works for the circle

        对于您的情况,在平方内半径和外半径范围内生成 SquaredR 的均匀分布。伪代码:

         Fi  = RandomUniform(0, 2 * Pi)
         SquaredR  = RandomUniform(inner*inner, outer*outer)
         R = Sqrt(SquaredR)
         x,y = R * Cos(Fi), R * Sin(Fi)
        

        【讨论】:

          【解决方案7】:

          如果您更正一行,您的实现也将起作用:与其调用meteorites() 两次,不如只调用一次。

          x = np.zeros(1000)
          y = np.zeros(1000)
          for i in range(1000):
              x[i], y[i] = meteorites()
          plt.scatter(x,y)
          plt.show()  
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-11-09
            • 1970-01-01
            • 1970-01-01
            • 2017-04-09
            • 1970-01-01
            • 2021-10-03
            • 1970-01-01
            • 2020-11-03
            相关资源
            最近更新 更多