1

それを表現するための簡略化されたコードを作成した問題があります。簡単に言うと、接続された SVG 線を描画するためのコードを Javascript で作成する必要があります。簡単な例:

<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>

これはいくつかの壁の迷路で、クリックすると色が変わります。そのため、どの壁をクリックしても、すべての接続を 1 回のクリックでペイントする必要があります。原寸大では、これらの壁はほぼ千個あり、一部は接続されており、一部は接続されていません。再帰関数を学習しようとしましたが、簡単にスタック サイズを超えてしまいました。助けてください、私はそれを大いに感謝します。

4

2 に答える 2

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 に答える
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 に答える