Ejemplo n.º 1
0
StateTreeNode::StateTreeNode(
	const StateSet &stateSet,
	int maxDepth,
	double centerShiftMultiplier
) :
	numSpacePartitions(pow(2, stateSet.getStates().at(0)->getCoordinates().size()))
{
	const vector<AbstractState*> &states = stateSet.getStates();
	unsigned int numCoordinates = states.at(0)->getCoordinates().size();

	for(unsigned int n = 1; n < states.size(); n++){
		TBTKAssert(
			numCoordinates == states.at(n)->getCoordinates().size(),
			"StateTreeNode::StateTreeNode()",
			"Unable to handle StateSets containing states with different dimensions.",
			""
		);
	}

	//Find bounding box.
	vector<double> min;
	vector<double> max;
	double maxFiniteExtent = 0.;
	unsigned int n = 0;
	//Find first state with finite extent and initialize min and max such
	//that the state is contained inside the corresponding rectangle.
	for(; n < states.size(); n++){
		if(states.at(n)->hasFiniteExtent()){
			for(unsigned int c = 0; c < numCoordinates; c++){
				min.push_back(states.at(n)->getCoordinates().at(c) - states.at(n)->getExtent());
				max.push_back(states.at(n)->getCoordinates().at(c) + states.at(n)->getExtent());
			}
			maxFiniteExtent = states.at(n)->getExtent();
			break;
		}
	}
	//If all state have infinite extent, create a dummy box of zero extent.
	if(n == states.size()){
		for(unsigned int c = 0; c < states.at(0)->getCoordinates().size(); c++){
			min.push_back(0);
			max.push_back(0);
		}
	}
	//Loop over all remaining states and update min and max so that every
	//state is contained in the corresponding rectangle.
	for(; n < states.size(); n++){
		if(!states.at(n)->hasFiniteExtent())
			continue;

		for(unsigned int c = 0; c < numCoordinates; c++){
			if(min.at(c) > states.at(n)->getCoordinates().at(c) - states.at(n)->getExtent())
				min.at(c) = states.at(n)->getCoordinates().at(c) - states.at(n)->getExtent();
			if(max.at(c) < states.at(n)->getCoordinates().at(c) + states.at(n)->getExtent())
				max.at(c) = states.at(n)->getCoordinates().at(c) + states.at(n)->getExtent();
		}

		if(maxFiniteExtent < states.at(n)->getExtent())
			maxFiniteExtent = states.at(n)->getExtent();
	}

	//Enlarge and shift box to avoid problems with high level partition
	//boundaries cutting through states. This would be particularly
	//problematic if the states for example have three dimensional
	//coordinates, but are contained in a plane. Without shifting the box,
	//the first partition boundary would cut every state and thereby every
	//state would be added to the root node.
	for(unsigned int n = 0; n < max.size(); n++)
		max.at(n) += centerShiftMultiplier*maxFiniteExtent;
	for(unsigned int n = 0; n < min.size(); n++)
		min.at(n) -= 2.*(max.at(n) - min.at(n))*(1 - ROUNDOFF_MARGIN_MULTIPLIER);

	//Calculate center nad halfSize of the bounding box.
	halfSize = 0.;
	for(unsigned int n = 0; n < numCoordinates; n++){
		center.push_back((min.at(n) + max.at(n))/2.);
		if(halfSize < (max.at(n) - min.at(n))/2.)
			halfSize = (max.at(n) - min.at(n))/2.;
	}

	this->maxDepth = maxDepth;

	for(unsigned int n = 0; n < states.size(); n++)
		add(states.at(n));
}