使用C++计算旋转矩形交叉区域

问题描述

我正在尝试使用 C++ 计算两个任意大小和旋转的矩形的交叉区域。我发现了一些关于非旋转矩形的信息,但关于旋转和不同大小的矩形的信息很少。我想创建一个 C/C++ 程序来执行此操作。

有没有人有任何信息/提示或更好的一些简单的代码可以提供帮助?

预先感谢您的任何帮助。

解决方法

我认为最简单的方法是使用 Sutherland-Hodgman 算法将一个矩形裁剪成另一个:https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm

然后您使用鞋带公式计算所得多边形的面积:https://en.wikipedia.org/wiki/Shoelace_formula

,

已经有一个question(有六个答案),但是那里的 OP 对大约交叉路口区域感兴趣。

如果您需要一个精确解决方案,那么您必须考虑许多极端情况,这使得几何问题很难在具有有限数据的真实计算机上正确解决精度 - 例如,参见 here

幸运的是,已经有许多高质量的计算几何库,可以使用精确数字进行精确计算来解决此类问题。其中之一是CGAL,它是多所大学的联合项目,经过精心开发和测试。但是,该库不支持将旋转矩形作为单独的实体 - 您需要使用一般多边形。因此,您的代码将如下所示:

#include <iostream>
#include <vector>

#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Polygon_with_holes_2.h>

using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Polygon = CGAL::Polygon_2<Kernel>;
using PolygonWithHoles = CGAL::Polygon_with_holes_2<Kernel>;
using Point = Polygon::Point_2;

int main()
{
  // ------ define polygon #1
  const std::vector<Point> pts1{/* ... polygon #1 vertices ... */};
  const Polygon p1(pts1.cbegin(),pts1.cend());
  // ------ define polygon #2
  const std::vector<Point> pts2{/* ... polygon #2 vertices ... */};
  const Polygon p2(pts2.cbegin(),pts2.cend());
  // ------ compute intersection - you'll get a single polygon without holes!!!
  std::vector<PolygonWithHoles> res;
  CGAL::intersection(p1,p2,std::back_inserter(res));
  // ------ output area of intersection
  std::cout << res[0].outer_boundary().area() << std::endl;
}

如果你不关心几何计算的稳健性,那么这个库仍然可以帮助你——你可以选择常规的 double 数字来表示坐标。在这种情况下,您将获得更好的性能,但在某些情况下可能会得到错误的答案。

,

一个完整的工作示例,基于@HEKTO 回答:

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Polygon_with_holes_2.h>

using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Polygon = CGAL::Polygon_2<Kernel>;
using Point = CGAL::Point_2<Kernel>;
using PolygonWithHoles = CGAL::Polygon_with_holes_2<Kernel>;

int main() {
  const std::array<Point,4> points1{Point(1.3,2.5),Point(2.7,5.5),Point(1.3,5.5)};
  const Polygon polygon1(points1.cbegin(),points1.cend());

  const std::array<Point,4> points2({Point(1.47,2.65),Point(2.63,2.34),Point(3.3,4.85),Point(2.14,5.16)});
  const Polygon polygon2(points2.cbegin(),points2.cend());

  std::vector<PolygonWithHoles> intersections;
  CGAL::intersection(polygon1,polygon2,std::back_inserter(intersections));

  std::cout << "Intersection area: " << intersections[0].outer_boundary().area() << std::endl;

  return EXIT_SUCCESS;
}

输出:Intersection area: 2.34555

来自矩形的说明: Intersection between the rotated rectangles

,

OTHER METHODS

充分利用矩形的属性。长方形就是长方形!这使得使用三角学或积分法计算它们变得容易。

在您的情况下,使用三角学的 PS 可能更容易。