30 幾何演算法 線段集合內是否存在相交線段檢測

2021-10-05 18:31:10 字數 2361 閱讀 2420

檢測線段集合內是否存在兩個相交線段。

相比窮舉的方式,

利用事件點掃瞄法,最壞下時間複雜度為θ(nlg(n))

extern "c" class algorithmlib segmentintersection

; class linepoint

; class comparablelinegeometry

; segmentintersection();

~segmentintersection();

static bool run(const planegeometry::linegeometry& line1_, const planegeometry::linegeometry& line2_);

static bool run(const datastruct::array::dynarray& arrlines_);

};

bool segmentintersection::run(

const datastruct::array::dynarray& arrlines_)

else

}// 對2n個事件點

// 按優先順序

// x位置從小到大

// 從左端點到右端點

// y位置從小到大

// 排序

_arrcritialpoint.sort(

(const linepoint*& lpo1_, const linepoint*& lpo2_)->int

else

}if (lpo1_->m_type != lpo2_->m_type)

else

}double _ndeltay = lpo1_->m_popos.m_npos[1] - lpo2_->m_popos.m_npos[1];

if (_ndeltay > 0.0)

else if (_ndeltay < 0.0)

else

}); typedef datastruct::tree::sortedbalancebinarytreelinemap;

typedef datastruct::tree::sortedbalancebinarytree::node linemapnode;

linemap _linemap;

for (int _i = 0; _i < _arrcritialpoint.getsize(); _i++)

linemapnode* _plinenode = _linemap.search(comparablelinegeometry(_pnode->getpair().m_nvalue));

linemapnode* _pprelinenode = _linemap.pre(_plinenode);

linemapnode* _psuclinenode = _linemap.suc(_plinenode);

if (_pprelinenode

&& segmentintersection::run(_pprelinenode->getpair().m_nvalue, _plinenode->getpair().m_nvalue))

else if (_psuclinenode

&& segmentintersection::run(_psuclinenode->getpair().m_nvalue, _plinenode->getpair().m_nvalue))

}else

_linemap.delete(_plinenode->getpair().m_nkey);

} }for (int _i = 0; _arrcritialpoint.getsize(); _i++)

return false;

}

演算法目標:

給定線段集合

判斷此線段集合中是否存在相交的線段

演算法採用迭代實現,

用迴圈不變式來證明正確性

迴圈不變式:

每次迭代開始時,

1. _linemap維護了乙個線段集合,集合內每個線段均和上一事件點相交。

2. 線段集合按和事件點交點y座標有序儲存。

3. 線段集合內任意兩個線段不相交。

4. 目前為止尚未檢測到線段相交。

乙個定理:

如果線段集合存在相交的兩個線段,則按上述事件點掃瞄的方式,

必然會在某個事件點掃瞄處理後,

相交的兩個線段變成_linemap集合中連續的。

由於演算法中會檢測到所有_linemap中線段變為連續的情況。

故,演算法可以完成線段集合是否存在交點的檢測。

演算法 線段樹

幾次的省賽,成績都不是很理想。不過這幾次省賽的給我們留下了很多寶貴的經驗 首先發現的是線段樹,每考必有 今天我們學習的就是線段樹 線段樹的功能是 1 對一段數字進行累加。2 對數字進行搜尋。3 將包含在區間int的元素x插入到樹t中。4 從線段樹中刪除元素x。5 對線段樹上的資料進行更新。今天,我們...

演算法 線段樹

線段樹的根節點是整段區間,其它結點是由區間不斷二分得到的子區間,其中葉子結點是區間的每個單獨的元素。這裡使用結構體存線段樹。struct tree tree 4 maxn 2 注意陣列大小至少要開到區間長度的四倍大這裡預設我們要求的是區間和,故結點值均為區間和。可以視情況改變結點值的含義。void ...

演算法 線段樹 活動排期衝突問題

今天偶然遇到了乙個有點意思的問題,將它轉化成了題目,有點令人懷念 有一張活動排期表,表上有n組活動的排期。其中,每組活動都會開啟若干次,每個活動都有乙個唯一id和乙個開啟時間a,關閉時間b。同組活動不能在相同時間內開啟兩個及以上。如果同組活動同時開啟,則會產生衝突,活動開啟失敗。問 當前活動表內是否...