繁体   English   中英

我如何在xy平面中生成一个与y0(a,b)相距10步的随机点(x,y)?

[英]How can I generate a random point (x, y) 10 steps apart from y0(a, b) in xy-plane?

我已经在xy平面中生成了一个名为y0=(a,b)随机点,如何生成与y0相距10步的另一个随机点(x,y)

注意:距离发火点10步远不是欧几里得距离。 我的意思是两个点(a,b)和(x,y)之间的晶格步数由| xa | + | yb | = 10给出

我的尝试(有时会给出错误的结果)。

import random
y0=(random.randint(0,50),random.randint(0,50))# here I generated the first point.
y=random.randint(0,50)

# I used the formula  |x-a|+|y-b|=10.
x=(10 -abs(y-y0[1]))+y0[0]  or x=-(10 -abs(y-y0[1]))+y0[0]

x0=(x,y)

假设您的新点(x,y)位于半径为10且中心为(x0,y0)的圆角上。 随机分量是角度。

import math as m
# radius of the circle
r = 10
# create random angle and compute coordinates of the new point
theta = 2*m.pi*random.random()
x = x0 + r*m.cos(theta)
y = y0 + r*m.sin(theta)
# test if the point created is in the domain [[0,50], [0, 50]] (see comments of PM2Ring)
while not ( 0<=x<=50 and 0<=y<=50 ) :
    # update theta: add pi/2 until the new point is in the domain (see HumanCatfood's comment) 
    theta += 0.5*m.pi
    x = x0 + r*m.cos(theta)
    y = y0 + r*m.sin(theta)

假设您有一个点(x, y)

  1. 在平面上的任意位置创建另一个随机点: (x1, y2) = (random(), random())

  2. 从您的点到新点取向量: (vx, vy) = (x1-x, y1-y)

  3. 得到向量的长度ll = sqrt(vx * vx + vy * vy)

  4. 使用l归一化向量(因此其长度为1):( (vx, vy) = (vx / l, vy / l)

  5. 使向量长10步: (vx, vy) = (vx * 10, vy * 10)

  6. 将其添加到原始点以获得所需的点: (x1, y2) = (x + vx, y + vy)

oil :)

from random import random
from math import sqrt

# Deviation
dev = 50

# Required distance between points
l = 10

if __name__ == '__main__':

    # First random point
    x0, y0 = dev*random(), dev*random()

    # Second point
    x1 = dev*random()
    y1 = y0 + sqrt(l**2 - (x1 - x0)**2)

    # Output
    print "First point (%s, %s)" % (x0, y0)
    print "Second point (%s, %s)" % (x1, y1)
    print "Distance: %s" % (sqrt((x1 - x0)**2 + (y1 - y0)**2))

因此,您得到了公式d=d1+d2=|x-x0|+|y-y0| , for d=10 d=d1+d2=|x-x0|+|y-y0| , for d=10

让我们检查一下此公式的含义:

  • 假设我们在(0,0)处生成一个随机点P
  • 假设我们生成y=random.randint(0,50)并假设该值为50。

这是什么意思?

d1=|xp[0]|=50 ,您的原始公式是d=d1+d2=|x-x0|+|y-y0| ,则意味着d2=|y-y0|=10-50d2=|y-y0|=-40 这可能吗? 绝对不! 绝对值| y-y0 | 始终为正,这就是为什么您的公式不适用于某些随机点的原因,您需要确保(d-d1)> 0,否则您的方程将无解。


如果要考虑欧几里得距离,您只需要在以原始点为中心的圆中生成随机点,则可以这样做:

import random
import math


def random_point(p, r=10):
    theta = 2 * math.pi * random.random()
    return (p[0] + r * math.cos(theta), p[1] + r * math.sin(theta))

如果绘制一些随机点,您将越来越多地看到如何创建圆形,让我们尝试使用N = 10,N = 50,N = 1000:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

现在,似乎您需要将生成的圆限制在某些区域。 一种可能的选择(虽然不是最佳选择)是生成随机点,直到它们满足这些约束,这样可以做到:

def random_constrained_point(p, r=10, x_limit=50, y_limit=50):
    i = 0
    MAX_ITERATIONS = 100

    while True:
        x0, y0 = random_point(p, r)

        if (0 <= x0 <= x_limit and 0 <= y0 <= y_limit):
            return (x0, y0)

        if i == MAX_ITERATIONS:
            return p

        i += 1

一旦知道了这一点,检查一下随着圆半径(10,20,50)的增加而创建的形状会很有趣:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

如您所见,生成的随机约束点将形成一个定义明确的子弧。

此代码生成一个名为y0的随机点xy平面,然后生成另一个点x0,与滑行距离y0间隔10步。

-------代码的开头--------导入随机y0 =(random.randint(0,50),random.randint(0,50))

  while True:

      y=random.randint(0,50)

      x=(10 -abs(y-y0[1]))+y0[0] 
      if (abs(x-y0[0])+abs(y-y0[1]))==10:
         x0=(x,y)
         break

abs(x)+abs(y)=10定义了一个正方形 ,因此您要做的就是沿着正方形的周长(40个单位长)选取一个随机值,然后将该随机距离映射回x,y坐标对。

像(未经测试的):

x = random.randint(-10,9)
y = 10 - abs(x)
if (random.randint(0,1) == 0):
    x = -x
    y = -y
x = x + y0[0]
y = y + y0[1]
x0=(x,y)

裁剪x范围可确保所有点均被均匀拾取。 否则,您可能得到的(-10,0)和(10,0)的机率是任何其他坐标的两倍。

暂无
暂无

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

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