按序输出方形位置信息
1. 需求
现在有这样一个需求:
如下图,将图中的方框的信息(如每本书的书名)输出,且顺序为从左到右、从上到下。已知每个方框的左上角、右下角坐标。
而且这两点坐标由上层代码给出,此处仅处理本需求,不涉及上层代码,故此处不贴出源代码,仅展示上层提供的数据。
上层检测代码给我们提供了每个方框左上角及右下角的坐标,用一个列表box表示。并将所有box装在一个列表box_list里:
1 |
|
对应坐标位置关系如下图所示,name代表该方形名称。
最终的输出结果示例:
1 |
|
2. 方法一
2.1 想法
看到这个问题,我的第一个想法(也是最笨的方法)就是:将每个点的坐标进行比较。
具体来说就是先找到y坐标最小的点,以该点所在框为基准,循环判断每一个框的y坐标值,若他们的差的绝对值在一定范围则划定为同一行
实现这个想法需要考虑的问题有:
- 该差值是基准框与其他框的上边框还是下边框比较
- 基准框与其他框上下边框位置关系。不同的位置关系可能导致不同的结果,即在不在同一行的判断。
例如下面这种情况,A方框到底是属于第一行还是第二行呢?用几个方框的上下边框y坐标显然很难表达。
正是由于过于复杂、过于笨拙,遂很快放弃这种方案。
3. 方法二
3.1 想法
既然同时用上下边角坐标比较计算过于拙劣,那么简化一下,用他们的平均值坐标,也就是利用方形的重心,不就可以大大降低难度!而且准确率也比自己枚举法列出的情况高得多。
3.2 准备工作
获取到重心坐标后,对x、y方向坐标进行排序是必须的。对列表进行排序比较容易想到的是利用sort()函数。但单纯调用sort()默认是对列表第一个数进行排序,仍不能达到我们的目标,故需要进行一些处理。
利用sort函数的key属性,我们可以给sort传递一个函数,只要这个函数返回列表对应位数,就可以对指定位数进行排序。
1 |
|
3.3 代码实现
首先写上获取方形重心坐标函数.
计算得出重心x、y坐标后加入在原列表5、6号位,方便使用
1 |
|
然后将同一行按序放在一个列表里
先对重心y坐标排序,以最小的那个方形为基础,判断谁与之同行。只需循环遍历判断两个重心y坐标差值绝对值是否在一个误差区间内即可。这个误差需要根据实际情况进行调整
1 |
|
接着循环调用上面的函数直至排序完
而且将每行都装在一个列表里,方便后面打印信息
1 |
|
最后将信息打印出来
1 |
|
至此,我们可以测试一下。
假设有一个这样的列表:
1 |
|
他的图形大致为如下所示:
完整代码如下
1 |
|
输出结果:
至此需求解决。
4. 方法三
4.1 想法
待续…
4.2 代码实现
待续…