次のアルゴリズムを提案します。
prepareData();
if (findBorder('left')) {
foreach (direction in ['top', 'right', 'bottom']) {
findBorder(direction)
}
} else noIntersectionExists
prepareData (O(mlogm)):
垂直
方向の境界と水平方向の境界を並べ替え
ます。 結果を次のように
保存します。など
findBorder(left): // 他の方向も同様です 最良の場合 O(n)、最悪の場合 O(2m-n)
arrIntersections = new Array;
//an intersection has a depth (number of rectangles intersected), a top and bottom border and list of rectangles
for(i=0; i < 2*m-n-1; i++){ // or (i = 2*m-1; i > n; i--)
if(isLeftBorder(arrX[i])){
addToIntersections(arrX[i].rectangle, direction);
if(max(intersections.depth) = n) break;
} else {
removeFromIntersections(arrX[i].rectangle, direction);
}
}
addToIntersections(rectangle, direction): // direction=left の説明
最良のケース: O(n)、最悪のケース: O(m)
hasIntersected = false;
foreach(intersection in intersection){
if(intersect(intersection, rectangle)){
hasIntersected = true
intersections[] = {
depth: intersection.depth,
bottom: min(intersection.bottom, rectangle.bottom),
top: max(...)}
intersection.depth++
intersection.bottom = max(intersection.bottom, rectangle.bottom)
intersection.top = max(...)
}
}
if(!hasIntersected)
intersections[]={depth:1, bottom:rectangle.bottom, top:rectangle.top}
これにより、O(n^2) と O(m*(mn/2)) の間の全体的な順序が得られます。
私の疑似コードが十分に明確であることを願っています