簡體   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