2011-03-17 108 views
2

隨着越來越多的複雜算法的一部分,我需要如下:如何用不斷增加的半徑填充圓?

  • 讓說,我有一個半徑R1的圓上的離散網格(圖像)繪製的(綠色下面圖片)
  • 我想畫有圓圈半徑R2比R1大一個像素(下圖中紅色)。
  • 在每個算法步驟中,以每次有實心圓的方式繪製半徑增加的圓。

enter image description here

我如何能找到點在每一步,以填補所以在每個步驟結束時,我已經完全提起圈?

我想到了一些圓光柵化算法,但這會導致填充中的一些空白。另一種方法是使用一些像擴張這樣的數學形態學操作,但這似乎在計算上花費很大。

我一般都在尋找任意形狀的方法,但最初的圓形算法就足夠了。

+0

將每個步驟的形狀隱藏前面? – Adrian 2011-03-17 09:25:05

+0

在每個步驟中,我正在尋找一組點(紅色),這些點以約1個像素增加半徑。 – Ross 2011-03-17 09:27:37

回答

2

我目前的解決方案爲圓。

基於公知Midpoint circle algorithm

  • 創造1個八分圓爲R1半徑(淺綠色像素)
  • 創建1個八分圓R2的半徑設定點的設定點的(深橙色像素)
  • 爲圖像中的每一行比較橙色和綠色像素的X座標,並獲得0或1(或其他)之間的像素數量(淺橙色)。
  • 重複用於每個八分圓(其中一些八分圓柱,而不是行已被比較)

該算法可以應用於其他類型的參數的形狀(Bezier曲線基於例如)

對於具有中心對稱性(圓形)的核的非參數形狀(基於像素)圖像卷積(膨脹)。換句話說,對於形狀上的每個像素尋找具有小半徑的圓的鄰居並將它們設置爲該集的一部分。 (昂貴的計算)

enter image description here

+0

對平行Bezier曲線很有趣!......我認爲我的方法計算起來不太昂貴,即使你必須燒一些內存來創建一個緩衝區並將結果寫回... – Adrian 2011-03-17 13:02:20

+0

也許我不明白它,但你的方式並不是計算成本較低。與我的解決方案類似,但是執行最後沒有使用的操作。例如,填充綠色部分不是必需的。 「燃燒」的記憶不是選擇。預期的結果是像素列表,而不是必須再次處理才能找到它們的圖像。 – Ross 2011-03-17 13:17:27

2

您最好的選擇是繪製並填充一個稍大的紅色圓圈,然後繪製並填充綠色圓圈。然後在下一次迭代中重做。

只繪製1px邊框是非常棘手的。您的示例圖像甚至不完全一致。在某些地方,白色像素對角地出現在綠色像素上,而在其他地方,像素則呈紅色。

編輯:

  • borderPixels = emptySet
  • 對於每個綠色像素,p
    • 對於每個鄰居Ñp
      • 如果Ñ是白色
        • 添加ň爲* borderPixels`
  • 什麼就做什麼,你有borderPixels(如顏色紅色它們)
+0

圖片僅僅是它看起來的大致示例。我很喜歡算法,可以在某些點上變化1-2像素,特別是對於任意形狀。這個「前線」然後用於檢查一些其他圖形對象的交叉。 – Ross 2011-03-17 09:25:50

+0

好的。更新了答案。 – aioobe 2011-03-17 09:38:10

+0

謝謝,這算法是我的第一個解決方案,但發現「對於每個鄰居」基本上是一個3x3的面具和它的最大操作擴張。我在想,存在一些計算量較小的算法。 – Ross 2011-03-17 09:46:09

1

另一種選擇喜歡用2像素寬的紅色邊框繪製一個圓形/形狀,然後繪製一個綠色的實心圓形/無邊框形狀。其中應該留下大約1px寬的邊緣的大約。 這取決於您使用何種技術將線條解析爲像素。

圓圈算法傾向於針對繪製圓圈進行優化.....See the link here