1

与えられた非凸領域が与えられた長方形と完全に重なっているかどうかをチェックするための明確に定義されたアルゴリズムはありますか?両方の形状はポリラインによって定義されているため、ベクトルジオメトリを実行しています。衝突検出は必要ありません。完全にオーバーラップするだけです。

ストーリーは次のとおりです。ユーザーが長方形を配置できるSVGキャンバスがあり、回転している可能性があります。キャンバスには基本的なレイヤーシステムが存在します(各長方形は独自のレイヤー上にあります)。リクエストは次のとおりです。他の長方形が重なっているために完全に見えない長方形を削除します。したがって、指定された長方形以外の長方形は、非凸領域を形成し、場合によっては非連続にもなります。

ターゲットプログラミング言語はPHPですが、どの言語のソリューションでも大歓迎です。

4

3 に答える 3

2

微妙ではありませんが、オブジェクトのいずれかのポイントが長方形の境界内にあるかどうかを確認できます。ある場合は、オブジェクトを完全にカバーしていません。

于 2012-07-04T18:45:02.147 に答える
2

いくつかの空間トポロジスイート(さまざまなポートを備えたJTS http://www.vividsolutions.com/jts/jtshome.htmなど)を確認することをお勧めします。

複数のジオメトリで結合/交差などの操作を実行できます。この場合、複雑なポリゴンを長方形と結合すると、結果は元のポリゴンになります。そうでない場合、長方形はどこかで「覗き見」されます。

于 2012-07-04T18:51:54.423 に答える
1

長方形を回転させたときに何が起こるかわかりませんが、これが私の最初の例です。これはSVG用だったので、私はjavascriptを使用しています。有用であれば、PHPへの移植は比較的簡単です。

(function(win) {
    function Rectangle(el) {
       this.element = el;
       this._area = ''
       Rectangle.instances.push(this);
    }
    Rectangle.instances = [];
    Rectangle.largest = function() {
       var areas = Rectangle.collect('area');
       var largest_area = Math.max.apply(Math, areas); 
       return Rectangle.instances[areas.indexOf(largest_area)]
    }
    Rectangle.collect = function(prop) {
       var props = [], m;
       for (var i=0, l = Rectangle.instances.length; i<l; i++) {
          if (m = Rectangle.instances[i][prop]) {
             var val = (typeof m === 'function') ? m.call(Rectangle.instances[i]) : m;
             props.push(val);
          }      
       }
       return props;
    }
    Rectangle.prototype.area = function() {
       if (!this._area) { this._area = this.element.width * this.element.height; }
       return this._area;
    }

    Rectangle.prototype.overlaps = function(r) {
       var origin_inside = r.element.x <= this.element.x && r.element.y <= this.element.y,
           ends_inside_x = r.element.x + r.element.width >= this.element.x + this.element.width,
           ends_inside_y = r.element.y + r.element.height >= this.element.y + this.element.height;

       return origin_inside && ends_inside_x && ends_inside_y

    }




  rect1 = new Rectangle({width:10, height: 20, x:10, y:30});
  rect2 = new Rectangle({width:5, height: 30, x:20, y:40});
  rect3 = new Rectangle({width:5, height: 1, x:12, y:31});


  console.log(rect2.overlaps(rect1)) //false
  console.log(Rectangle.largest().overlaps(rect2)) //false
  console.log(rect2.overlaps(rect2)) //true
  console.log(rect3.overlaps(rect1)) //true

   //to use this with actual SVG elements, 

   var svgCanvas = document.getElementById('svgElementId');
   var ctx = svgCanvas.contentDocument

   svgr1 = new Rectangle(ctx.getElementById('rect1'))
   svgr2 = new Rectangle(ctx.getElementById('rect2'))

   console.log(svgr1.overlaps(svgr2)) //true

})(this);
于 2012-07-04T19:58:00.337 に答える