2013-04-04 24 views
5

点の間の距離が230から250の範囲になるように、円柱の表面にランダムな点を生成したいと思います。次のコードを使って、シリンダ:円柱の表面にランダムな点を生成する

import random,math 
H=300 
R=20 
s=random.random() 
#theta = random.random()*2*math.pi 
for i in range(0,300): 
    theta = random.random()*2*math.pi 
    z = random.random()*H 
    r=math.sqrt(s)*R 
    x=r*math.cos(theta) 
    y=r*math.sin(theta) 
    z=z 
    print 'C' , x,y,z 

ランダムな点を(シリンダの表面上の)範囲に収まるようにどのように生成できますか?

+0

シリンダー、または直線(ユークリッド)の表面に沿った距離? – NPE

+0

シリンダーの表面に沿って – user1407199

+1

質問に追加してください。 – NPE

答えて

1

これは完全な解決策ではなく、役立つ洞察です。円筒の表面を幅がw=2*pi*rで高さがhの矩形に「展開」すると、点間の距離を求める作業が簡単になります。シリンダーの上の点と側面の間の「表面に沿った距離」を測定する方法については説明していません。これはやや微妙な幾何学的な形状です。

私たちが人工の "縫い目"を作成したときの表面に沿った距離の計算は、(x1-x2)と(w-x1 + x2)の両方を使用してください。

私は、ポアソンディスクサンプリングを使用するという提案は非常に良いと思っていますが、h = 300とr = 20の制約で何があってもひどい結果が得られます。

1

これらの間の位置に制約を持つランダムな点のセットを作成する基本的な方法は、特定の場所に配置される点の確率を調整する機能を持たせることです。この関数は定数で始まり、ポイントが置かれると、そのポイントを囲む禁止されたエリアはゼロに設定されます。それは連続変数では困難ですが、問題を離散化するとかなり簡単です。

その他注意しなければならないのは、シリンダー部分にあることです。周期的に繰り返される矩形領域上のランダムな点と考える方が簡単かもしれません。これは、2つの異なる方法で処理することができます。

  1. 最も簡単なのは考慮にあなたがポイントを配置している長方形のタイルが、また、その近隣のものではないだけを取ることです。あなたがメインタイルにポイントを置くたびに、あなたはまた、隣のタイルにポイントを置き、タイル内の確率関数にその効果を計算します。

  2. より洗練されたアプローチでは、すでに配置されたポイントに対応するデルタ関数の合計で、禁則領域を符号化するカーネルの確率関数を考慮します。これがFFTを使用して計算される場合、周期性は生成物によって自然である。

次のように最初のアプローチは、コード化することができます:あなたは自分の価値観でそれを実行した場合、大きな最小距離が他のすべてを禁止して

from __future__ import division 
import numpy as np 

r, h = 20, 300 
w = 2*np.pi*r 
int_w = int(np.rint(w)) 
mult = 10 
pdf = np.ones((h*mult, int_w*mult), np.bool) 
points = [] 
min_d, max_d = 230, 250 

available_locs = pdf.sum() 
while available_locs: 
    new_idx = np.random.randint(available_locs) 
    new_idx = np.nonzero(pdf.ravel())[0][new_idx] 
    new_point = np.array(np.unravel_index(new_idx, pdf.shape)) 
    points += [new_point] 
    min_mask = np.ones_like(pdf) 
    if max_d is not None: 
     max_mask = np.zeros_like(pdf) 
    else: 
     max_mask = True 
    for p in [new_point - [0, int_w*mult], new_point +[0, int_w*mult], 
       new_point]: 
     rows = ((np.arange(pdf.shape[0]) - p[0])/mult)**2 
     cols = ((np.arange(pdf.shape[1]) - p[1]) * 2*np.pi*r/int_w/mult)**2 
     dist2 = rows[:, None] + cols[None, :] 
     min_mask &= dist2 > min_d*min_d 
     if max_d is not None: 
      max_mask |= dist2 < max_d*max_d 
    pdf &= min_mask & max_mask 
    available_locs = pdf.sum() 
points = np.array(points)/[mult, mult*int_w/(2*np.pi*r)] 

、出力は、通常、1つか2つの点です。より合理的な値で実行するとここ

min_d, max_d = 50, 200 

は、確率関数は、最初の5点の各々を確定した後にどのように見えるかは次のとおりに沿った点が最初の高さ、座標の対として返されること enter image description here

注、第二の距離シリンダーの円周。

関連する問題