void ComputeSkyline( struct Skyline *s, struct Building buildings[], int n ) { if ( n==1 ) { s->num = 3; s->height[0] = 0; s->height[1] = buildings->height; s->height[2] = 0; s->x[0] = MIN_X; s->x[1] = buildings->left; s->x[2] = buildings->right; s->x[3] = MAX_X; } else { struct Skyline s1; struct Skyline s2; int middle = n/2; ComputeSkyline( &s1, buildings, middle ); ComputeSkyline( &s2, buildings+middle, n-middle ); MergeSkylines( s, &s1, &s2 ); } }
// Divide and Conquer. vector<vector<int>> ComputeSkylineInInterval(const vector<vector<int>>& buildings, int left_endpoint, int right_endpoint) { if (right_endpoint - left_endpoint <= 1) { // 0 or 1 skyline, just copy it. return {buildings.cbegin() + left_endpoint, buildings.cbegin() + right_endpoint}; } int mid = left_endpoint + ((right_endpoint - left_endpoint) / 2); auto left_skyline = ComputeSkylineInInterval(buildings, left_endpoint, mid); auto right_skyline = ComputeSkylineInInterval(buildings, mid, right_endpoint); return MergeSkylines(left_skyline, right_skyline); }
void SkylineBinPack::AddSkylineLevel(int skylineNodeIndex, const Rect2U &rect) { // First track all wasted areas and mark them into the waste map if we're using one. if (mIsUseWasteMap) { AddWasteMapArea(skylineNodeIndex, rect.Size, rect.Origin.Y); } mUsedRects.Add(rect); Skyline newLine; newLine.Origin.X = rect.Origin.X; newLine.Origin.Y = rect.Top(); newLine.Width = rect.Size.Width; mLines.Insert(skylineNodeIndex, newLine); assert(newLine.Right() <= mBinSize.Width); assert(newLine.Origin.Y <= mBinSize.Height); //remove occupied lines for (size_t i = skylineNodeIndex + 1; i < mLines.Count(); ++i) { assert(newLine.Origin.X <= mLines[i].Origin.X); if (mLines[i].Right() <= newLine.Right()) { mLines.RemoveAt(i); --i; } else { int shrink = newLine.Right() - mLines[i].Origin.X; if (shrink>0) { mLines[i].Origin.X += shrink; mLines[i].Width -= shrink; } break; } } MergeSkylines(); }