如何检查给定的非凸面区域是否与给定的矩形完全重叠

时间:2012-07-04 18:34:20

标签: php javascript svg geometry

是否有任何明确定义的算法来检查给定 nonconvex 区域是否与给定的矩形完全重叠?两个形状都由折线定义,所以我们正在做矢量几何。我不想要碰撞检测,只是完全重叠。

故事如下:我们有一个SVG画布,用户可以在其上放置可能已旋转的矩形。在画布上存在基本层系统(每个矩形在它自己的层上)。请求如下:删除与其重叠的其他矩形完全阻挡的矩形。因此,除了给定矩形之外的矩形形成非凸区域,可能也是非连续的。

目标编程语言是PHP,但欢迎使用任何语言的解决方案。

3 个答案:

答案 0 :(得分:2)

这不是微妙的,但你可以检查对象的任何一点是否位于矩形的边界内,如果有的话,它就不会完全覆盖它。

答案 1 :(得分:2)

您可能想要查看一些空间拓扑套件(如带有各种端口的JTS http://www.vividsolutions.com/jts/jtshome.htm

你可以在多个几何上进行联合/交叉等操作,在你的情况下,如果你将复杂多边形与矩形结合起来,结果应该是原始多边形,否则矩形在某处“偷看”。 / p>

答案 2 :(得分: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);