2013-01-02 53 views
1

的填充效果,我們可以在這裏看到http://hakim.se/experiments/html5/coil/是相當驚人的。我甚至不能猜測那樣的填充如何(關閉同時提請你會發現你正在創建的封閉形狀的填充形狀)可以工作什麼..填寫複雜的形狀(畫線)

任何想法,請?

+0

除了我的回答,請嘗試在網上搜索「洪水填多邊形」,如果你有興趣的瀏覽器的帆布實現可能如何填補機制實際的多邊形內容。 – GargantuChet

回答

6

這聽起來像你正在尋找整體高層次的過程。如果沒有對該網站使用的方法進行反向工程,以下是我可能會考慮採用的方法。

開始與鼠標的當前位置的點。每隔一段時間,

  1. 從鼠標的上一個位置繪製線段到鼠標的當前位置。
  2. 刪除太舊的線段。
  3. 如果新線段相交的任何現有(谷歌「檢測線段相交」或類似),在點分裂他們,他們相交(「在路口算法拆分線段」搜索可能讓你那裏)

    假設你開始

     
        o----o 
        \ 
        \  o 
         \ /
         \/
         o 
    

    ,並從點右側增加一個段,向左延伸:新段相交現有線段

     
        o----o 
        \ 
    o----------o 
         \ /
         \/
         o 
    

    注意。在交叉點處將它們分割:

     
        o----o 
        \ 
    o----o-----o 
         \ /
         \/
         o 
    

    注意o表示線段的終點。我們已經從四個細分市場,其中兩個相交,到六個細分市場,其中四個細分市場有共同點。

    這些步驟會給你一個連續的線段。現在讓我們來看看它們是否構成一個多邊形:

  4. 通過每個線段端到端的步驟。識別在多個不相鄰段之間共享的線段的第一個結束。一旦你找到爲此,畫出所有線段到這一點:

     
        ●----● 
        \ 
        ● 
    
  5. 開始在另一端,做同樣的事情。

     
        o----o 
        \ 
    ●----● 
    
  6. 所有剩餘的線段都是多邊形的一部分。現在,在畫布上的draw the enclosed polygon

     
        o----o 
        \ 
    o----●-----● 
         \.../ 
         \./ 
         ● 
    
  7. 最後是找出多邊形中包含哪些圓的時候了。用上面實際形成多邊形的片段列表武裝起來,用諸如「算法點在多邊形內」的搜索命中網絡。

+0

令人驚歎的答案,非常感謝! – Mia

1

你基本上繪製一條折線(線條,在OpenGL術語)。有三個關鍵問題:

  • 如何測試您是否關閉了折線。
  • 如何獲得封閉的折線,一旦你已經決定,有一個。
  • 如何柵格化閉合多段線以獲得填充的形狀。

對於第一個問題,您可以(粗略地說,雖然實際上會有點煩瑣)存儲您在繪製折線時所點擊的像素序列,然後在當前位線繪圖點擊你之前繪製的東西。 (在遊戲中,線條的舊位會在一段時間後過期 - 這可以通過存儲像素的時間值進行建模,並在年齡大於某個閾值時將其刪除。)

對於第二個問題,您只是將像素序列的一部分保留在開始點和結束點之間。

第三個問題有點難,如果你想強有力地做(有很多「愉快」的特殊情況) - 做一個「多邊形光柵化」的搜索,並準備好相當多的閱讀。我曾經寫過一些代碼來做到這一點,這是在這裏,爲它的價值:

https://github.com/sgolodetz/millipede/blob/master/trunk/source/common/graphics/PolylineRasterizer.cpp

注意,在實踐中,這一切都將可能是相當fiddlier不是我這裏描述的 - 但一些沿這些線粗略地說你可能會這樣做。

0

使用開始路http://www.html5canvastutorials.com/tutorials/html5-canvas-shape-fill/

<!DOCTYPE HTML> 
<html> 
<head> 
<style> 
    body { 
    margin: 0px; 
    padding: 0px; 
    } 
</style> 
</head> 
<body> 
<canvas id="myCanvas" width="578" height="200"></canvas> 
<script> 
    var canvas = document.getElementById('myCanvas'); 
    var context = canvas.getContext('2d'); 

    // begin custom shape 
    context.beginPath(); 
    context.moveTo(170, 80); 
    context.bezierCurveTo(130, 100, 130, 150, 230, 150); 
    context.bezierCurveTo(250, 180, 320, 180, 340, 150); 
    context.bezierCurveTo(420, 150, 420, 120, 390, 100); 
    context.bezierCurveTo(430, 40, 370, 30, 340, 50); 
    context.bezierCurveTo(320, 5, 250, 20, 250, 50); 
    context.bezierCurveTo(200, 5, 150, 20, 170, 80); 

    // complete custom shape 
    context.closePath(); 
    context.lineWidth = 5; 
    context.fillStyle = '#8ED6FF'; 
    context.fill(); 
    context.strokeStyle = 'blue'; 
    context.stroke(); 
</script> 
</body> 
</html>