1

我有一个问题,需要简化代码来表达它。简而言之,我需要用 Javascript 构建代码来绘制连接的 SVG 线条。简单的例子:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >

<line x1="50" y1="50" x2="200" y2="50" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="100" y1="100" x2="400" y2="100" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="300" y1="300" x2="200" y2="300" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="100" y1="50" x2="100" y2="400" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="300" y1="100" x2="300" y2="300" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />
<line x1="200" y1="300" x2="200" y2="200" stroke="steelblue" stroke-width="20" onclick="fillWall(evt)" />

<script type="text/javascript"> 
<![CDATA[
function fillWall(evt) {
  var tgt=evt.target;
  tgt.setAttributeNS(null, "stroke", "firebrick");
}
]]>
</script>
</svg>

这是几堵墙的迷宫,当你点击一些它会改变颜色时,所以我需要一键完成所有连接的绘制,无论在哪个墙上点击。在全尺寸范围内,这些墙几乎有数千个,有些是相连的,有些没有。我尝试学习递归函数,但很容易超出堆栈大小。请帮忙,我会很感激。

4

2 回答 2

1

我的伪代码版本:

function doWall(I_oWall) {
    if I_oWall.painted then return;
    I_oWall.paint();
    for each wall in walls
        if I_oWall.isAdjacentTo(wall) then
            doWall(wall);
        end if
    loop
}

抱歉,我知道这不是一个完整和完整的答案,但我认为它真的会帮助您解决问题。

干杯

于 2012-06-16T15:32:11.227 回答
1

故意有一个功能:与getBBox配对的getIntersectionList 可以帮助您解决问题。伪代码:

fillWall(evt) {
 fillConnected(evt.target, [])
}
fillConnected(node, filled) {
 if (!filled.contains(node)) {
   fill(node);
   filled.append(node);
   foreach(n in document.getIntersectionList(node.getBBox()))
    fillConnected(n, filled)
 }
}

我将尝试使用 jsFiddle 编写实际代码,稍后将发布地址...

编辑看到这个小提琴,但似乎 Firefox 仍然没有实现所需的 getIntersectionList。然后,如果我们必须自己制作,最好缓存列表,因为这将是一种相当昂贵的方法......

编辑我已经修改了仅在本地文件上工作的小提琴代码,现在在 Chrome 中运行良好,但是在墙壁刚刚接触的地方,getIntersectionList 不起作用。所以无论如何我们都必须实现我们自己的版本......稍后见......

编辑好,最后小提琴似乎起作用了。请注意,墙壁必须对其端点进行排序(x2 >= x1,y2 >= y1),您可以在墙壁上看到颜色为黄色(已校正)和绿色(仍然错误)的排序效果。

于 2012-06-16T16:54:23.330 回答