判断轮廓点是否为矩形

最近有需求要判断多边形是否为矩形,网上查了资料,有介绍说计算所有点间的距离,用sort进行排序,unique去重后如果只留下3组数据,并且符合勾股定理,则为矩形。代码实现如下:

bool IsRectangle(const std::vector<Eigen::Vector2d>& corners) {
  if (corners.size() != 4) return false;

  auto GetLengthPow = [](Eigen::Vector2d p1,
                         Eigen::Vector2d p2) {
    return pow(p1(0) - p2(0), 2) + pow(p1(1) - p2(1), 2);
  };

  double length[6] = {GetLengthPow(corners.at(0), corners.at(1)),
                      GetLengthPow(corners.at(0), corners.at(2)),
                      GetLengthPow(corners.at(0), corners.at(3)),
                      GetLengthPow(corners.at(1), corners.at(2)),
                      GetLengthPow(corners.at(1), corners.at(3)),
                      GetLengthPow(corners.at(2), corners.at(3))};
  std::sort(length, length + 6);
  int size = std::unique(length, length + 6) - length;
  if (size == 2) {
    return true;
  }
  if (size == 3) {
    // 勾股定理
    if (length[0] + length[1] - length[2] < 1e-6) {
      return true;
    }
    return false;
  } else {
    return false;
  }
}

 但是问题在double类型的计算会有精度损失,用以下代码做了验证

#include <iostream>
#include <math.h>
#include <algorithm>

int main(){
	double a = 1.0 + 20.2 +30.03;
	double b = 51.23;
	std::cout << "a == b : " << (a == b) << std::endl;

	double len[2] = {a, b};
	auto size = std::unique(len, len + 2) - len;
	std::cout << "size = " << size << std::endl;
} 

 

 发现unique去重会受到double精度的影响,a和b理论上是一致的结果的size应为1,但由于double类型,a和b并不相等,查阅unique的源码,其中的判断就是直接 == 来判断相同并去重。因此unique用来去重double并不合适。

所以实现方法暂时修改为:判断对边相等,且有相邻两条边垂直。

如果多边形的轮廓没有顺序,可以通过找到max_y 以此点为起点,计算其与其他所有轮廓顶点的余弦值,从小到大排序则为逆时针顶点排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值