求兩個矩形之間的最小距離

正在參與的工程裏有一個小功能是求兩個矩形之間的最小距離。大致翻了一下OpenCV,貌似沒看到現成的函數,那就自己寫一個好了。

一個畫面中,兩個矩形的幾何關係大致可分爲如下幾種,以C1爲參考,分別是:

(1) 不相交,但在X或Y軸方向上有部分重合座標,比如矩形1和2,此時,最小距離爲兩個矩形之間的最小平行距離或垂直距離,如圖中紅色箭線D12所示。

(2) 不相交,在X和Y軸方向上均無重合座標,比如矩形1和3,此時最小距離爲兩矩形距離最近的兩個頂點之間的距離,如圖中紅色箭線D13。

(3) 相交,此時距離爲負數,如矩形1和4。

爲了實現以上幾何關係,寫了個小函數:

int min_distance_of_rectangles(Rect rect1, Rect rect2)
{
	int min_dist;
	
	//首先計算兩個矩形中心點
	Point C1, C2;
	C1.x = rect1.x + (rect1.width / 2);
	C1.y = rect1.y + (rect1.height / 2);
	C2.x = rect2.x + (rect2.width / 2);
	C2.y = rect2.y + (rect2.height / 2);
	
	// 分別計算兩矩形中心點在X軸和Y軸方向的距離
	int Dx, Dy;
	Dx = abs(C2.x - C1.x);
	Dy = abs(C2.y - C1.y);
	
	//兩矩形不相交,在X軸方向有部分重合的兩個矩形,最小距離是上矩形的下邊線與下矩形的上邊線之間的距離
	if((Dx < ((rect1.width + rect2.width)/ 2)) && (Dy >= ((rect1.height + rect2.height) / 2)))
	{
		min_dist = Dy - ((rect1.height + rect2.height) / 2);
	}
	
	//兩矩形不相交,在Y軸方向有部分重合的兩個矩形,最小距離是左矩形的右邊線與右矩形的左邊線之間的距離
	else if((Dx >= ((rect1.width + rect2.width)/ 2)) && (Dy < ((rect1.height + rect2.height) / 2)))
	{
		min_dist = Dx - ((rect1.width + rect2.width)/ 2);
	}
	
	//兩矩形不相交,在X軸和Y軸方向無重合的兩個矩形,最小距離是距離最近的兩個頂點之間的距離,
	// 利用勾股定理,很容易算出這一距離
	else if((Dx >= ((rect1.width + rect2.width)/ 2)) && (Dy >= ((rect1.height + rect2.height) / 2)))
	{
		int delta_x = Dx - ((rect1.width + rect2.width)/ 2);
		int delta_y = Dy - ((rect1.height + rect2.height)/ 2);
		min_dist = sqrt(delta_x * delta_x  + delta_y * delta_y);
	}
	
	//兩矩形相交,最小距離爲負值,返回-1
	else
	{
		min_dist = -1;
	}
	
	return min_dist;
}

測試一下:

#include <iostream>
#include <vector>
#include <math.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;
using namespace cv;

int main()
{
	// 創建一個空白背景
	Mat img(Size(1000, 1000), CV_8UC3, Scalar(255, 255, 255));
	
	// 三個矩形,1和2、1和3分別代表兩種位置關係
	Rect rect1(200,200,300,300);
	Rect rect2(600,100,300,200);
	Rect rect3(700,600,100,100);
	Rect rect4(100,400,200,200);
	
	//繪製在背景圖像上
	rectangle(img, rect1, Scalar(255, 0, 0), -1);
	rectangle(img, rect2, Scalar(0, 255, 0), -1);
	rectangle(img, rect3, Scalar(0, 0, 255), -1);
	rectangle(img, rect4, Scalar(0, 255, 255), -1);
	
	imshow("img", img);
	waitKey(0);
	imwrite("rects.bmp", img);
	
	//開始計算距離
	int min_dist_12 = min_distance_of_rectangles(rect1, rect2);
	int min_dist_13 = min_distance_of_rectangles(rect1, rect3);
	int min_dist_14 = min_distance_of_rectangles(rect1, rect4);
	
	cout << "Minimun distance between rect1 and rect2 is: " << min_dist_12 << endl;
	cout << "Minimun distance between rect1 and rect3 is: " << min_dist_13 << endl;
	cout << "Minimun distance between rect1 and rect4 is: " << min_dist_14 << endl;
	
	return 0;
}

繪製的實驗圖像:

最小距離計算執行結果如下,與預期的結果相同。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章