点云随笔(七)鞋带公式计算投影面积

       投影面面积采用格网法计算时,主要还是根据网格尺寸来决定,网格设置的越小,面积也就越准确,但是也会造成计算上的冗余。为此可以基于鞋带公式进行投影面面积的计算工作。

       首先需要进行的是将贴合边界统计出来,这就需要使用凹包算法,具体不过多在此处赘述,该算法主要将点云数据内凹型边界提取出来,然后采用中心点方位角法进行点云边界排序处理:

       式中\Delta y为边界点与边界点云中心点的y值作差,\Delta x为边界点与边界点云中心点的x值作差, angle则为每个点与中心点计算所得的方位角,然后基于方位角对边界点云按照大小进行排序,排序后基于高斯面积公式进行道路危险区投影面面积计算:

        式中x_{i},y_{i}为当前点坐标值, x_{i+1},y_{i+1}为下一点坐标值。

double area_shoelace_formula(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud) {//鞋带公式计算投影面积和凹包算法
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull(new pcl::PointCloud<pcl::PointXYZ>), cloud2(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ConcaveHull<pcl::PointXYZ> chull;
    chull.setInputCloud(cloud);
    chull.setAlpha(1);
    chull.reconstruct(*cloud_hull);

    pcl::PointXYZ maxpt, minpt;
    pcl::getMinMax3D(*cloud_hull, minpt, maxpt);
    double xx = (maxpt.x + minpt.x) / 2, yy = (maxpt.y + minpt.y) / 2;
    vector<pair<double, int>> pairs;

    for (int i{ 0 }; i < cloud_hull->size(); i++) {

        double angle{ 0 }, delta_x = cloud_hull->points[i].x - xx, delta_y = cloud_hull->points[i].y - yy;
        //第一象限
        if (delta_x > 0 && delta_y > 0) {
            angle = (atan(delta_y / delta_x)) * 180 / PI;
        }
        //第二象限
        else if (delta_x < 0 && delta_y > 0) {
            angle = 180 - (atan(delta_y / abs(delta_x))) * 180 / PI;
        }
        //第三象限
        else if (delta_x < 0 && delta_y < 0) {
            angle = 180 + (atan(abs(delta_y) / abs(delta_x))) * 180 / PI;
        }
        //第四象限
        else if (delta_x > 0 && delta_y < 0) {
            angle = 360 - (atan(abs(delta_y) / delta_x)) * 180 / PI;
        }
        pairs.push_back(make_pair(angle, i));
    }
    sort(pairs.begin(), pairs.end());
    double area{ 0 };
    for (int i = 0; i < cloud_hull->size()-1; i++) 
    {
        area += cloud_hull->points[pairs[i].second].x * cloud_hull->points[pairs[i + 1].second].y - cloud_hull->points[pairs[i + 1].second].x * cloud_hull->points[pairs[i].second].y;
    }
    double area_add = cloud_hull->points[pairs[cloud_hull->size() - 1].second].x * cloud_hull->points[pairs[0].second].y - cloud_hull->points[pairs[0].second].x * cloud_hull->points[pairs[cloud_hull->size() - 1].second].y;
    area = abs(area+area_add) / 2;
    cout << "凹包边界-多边形面积公式计算得到面积为" << area << endl;
    return area;
}

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值