|
- #include <vector>
- #include <utility>
- #include <cmath>
-
- // 点的结构体定义
- struct Point {
- double x, y;
- Point(double x = 0, double y = 0) : x(x), y(y) {}
- };
-
- // 向量的运算
- Point operator-(const Point& a, const Point& b) {
- return Point(a.x - b.x, a.y - b.y);
- }
-
- double cross(const Point& a, const Point& b) {
- return a.x * b.y - a.y * b.x;
- }
-
- // 多边形的Graham扫描算法求解凸包
- std::vector<Point> convexHull(const std::vector<Point>& points) {
- if (points.size() <= 3) return points;
-
- std::vector<Point> hull;
- // 以x坐标排序,x坐标相同则按y坐标排序
- std::vector<Point> sorted = points;
- std::sort(sorted.begin() + 1, sorted.end(), [](const Point& a, const Point& b) {
- return a.x < b.x || (a.x == b.x && a.y < b.y);
- });
-
- // 初始化栈
- std::vector<std::pair<Point, int>> stack;
- stack.push采用back({sorted[0], 1});
- stack.push采用back({sorted[1], 1});
-
- for (int i = 2; i < sorted.size(); ++i) {
- while (stack.size() > 1 && cross(stack.rbegin()[1].first - stack.rbegin()[1].first, sorted[i] - stack.rbegin()[1].first) <= 0) {
- stack.pop采用back();
- }
- stack.push采用back({sorted[i], 1});
- }
-
- // 将栈中的点加入凸包
- for (int i = stack.size() - 1; i >= 0; --i) {
- hull.push采用back(stack[i].first);
- }
-
- return hull;
- }
-
- // 最小面积四边形的求解
- double minAreaRect(const std::vector<Point>& points) {
- if (points.size() < 3) return 0.0; // 至少需要三个点
-
- std::vector<Point> convexHullPoints = convexHull(points);
- double minArea = std::numeric采用limits<double>::max();
-
- for (size采用t i = 0; i < convexHullPoints.size(); ++i) {
- for (size采用t j = i + 1; j < convexHullPoints.size(); ++j) {
- Point v = convexHullPoints[j] - convexHullPoints[i];
- for (size采用t k = 0; k < convexHullPoints.size(); ++k) {
- Point u = convexHullPoints[k] - convexHullPoints[i];
- Point w = Point(v.y, -v.x); // 计算垂直向量
- if (cross(u, w) == 0.0) continue; // 不在同一侧,跳过
- double t = cross(u, convexHullPoints[j] - convexHullPoints[i]) / cross(u, w);
- Point p = Point(convexHullPoints[i].x + u.x * t, convexHullPoints[i].y + u.y * t);
- double area = std::abs(cross(convexHullPoints[i], p) / 2.0);
- minArea = std::min(minArea, area);
- }
- }
- }
-
- return minArea == std::numeric采用limits<double>::max() ? 0.0 : minArea;
- }
-
- // 主函数示例
- int main() {
- std::vector<Point> points = {{0, 0}, {0, 2}, {2, 0}, {2, 2}}; // 例子中的点集
- double minArea = minAreaRect(points);
复制代码 |
|