我正在尋找一種能產生與藍噪聲相似的點放置結果的算法。無限藍噪聲
但是,它需要一個無限平面工作。在給出邊界框的情況下,它返回所有落入其中的點的位置。任何幫助,將不勝感激。我做了很多研究,沒有找到適合我需要的東西。
我正在尋找一種能產生與藍噪聲相似的點放置結果的算法。無限藍噪聲
但是,它需要一個無限平面工作。在給出邊界框的情況下,它返回所有落入其中的點的位置。任何幫助,將不勝感激。我做了很多研究,沒有找到適合我需要的東西。
最後我設法得到了結果。與藍噪聲特性 生成點分佈的
一種方式是通過泊松磁盤分佈
的裝置從所述紙快速泊松磁盤採樣在 任意尺寸,羅伯特·布里森算法繼我有:
步驟男人
步驟0初始化n維背景網格以存儲 樣本並加速空間搜索。我們選取單元格大小爲r/sqrt(n)爲界的 ,以便每個網格單元最多包含一個樣本,因此網格可以實現爲一個簡單的n維 整數數組:缺省值-1指示無樣本,非負 整數給出了位於單元格中的樣本的索引
第1步。選擇從 域中統一隨機選擇的初始樣本x0。將其插入到背景網格中,並使用此索引(零)初始化「活動列表」(樣本索引數組)。
第2步。當活動列表不爲空時,從 (例如i)中選擇一個隨機索引。在xi周圍半徑r和2r之間生成多達k個點,均勻地從 球形環面選擇。對於 轉彎中的每個點,檢查它是否在現有樣本的距離r內(使用 背景網格僅測試附近的樣本)。如果一個點遠離現有樣本足夠遠,則將其作爲下一個樣本發出並將其添加到 活動列表中。如果在k次嘗試後沒有找到這樣的點,取而代之的是 將i從活動列表中刪除。
請注意,爲了簡單起見,我跳過了第0步。儘管運行時間仍然合理。它是<.5s。實施這一步肯定會提高性能。
以下是Processing中的示例代碼。它是一種建立在Java之上的語言,因此語法非常相似。爲了您的目的翻譯它不應該很難。
import java.util.List;
import java.util.Collections;
List<PVector> poisson_disk_sampling(int k, int r, int size)
{
List<PVector> samples = new ArrayList<PVector>();
List<PVector> active_list = new ArrayList<PVector>();
active_list.add(new PVector(random(size), random(size)));
int len;
while ((len = active_list.size()) > 0) {
// picks random index uniformly at random from the active list
int index = int(random(len));
Collections.swap(active_list, len-1, index);
PVector sample = active_list.get(len-1);
boolean found = false;
for (int i = 0; i < k; ++i) {
// generates a point uniformly at random in the sample's
// disk situated at a distance from r to 2*r
float angle = 2*PI*random(1);
float radius = random(r) + r;
PVector dv = new PVector(radius*cos(angle), radius*sin(angle));
PVector new_sample = dv.add(sample);
boolean ok = true;
for (int j = 0; j < samples.size(); ++j) {
if (dist(new_sample.x, new_sample.y,
samples.get(j).x, samples.get(j).y) <= r)
{
ok = false;
break;
}
}
if (ok) {
if (0 <= new_sample.x && new_sample.x < size &&
0 <= new_sample.y && new_sample.y < size)
{
samples.add(new_sample);
active_list.add(new_sample);
len++;
found = true;
}
}
}
if (!found)
active_list.remove(active_list.size()-1);
}
return samples;
}
List<PVector> samples;
void setup() {
int SIZE = 500;
size(500, 500);
background(255);
strokeWeight(4);
noLoop();
samples = poisson_disk_sampling(30, 10, SIZE);
}
void draw() {
for (PVector sample : samples)
point(sample.x, sample.y);
}
但是,它需要一個無限平面工作。
您可以使用參數size
控制框的大小。 r
控制點之間的相對距離。 k
控制在拒絕電流前應嘗試多少新樣本。該文件建議k=30
。
謝謝你的快速回答。這看起來很有希望。雖然我誤解了你的部分代碼,或者我在解釋結束時不太清楚。當我說無限的飛機時,我的意思是我可以在各個地點提供儘可能多的邊界框,並且它們內部的點總是排成一行。如果我誤解了你的代碼,請解釋一下。 –
@BryanBrownTheDudeFromCI,所以你的意思是你的方法應該採用幾個邊界框作爲輸入,它應該返回所有這些樣本? – svs
是的。就像我可以添加多個框,但不是一次。一次一個。並且每個盒子可以允許點彼此流動,如果盒子彼此相鄰則不會重疊。或者如果部分框重疊,則返回相同的點。 現在查看您的代碼,我認爲可以使用種子並擴大搜索範圍以使其正常工作。謝謝你的幫助! :) –
這張照片取自[José's Sketchbook](http://www.joesfer.com/?p=108)?無論如何,由於正確的圖案由左側的圖塊組成,因此您只需手動計算左側圖塊中的點,然後跟蹤使用哪個圖塊以及多少次。 – usr2564301
我第一次聽到Robert Ulichney在1987年出版的「數字半色調」一書中的「藍噪聲」一詞。他可能已經發明瞭這個術語,我不確定。在任何情況下,本書都有一些用於將灰度級別轉換爲藍色噪聲模式的好算法,但有一整章專門討論了該主題。算法應該是非常高效的。 –