C++ 如何确保给定的一组点位于可能的正方形的边界上?

C++ 如何确保给定的一组点位于可能的正方形的边界上?,c++,algorithm,geometry,computational-geometry,C++,Algorithm,Geometry,Computational Geometry,给定一组积分坐标,检查给定的所有点是否位于一个可能的正方形的侧面,以便形成的正方形的轴平行于X轴和Y轴。如果这样的正方形是可能的,给出正方形的最小可能边 假设点是(0,0),(1,1),(2,2) 答:正方形是不可能的 假设点是(0,0),(0,2),(0,5),(0,7),`(3,0)。 回答:正方形是可能的,边的最小长度是7 我试过了,发现了很多拐弯处的案例,似乎不可能单独处理。我想知道是否有人能对这类问题给出一个更普遍的方法,以及如何朝着正确的方向思考。 提前谢谢。 坐标范围:-1000您

给定一组积分坐标,检查给定的所有点是否位于一个可能的正方形的侧面,以便形成的正方形的轴平行于X轴和Y轴。如果这样的正方形是可能的,给出正方形的最小可能边

假设点是
(0,0)
(1,1)
(2,2)

答:正方形是不可能的

假设点是
(0,0)
(0,2)
(0,5)
(0,7)
,`(3,0)。
回答:正方形是可能的,边的最小长度是7

我试过了,发现了很多拐弯处的案例,似乎不可能单独处理。我想知道是否有人能对这类问题给出一个更普遍的方法,以及如何朝着正确的方向思考。 提前谢谢。
坐标范围:
-1000您可以使用轴对齐边界框(ABB)的常见概念来解决此问题。给定一组点,计算ABB:

在所有点上循环一次,找出最小x、最小y、最大x和最大y。然后,需要对照所有点检查由左下角(min_x,min_y)和右上角(max,max y)两个角定义的长方体,以查看它们是否位于其周长上。由于坐标是整数(无浮点误差),因此很容易做到:对于每个点,x坐标或y坐标必须与AAB的相应坐标匹配,而另一个坐标必须在其他坐标的范围内。希望这是有意义的。

轴的要求有助于我们进行以下观察

  • 每一个这样的正方形都由两条平行的垂直线限定,垂直线上的每一点都有相同的X坐标。让我们把这些坐标称为
    maxX
    minX
    。(其中一个比另一个小)
  • 每个这样的正方形都有两条平行的水平线,垂直线上的每个点都有相同的Y坐标。让我们把这些坐标称为
    maxY
    minY
  • 这一点至关重要:输入列表中的每个点都必须具有X坐标匹配
    maxX
    minX
    或Y坐标匹配
    maxY
    minY
    。(注意OR。如果有一个点两者都不匹配,比如前面的示例中的
    (1,1)
    ,那么您就有一个反例)
  • 这里有一个类似c++的伪代码来计算这些量。假设您有一个适当的
    结构

    bool isSquare(vector<Point> points) { 
       double maxX = points[0].X;
       double minX = points[0].X;
       double maxY = points[0].Y;
       double minY = points[0].Y;
    
       // set maxX, minX, maxY, minY
       for(int i = 0; i < points.size(); i++) {
          maxX = max(points[i].X, maxX);
          minX = min(points[i].X, minX);
          maxY = max(points[i].Y, maxY);
          minY = min(points[i].Y, minY);
       }
    
       // Finally, find a point which matches neither {maxX, minX, maxY, minY}
       for(int i = 0; i < points.size(); i++) {
          if (points[i].X != maxX && points[i].X != minX && points[i].Y != maxY && points[i].Y != minY) return false;
        }
    
        // We are not done yet!
     }
    
    bool-isSquare(向量点){
    double maxX=点[0].X;
    双最小值=点[0].X;
    double maxY=点[0].Y;
    双minY=点[0].Y;
    //设置maxX,minX,maxY,minY
    对于(int i=0;i
    现在通过此代码中的检查可以确保这些点至少形成一个矩形,并且矩形内没有点。确保矩形是正方形是较难的部分。对于该部分,您必须检查:

  • 一个点位于矩形的角上,即其X坐标匹配
    {maxX,minX}
    和Y坐标匹配
    {maxY,minY}
    。如果找到,则需要找到该点与相应边上任何其他点的最大距离
  • 如果不存在这样的角落,你的境况会好得多!。在这种情况下,正方形边的长度就是
    max(maxX-minX,maxY-minY)

    <> P>你需要小心地为这个角落查找部分编写伪代码,并考虑所有的情况。但我认为,一旦完成,这将最终给出答案。

    如果你通过
    xmin
    xmax
    ymin
    ymax
    定义正方形,那么所有点都必须位于这些坐标之一。即,如果对于所有顶点
    v
    ,则正方形有效:

    v.x == xmin || v.x == xmax || v.y == ymin || v.y == ymax
    
    边界的候选对象是点的边界矩形的边界。如果计算这些边界,请维护每条边的顶点列表

    如果无法将每个顶点指定给边,则无法创建正方形

    现在很可能矩形不是正方形。所以我们需要扩大它的最短边。如果选择了边,则需要选择是移动最小边还是最大边。这就是关联顶点列表发挥作用的地方。对于要移动的边,请检查所有关联的顶点是否也与另一条边关联。然后移动此边缘是安全的。如果我们既不能移动最小边也不能移动最大边,那么就不可能创建正方形


    由此产生的最小边长就是边缘的距离。

    我正试图想出一种方法在一次传球中做到这一点,但现在已经是深夜了,我很累,所以

    • 对所有元素运行一次,并记录整套元素的最小值和最大值
      x
      y
      。正方形的边长(如果存在)将为
      max(xmax-xmin,ymax-ymin)

    • 把要点再看一遍。要描述平行于轴的正方形,每个点必须具有

      x==xmin | | x==xmax | | y==ymin | y==ymax

      也就是说,至少有一个坐标必须位于正方形的一侧。如果任何一点失败,那么你就没有一个正方形


    我很确定这已经足够了,但分两步进行似乎并不理想。这是个有趣的问题,祝你好运。

    请考虑新的编辑