2013-01-02 54 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>