顶角判别法识别多边形的凸凹性,并将凹多边形近似处理为凸多边形

顶角判别法:    该算法首先在顶点数据集中找J坐标值最大的点,若J坐标值最大的点不止一个,则在J坐标值最大的这些点中找,坐标值最大的点,这样找出的顶

点一定显凸性;然后,以该凸顶点为支点顺时针方向旋转后一个顶点到支点与前一个顶点的射线上,若旋转角度小于7T,则记为“+”号,大于7T则记为“一”号;遍历

其他顶点,以该顶点为支点顺时针方向旋转后一个顶点到支点与前一个顶点的射线上,旋转的角度小于7T则记为“+”号,大于7T则记为“一”号(凸凹点的判断);最后,

如果该点和顶点的符号相同则为凸点,否则为凹点。

效果图:           

              

处理后:

             

代码实现:

          

/**
 * 顶点判决法,并将凹多边形近似处理为凸多边形
 */
void MyPainterWidget::apexAngle(){
  //1.找顶角
  int maxIndex = 0 ;
  int maxY = points[0].y();
  int maxX;
  for(int i = 1;i < points.size();i++){
      if(points[i].y() < maxY){
          maxY = points[i].y();
          maxX = points[i].x();
          maxIndex = i;
      }else if(points[i].y() == maxY){
          //y值相同
          if(points[i].x() > maxX){
              maxX = points[i].x();
              maxIndex = i;
          }
      }
  }

 // qDebug()<<"maxIndex:"<<maxIndex;
  //2.1 找到顶角后,判断是否是凹点如果是,则移除
  // 逐次的往后求sin  sin < 0 :凸点:凹点;
  preIndex = maxIndex;
  for(int i = maxIndex + 1;i + 1 < points.size() && i - 1 >= 0;i++){
      filter(preIndex,i,i + 1);
  }


  if(points.size() > 2){
      //2.2 求最后一个角
      filter(preIndex,points.size() - 1,0);

      //2.3求第0个角
      filter(preIndex,0,1);

  }

  //2.4 找出顶角前面的凹点
  for(int i = 1;i < maxIndex + 1;i++){
      filter(preIndex,i,i+1);
  }
}

/**
 * @brief MyPainterWidget::filter
 * @param pre 前一个凸点
 * @param cur 当前点
 * @param next 下一个点
 * 记录最新凸点,剔除凹点
 */
void MyPainterWidget::filter(int pre,int cur,int next){
    if(!isBump(&points[pre],&points[cur],&points[next])){
        //更新前面最新的一个凸点
        preIndex = cur;
    }else{
        //从容器中移除当前凹点
        points.erase(points.begin() + cur);
         qDebug()<<"delete:"<< cur;
    }
}

//三个点组成的夹角,判断该点是否是凸点
bool MyPainterWidget::isBump(QPoint *p1,QPoint *p2,QPoint *p3){
    int sin = ((p1->x() - p2->x())*(p3->y() - p2->y()) - (p3->x() - p2->x())*(p1->y() - p2->y()));

    return sin < 0;

}

完整工程下载地址:http://download.csdn.net/detail/buqulinghun/9715040

参考论文:平面多边形凹凸性的顶角判别法,万书亭,韩庆瑶

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值