【问题标题】:Validating for rectangle overlaps in Solidity在 Solidity 中验证矩形重叠
【发布时间】:2018-01-18 21:12:44
【问题描述】:

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

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

这就是我想做的事情。为点创建另一个结构体,包含:x、y、主矩形数组的索引。

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

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

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

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

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

【问题讨论】:

    标签: solidity


    【解决方案1】:

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

    在 Solidity 中:

    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 函数来检索所有存储的矩形并在客户端进行比较。这将是缓慢而复杂的,但如果费用是您最关心的问题,这是一种选择。您选择的方法将取决于您的合同需要支持多少矩形、您正在寻找的性能以及您的成本限制。

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 2023-04-01
      • 2013-03-09
      • 2016-06-27
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      相关资源
      最近更新 更多