计算两个多边形的重叠面积(C++)

本文介绍了两种方法用C++计算两个凸多边形的重叠面积。法一是基于扫线算法,通过遍历多边形边并找到交点,构建相交多边形并计算其面积。这种方法依赖于叉积和比较函数,适用于凸多边形,否则可能失败。
摘要由CSDN通过智能技术生成

计算两个多边形的重叠面积(C++)

法一

#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

const int maxn = 300;//maxn表示多边形的最大顶点数量,设为300,即多边形最多有300个顶点
const double eps = 1e-6;//eps表示一个极小的数值,设为1e-6,即0.000001,通常用于判断两个浮点数是否相等。
//位置标识
int dcmp(double x)
{
   
    if(x > eps) return 1;
    return x < -eps ? -1 : 0;
}
// 定义二维点的结构体
struct Point
{
   
    double x, y;
};
// 计算向量(p1, p2)和(p1, p3)的叉积
double cross(Point a, Point b, Point c)  
{
   
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);  //叉积公式
}

//计算线段ab和cd的交点坐标
Point intersection(Point a, Point b, Point c, Point d)
{
   
    Point p = a;
    // 计算交点坐标,公式为二维向量叉积的结果
    double t =((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x)); 
    p.x +=(b.x-a.x)*t; 
    p.y +=(b.y-a.y)*t;
    cout << "intersection p.x=" << p.x << ", p.y=" << p.y << endl;
    return p;
}

//计算多边形面积,将多边形拆解成连续三个顶点组合成的多个三角形进行计算,这个循环计算一次其实是计算两次多边形的面积。
double PolygonArea(Point p[], int n)
{
   
    if(n < 3) return 0.0;
    double s = p[0].y * (p[n - 1].x - p[1].x);
    for(int i = 1; i < n - 1; ++ i) {
   
        s += p[i].y * (p[i - 1].x - p[i + 1].x);
        // cout << "p[i-1].x =" << p[i-1].x << ", p[i-1].y=" << p[i-1].y << endl;
        // cout << "p[i].x =" << p[i].x << ", p[i].y=" << p[i].y << endl;
        // cout << "p[i+1].x =" << p[i+1].x << ", p[i+1].y=" << p[i+1].y << endl;
    }
    s += p[n - 1].y * (p[n - 2].x - p[0].x);
    cout << "s =" << s << endl;
    return fabs(s * 0.5);
}
// 计算两个凸多边形的交集面积
double CPIA(Point a[], Point b[], int na, int nb)  //ConvexPolygonIntersectArea
{
   
    Point p[20], tmp[20];//定义两个点集数组,p存储b数组中的所有点,tmp存储在计算交集时得到的新点集
    int tn, sflag, eflag;//定义临时变量:新点集中的点数,起点和终点在连续点之间的位置标志
    memcpy(p,b,sizeof(Point)*(nb));// 把点集b的所有点复制到p中,初始化p数组
    for(int i = 0; i < na && nb > 2; i++)// 遍历a数组中的所有点,如果b中的点数小于等于2,则交集面积为0
    {
   
    	// 计算连续两个点组成的矢量线段在p数组中的位置
        if (i == na - 1) {
   //对于a中的最后一个点,计算a[0]和a[na-1]组成的矢量线段在p数组中的位置
    		sflag = dcmp(cross(a[0], p[0],a[i]));//计算a[0], a[na-1]所在矢量线段和p[0]的位置关系
    	} else {
   //计算a[i], a[i+1]所在矢量线段和p[0]的位置关系
    		sflag = dcmp(cross(a[i + 1], p[0],a[i]));
    	}
        for(int j = tn = 0; j < nb; j++, sflag = eflag)//遍历p数组中的所有点,计算在两个矢量线段之间的点,并存储到新的tmp数组中
        {
   
            if(sflag>=0) {
   
            	tmp[tn++] = p[j];
            }
            if (i == na - 1) {
   //计算下一个连续点在矢量线段的位置
            	if (j == nb -1) {
   //如果已经到达p数组中的最后一个点,则计算a[0], a[na-1]所在矢量线段和p[0]的位置关系
            		eflag = dcmp(cross(a[0], p[0], a[i]));
				} else {
   //计算a[0], a[na-1]所在矢量线段和p[j], p[j+1]的位置关系
					eflag = dcmp(cross(a[0], p[j + 1], a[i])); //计算下一个连续点在矢量线段的位置
				}
			} else {
   
				if (j == nb -1) {
   //计算a[i], a[i+1]所在矢量线段和p[0]的位置关系
					eflag = dcmp(cross(a[i + 1], p[0], a[i]));
				} else {
   //计算a[i], a[i+1]所在矢量线段和p[j], p[j+1]的位置关系
					eflag = dcmp(cross(a[i + 1], p[j + 1], a[i]));
				}
			}
            if((sflag ^ eflag) == -2) {
     //1和-1的异或为-2,也就是两个点分别在矢量线段的两侧
            	if (i == na - 1) {
   
            		if (j == nb -1) {
   
            			tmp[tn++] = intersection(a[i], a[0], p[j], p[0]); //求交点
            		} else {
   
            			tmp[tn++] = intersection(a[i], a[0], p[j], p[j + 1]);
            		}
				} else {
   
					if (j == nb -1) {
   
						tmp[tn++] = intersection(a[i], a[i + 1], p[j], p[0]);
					} else {
   
						tmp[tn++] = intersection(a[i], a[i + 1], p[j], p[j + 1]);
					}
				}
            }
        }
        memcpy(p, tmp, sizeof(Point) * tn);
        nb = tn, p[nb] = p[0];
    }
    if(nb < 3) return 0.0;
    return PolygonArea(p, nb);
}

