在Solidity

时间:2018-01-18 21:12:44

标签: solidity

区块链将存储一个结构数组:x1,y1,x2,y2(uint)来表示矩形的左上角和右下角。

添加新矩形时,我需要验证它是否与区块链中的任何其他矩形重叠。

这就是我正在考虑的事情。为点创建另一个结构,包含:x,y,主矩形数组的索引。

我将有两个数组,一个按X排序,另一个按Y排序。定义每个矩形的两个角将在两个数组中都有条目。

为了验证新矩形,我搜索X数组中是否存在2个X之间的任何条目。 Y也是如此。如果X和Y的任何返回条目具有相同的"主数组"索引,然后有重叠。我还必须验证新矩形是否完全在另一个矩形内。

我仍然开始使用Solidity来尝试这一点。虽然这是一个非常昂贵的过程,但可能无法扩展。我必须多次扫描2个数组以验证我添加的每个新矩形。

是否有更有效的方法来验证我的新矩形而无需扫描2个数组?

另一种选择是只保留1个数组,并针对新数组验证每个矩形。再次,这听起来相当昂贵。

1 个答案:

答案 0 :(得分:0)

有一些简单的算法可以检测两个矩形是否重叠。可以找到一个常见的here

坚持:

pragma solidity ^0.4.19;

contract A {
    struct Rectangle {
      uint _x1;
      uint _y1;
      uint _x2;
      uint _y2;
    }   

    Rectangle[] _rectangles;

    function addRectangle(uint x1, uint y1, uint x2, uint y2) public {
      for (uint i = 0; i < _rectangles.length; i++) {
        Rectangle storage rectangle = _rectangles[i];

        // Reject if rectangle overlaps with input            
        require(x1 > rectangle._x2 || rectangle._x1 > x2);
        require(y1 > rectangle._y2 || rectangle._y1 > y2);
      }

      _rectangles.push(Rectangle(x1, y1, x2, y2));
    }
}

就费用而言,这可能是在合同中解决这个问题的最便宜的方法。因为一旦发现碰撞(并退还任何剩余的气体),这将保释,您可以通过在插入时间排序来改进它,这将允许您在某个时刻停止比较并假设成功。当然,最坏的情况仍然是所有矩形的完整循环。

另一种方法是避免在EVM中进行比较。这将要求您使用constant函数来检索所有存储的矩形并在客户端进行比较。这将是缓慢而复杂的,但如果费用是您主要关心的问题,那么它是一种选择。您选择的方法取决于合同需要支持的矩形数量,您要查找的性能以及成本限制。