繁体   English   中英

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

[英]Computing rotated rectangle intersection area using C++

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

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

提前感谢您的任何帮助。

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

然后使用鞋带公式找到生成的多边形的面积: https://en.wikipedia.org/wiki/Shoelace_formula

已经有一个关于此的问题(有六个答案),但是那里的 OP 对交叉路口的大致区域感兴趣。

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

幸运的是,已经有许多高质量的计算几何库,可以使用精确数字的精确计算来解决这类问题。 其中之一是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, 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;
}

Output: Intersection area: 2.34555

矩形的插图: 旋转矩形之间的交点

用积分计算交集

使用矩形的属性对您有利。 长方形就是长方形。 这使得使用三角函数或积分计算它们变得容易。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM