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