简体   繁体   English

试图在python中的环中生成随机x,y坐标

[英]Trying to generate random x,y coordinates within a ring in python

I am trying to generate random x and y coordinates within a ring, which has an outer radius of 3.5 and an inner radius of 2. Therefor the following must be true for x and y: 我试图在一个环中生成随机的x和y坐标,它的外半径为3.5,内半径为2.因此x和y必须满足以下条件:

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

I wrote the following function: 我写了以下函数:

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()  

When I plot the resulting coordinates I get a square from -3.5 to 3.5. 当我绘制结果坐标时,我得到一个从-3.5到3.5的正方形。 I can't seem to find the problem. 我似乎无法找到问题。 I'm also not sure if it's a coding error, or some dum math problem. 我也不确定这是编码错误还是一些数学问题。 Since you guys are usually good at both, can you see what I'm doing wrong here? 既然你们两个都很擅长,你能看到我在这里做错了什么吗?

To get uniform distribution of random point in the ring, one should take relative areas of thin circular regions into account. 为了在环中获得随机点的均匀分布,应该考虑薄圆形区域的相对区域。 How it works for the circle 它如何适用于圆圈 在此输入图像描述

For your case generate uniform distribution of SquaredR in range of squared inner and outer radii. 对于您的情况,在内半径和外半径的平方范围内产生均匀分布的SquaredR。 Pseudocode: 伪代码:

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

Take a random angle and a random distance between the two constraints; 取一个随机角度和两个约束之间的随机距离; you'll need to produce a 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)

You're getting random points that don't fall on your ring because these two lines don't do what you want: 你得到的随机点数不会落在你的戒指上,因为这两行不符合你的要求:

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

These assign an x value from one point on the ring to x[i] , and the y value from a different point on the ring to y[i] . 这些将x值从环上的一个点分配给x[i] ,将y从环上的不同点分配给y[i] You get coordinates from different points because you're calling meteorites() twice. 你从不同的点获得坐标,因为你两次调用meteorites()

Instead, you probably want to call the function once, and then assign to each coordinate, or do an assignment with iterable-unpacking where both targets are on the left side of the equals sign: 相反,您可能希望调用该函数一次,然后分配给每个坐标,或者使用iterable-unpacking进行赋值,其中两个目标都位于等号的左侧:

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

as @Martijn Pieters suggested, simply draw the polar coordinates uniformly in the range you require. 正如@Martijn Pieters建议的那样,只需在你需要的范围内均匀地绘制极坐标。

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

EDIT: There will be equal probability for every point in the ring to occur. 编辑:环中的每个点都有相同的概率发生。

But practically there will be less pixels for a given theta the closer r is to the lower limit. 但实际上,给定theta的像素越少, r越接近下限。 So "meteorites" with smaller r will occur with larger probability. 因此具有较小r “陨石”将以更大的概率发生。

I believe this effect is negligeble. 我相信这种影响是疏忽的。

EDIT 2: MBo's answer is better. 编辑2: MBo的答案更好。 Code: 码:

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)

I would also rather run through a loop that picks a random angle and a random distance within your ring range. 我还想通过一个循环来选择随机角度和你的戒指范围内的随机距离。 Then calculate the coords from that. 然后从中计算出坐标。

But in your code the first problem is see is that should write: 但在您的代码中,第一个问题是应该写:

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

instead of 代替

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

In your example, you're called meteorites() twice resulting in the x and y two different meteorites. 在你的例子中,你被称为陨石()两次,导致x和y两个不同的陨石。

Your implementation will also work if you correct one line: insstead of calling meteorites() twice, call just once. 如果你更正了一行,你的实现也会起作用:两次调用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()  

在此输入图像描述

You could try the following to generate 1000 samples using numpy: 您可以尝试以下操作使用numpy生成1000个样本:

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

Then x, y coordinates can be constructed as follows using the transformation from radial to cartesian coordinates: 然后使用从径向到笛卡尔坐标的变换,可以如下构造x,y坐标:

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

This shows the power of numpy, as x and y are now arrays without needing to iterate over n. 这显示了numpy的强大功能,因为x和y现在是数组而不需要迭代n。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM