如何在不知道宽度或高度的情况下最好地对矩形的角进行排序?
Posted
技术标签:
【中文标题】如何在不知道宽度或高度的情况下最好地对矩形的角进行排序?【英文标题】:How to best sort the corners of a rectangle without knowing the width or height? 【发布时间】:2014-03-13 17:03:00 【问题描述】:我有一个检测到的矩形的四个坐标。我想找出其中哪一个是左上角、右上角、左下角和右下角。 我自己编写的方法(不必要地)很长,实际上并没有奏效(可能是因为我在某处犯了错误)。无论哪种方式,我确信有一种更简单的方法,但我找不到使用谷歌的方法。因此,我们将不胜感激。
我的方法是用 max y(most-top), min y(most-bottom), max x(most-right), min x (most-left) 找到角点。然后如果 most-left.y > the most-right.y 那么左上点是最左,右上角是最上等。 这种方法正确吗?还有更简单的方法吗?
我的代码,对不起它的混乱和混乱...... squareX[0] 是第一个 x 坐标 squareY[0] 是第一个 y 坐标等。
编辑:原来我的方法很好,它只是 max() 没有做我认为的事情(从所有输入的数字中返回最大数字)。
maxx = max(squareX[0], squareX[1], squareX[2], squareX[3]);
maxy = max(squareY[0], squareY[1], squareY[2], squareY[3]);
minx = min(squareX[0], squareX[1], squareX[2], squareX[3]);
miny = min(squareY[0], squareY[1], squareY[2], squareY[3]);
if (squareX[0] == maxx)
mx = 0;
if (squareX[1] == maxx)
mx = 1;
if (squareX[2] == maxx)
mx = 2;
if (squareX[3] == maxx)
mx =3;
if (squareX[0] == minx)
mix = 0;
if (squareX[1] == minx)
mix = 1;
if (squareX[2] == minx)
mix = 2;
if (squareX[3] == minx)
mix = 3;
if (squareY[0] == maxy)
my = 0;
if (squareY[1] == maxy)
my = 1;
if (squareY[2] == maxy)
my = 2;
if (squareY[3] == maxy)
my = 3;
if (squareY[0] == miny)
miy = 0;
if (squareY[1] == miny)
miy = 1;
if (squareY[2] == miny)
miy = 2;
if (squareY[3] == miny)
miy = 3;
if (squareY[mix] > squareY[mx])
Pt1.x = squareX[mix];
Pt1.y = squareY[mix];
Pt2.x = squareX[my];
Pt2.y = squareY[my];
Pt3.x = squareX[mx];
Pt3.y = squareY[mx];
Pt4.x = squareX[miy];
Pt4.y = squareY[miy];
else
Pt1.x = squareX[my];
Pt1.y = squareY[my];
Pt2.x = squareX[mx];
Pt2.y = squareY[mx];
Pt3.x = squareX[miy];
Pt3.y = squareY[miy];
Pt4.x = squareX[mix];
Pt4.y = squareY[mix];
谢谢
【问题讨论】:
矩形是否与轴平行? 你的方法似乎是最简单的,所以不清楚你想简化什么。所以请添加您的代码。 它可以在任何方向,但可能不平行于轴。 首先,沿x方向的起点对矩形进行排序,然后沿y方向排序。您最终将对该组进行排序。 如果矩形可以是正方形并且可以有任何方向,如果正方形正好位于尖端,您如何定义左上角? 【参考方案1】:按照点的距离对点进行排序。前两个点是矩形的左侧。按高度对这两个点进行排序。最高的是左上角,另一个是左下角。对右边的两个做同样的事情。
【讨论】:
使用字典顺序(在 X 上比较,然后在 Y 上比较,以防出现平局)将一次性执行。【参考方案2】:您可以将标准 C++ 库 min_element
和 max_element
与自定义比较器一起使用。 Here是官方文档。
我有一个简单的例子here(抱歉,它不是纯opencv,但移植很简单)。
【讨论】:
【参考方案3】:我最近遇到了类似的问题,分享一下我的方案:
-
计算矩形的中心。
使用矩形的中心作为角的新原点。
将角转换为极坐标。
按角对角进行排序。
【讨论】:
【参考方案4】:这是尝试使用尽可能少的比较:
if X0 == X1:
# P0 and P1 are on a vertical
if X0 < X2:
# P0 and P1 are on the left
else:
# P2 and P3 are on the left
swap P0-P2
swap P1-P3
else:
# P0 and P1 are on a diagonal
if X0 < X1:
# P0 is on the left
if X0 < X2:
# P0 and P3 are on the left
swap P1-P3
else:
# P0 and P2 are on the left
swap P1-P2
else:
# P1 is on the left
if X1 < X2:
# P1 and P3 are on the left
swap P0-P3
else:
# P1 and P2 are on the left
swap P0-P2
在 X 上进行两三次比较后,您已经确定了左右角对(现在是 P0-P1 和 P2-P3)。
if Y0 > Y1:
# P1 is upper
swap P0-P1
if Y2 > Y3:
# P3 is upper
swap P2-P3
在 Y 上再进行两次比较(向下增加),矩形为 0231,顺时针方向。
您不能在少于 5 次比较中做到这一点,因为您需要覆盖 24 种排列 (2^4
【讨论】:
以上是关于如何在不知道宽度或高度的情况下最好地对矩形的角进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
视图如何在不使用依赖于框架的 intrinsicContentSize 的情况下根据其宽度的函数确定其高度?