線段樹思想實現矩形切割

因爲前段時間碰到一個問題,是要對一組相交、重疊、相離的矩形進行切割,一組大致有幾百個矩形,當時寫了個算法,雖然沒有問題單總感覺時間複雜度比較大,判斷次數比較多,那個算法就不發了,今天沒事有研究了下這個問題,發現用線段樹思想愛解決這個問題比較容易,準確說是用線段樹裏面的二維矩形樹,這裏只說下對兩個相交矩形的切割,對一組矩形的切割就比較簡單了。

如下圖,對矩形1按x和y方向切割後

                                 


// Clip.cpp : 定義控制檯應用程序的入口點。
//
#include <vector>
//#include <Windows.h>
using namespace std;
typedef struct tagRECT 
{
	int left;
	int top;
	int right;
	int bottom;
}RECT;

RECT intSect(const RECT rectI, const RECT rectII)
{
	RECT rect = {0, 0, 0, 0};
	rect.left = max(rectI.left, rectII.left);
	rect.right = min(rectI.right, rectII.right);
	rect.top = max(rectI.top, rectII.top);
	rect.bottom = min(rectI.bottom, rectII.bottom);
	return rect;
}

bool isFull(RECT rc)
{
	if (rc.left < rc.right && rc.top< rc.bottom)
	{
		return true;
	}
	return false;
}
int main()
{
	vector<RECT> rcVct;
	RECT rectI = {0,0,5,5};
	RECT rectII = {3,3,10,10};
	RECT inSectRect = intSect(rectI, rectII);
	if (!isFull(inSectRect))
	{
		return 0;
	}
	//利用線段樹四分思想完成相交矩形的切割
	//按x方向切割
	int k1 = inSectRect.left;
	int k2 = inSectRect.right;
	if (rectI.left < k1)
	{
		RECT temp_rect = {rectI.left, rectI.top, k1, rectI.bottom};
		rcVct.push_back(temp_rect);
	}
	if (k2 < rectI.right)
	{
		RECT temp_rect = {k2, rectI.top, rectI.right, rectI.bottom};
		rcVct.push_back(temp_rect);
	}

	//按y方向切割
	int k3 = inSectRect.top;
	int k4 = inSectRect.bottom;
	if (rectI.top < k3)
	{
		RECT temp_rect = {k1, rectI.top, k2, k3};
		rcVct.push_back(temp_rect);
	}
	if (k4 < rectI.bottom)
	{
		RECT temp_rect = {k1, k4, k2, rectI.bottom};
		rcVct.push_back(temp_rect);
	}
	rcVct.push_back(rectII);
	for (vector<RECT>::iterator pos = rcVct.begin(); pos != rcVct.end(); pos++)
	{
		printf("left: %d, top: %d, right: %d, bottom: %d\n", pos->left, pos->top, pos->right, pos->bottom);
	}
	return 0;
}

因爲在線測試無法包含Windows.h,所以將RECT自定義了一次。

在線測試(點擊此處運行


發佈了21 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章