double SPIA(Point a[], Point b[], int na, int nb)    //SimplePolygonIntersectArea
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个计算两个多边形IOU的C++代码,假设多边形的顶点坐标已知: ```c++ #include <iostream> #include <vector> using namespace std; struct Point { double x, y; }; // 计算多边形面积 double polygonArea(const vector<Point>& polygon) { double area = 0; int n = polygon.size(); for (int i = 0; i < n; i++) { int j = (i + 1) % n; area += polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y; } return area / 2; } // 计算多边形的交集面积 double polygonIntersectionArea(const vector<Point>& polygon1, const vector<Point>& polygon2) { double area = 0; int n1 = polygon1.size(); int n2 = polygon2.size(); for (int i = 0; i < n1; i++) { int j = (i + 1) % n1; for (int k = 0; k < n2; k++) { int l = (k + 1) % n2; Point p1 = polygon1[i]; Point p2 = polygon1[j]; Point q1 = polygon2[k]; Point q2 = polygon2[l]; double t1 = (q1.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q1.y - p1.y); double t2 = (q2.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q2.y - p1.y); double t3 = (p1.x - q1.x) * (q2.y - q1.y) - (q2.x - q1.x) * (p1.y - q1.y); double t4 = (p2.x - q1.x) * (q2.y - q1.y) - (q2.x - q1.x) * (p2.y - q1.y); if (t1 * t2 < 0 && t3 * t4 < 0) { Point p = {0, 0}; p.x = (t2 * q1.x - t1 * q2.x) / (t2 - t1); p.y = (t2 * q1.y - t1 * q2.y) / (t2 - t1); area += polygonArea(vector<Point>{p1, p, p2}); } } } return area; } // 计算两个多边形的IOU double polygonIOU(const vector<Point>& polygon1, const vector<Point>& polygon2) { double area1 = polygonArea(polygon1); double area2 = polygonArea(polygon2); double intersectionArea = polygonIntersectionArea(polygon1, polygon2); double unionArea = area1 + area2 - intersectionArea; return intersectionArea / unionArea; } int main() { // 示例1:边长为1的正方形和边长为2的正方形,重叠面积为1,总面积为4 vector<Point> polygon1{{0, 0}, {1, 0}, {1, 1}, {0, 1}}; vector<Point> polygon2{{0.5, 0.5}, {2.5, 0.5}, {2.5, 2.5}, {0.5, 2.5}}; double iou = polygonIOU(polygon1, polygon2); cout << "IOU: " << iou << endl; // 示例2:半径为1的圆和半径为2的圆,重叠面积为2.828,总面积为9.424 const double pi = 3.14159265358979323846; vector<Point> circle1; vector<Point> circle2; int n = 100; for (int i = 0; i < n; i++) { double angle = 2 * pi / n * i; Point p1 = {cos(angle), sin(angle)}; Point p2 = {2 * cos(angle), 2 * sin(angle)}; circle1.push_back(p1); circle2.push_back(p2); } iou = polygonIOU(circle1, circle2); cout << "IOU: " << iou << endl; return 0; } ``` 以上代码实现了计算两个多边形IOU的功能,并提供了两个示例。其中,`polygonArea`函数用于计算多边形面积;`polygonIntersectionArea`函数用于计算两个多边形的交集面积;`polygonIOU`函数用于计算两个多边形的IOU。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十张哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值