/// Create the range calculator
B2DConnectedRanges() :
maDisjunctAggregatesList()
{
}
/** Add an additional range.
Thismethodintegratesanewrangeintotheconnected rangeslists.Themethodhasaworst-casetimecomplexity ofO(n^2),withndenotingthenumberofalreadyadded ranges(typically,forwell-behavedinput,itisO(n) though).
*/ void addRange( const B2DRange& rRange, const UserData& rUserData )
{ // check whether fast path is possible: if new range is // outside accumulated total range, can add it as a // separate component right away. constbool bNotOutsideEverything(
maTotalBounds.overlaps( rRange ) );
// update own global bounds range
maTotalBounds.expand( rRange );
// assemble anything intersecting with rRange into // this new connected component
ConnectedComponents aNewConnectedComponent;
// as at least rRange will be a member of // aNewConnectedComponent (will be added below), can // preset the overall bounds here.
aNewConnectedComponent.maTotalBounds = rRange;
// STAGE 1: Search for intersecting maDisjunctAggregatesList entries
// if rRange is empty, it will intersect with no // maDisjunctAggregatesList member. Thus, we can safe us // the check. // if rRange is outside all other rectangle, skip here, // too if( bNotOutsideEverything &&
!rRange.isEmpty() )
{ typename ConnectedComponentsType::iterator aCurrAggregate; typename ConnectedComponentsType::iterator aLastAggregate;
// flag, determining whether we touched one or more of // the maDisjunctAggregatesList entries. _If_ we did, // we have to repeat the intersection process, because // these changes might have generated new // intersections. bool bSomeAggregatesChanged;
// loop, until bSomeAggregatesChanged stays false do
{ // only continue loop if 'intersects' branch below was hit
bSomeAggregatesChanged = false;
// iterate over all current members of maDisjunctAggregatesList for( aCurrAggregate=maDisjunctAggregatesList.begin(),
aLastAggregate=maDisjunctAggregatesList.end();
aCurrAggregate != aLastAggregate; )
{ // first check if current component's bounds // are empty. This ensures that distinct empty // components are not merged into one // aggregate. As a matter of fact, they have // no position and size.
if( !aCurrAggregate->maTotalBounds.isEmpty() &&
aCurrAggregate->maTotalBounds.overlaps(
aNewConnectedComponent.maTotalBounds ) )
{ // union the intersecting // maDisjunctAggregatesList element into // aNewConnectedComponent
// calc union bounding box
aNewConnectedComponent.maTotalBounds.expand( aCurrAggregate->maTotalBounds );
// extract all aCurrAggregate components // to aNewConnectedComponent
aNewConnectedComponent.maComponentList.splice(
aNewConnectedComponent.maComponentList.end(),
aCurrAggregate->maComponentList );
// remove and delete aCurrAggregate entry // from list (we've gutted it's content // above). list::erase() will update our // iterator with the predecessor here.
aCurrAggregate = maDisjunctAggregatesList.erase( aCurrAggregate );
// at least one aggregate changed, need to rescan everything
bSomeAggregatesChanged = true;
} else
{
++aCurrAggregate;
}
}
} while( bSomeAggregatesChanged );
}
// STAGE 2: Add newly generated connected component list element
// add new component to the end of the component list
aNewConnectedComponent.maComponentList.push_back(
ComponentType( rRange, rUserData ) );
// do some consistency checks (aka post conditions)
OSL_ENSURE( !aNewConnectedComponent.maComponentList.empty(), "B2DConnectedRanges::addRange(): empty aggregate list" );
OSL_ENSURE( !aNewConnectedComponent.maTotalBounds.isEmpty() ||
aNewConnectedComponent.maComponentList.size() == 1, "B2DConnectedRanges::addRange(): empty ranges must be solitary");
// add aNewConnectedComponent as a new entry to // maDisjunctAggregatesList
maDisjunctAggregatesList.push_back( aNewConnectedComponent );
}
/** Apply a functor to each of the disjunct component aggregates.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.