Пример #1
0
//! Place labels with greedy algorithm
void Renderer::placeLabels(const std::list<shared_ptr<Label> >& labels,
						   std::vector<shared_ptr<Label> >& placed)
{
	std::vector<shared_ptr<Label>> contained;
	contained.reserve(labels.size());

	// first sort out all out-of-bounds labels
	for (auto& l : labels) {
		if (bounds.contains(l->box))
			contained.push_back(l);
		else if (bounds.getIntersection(l->box).getArea() > 0.0){
			if (isCutOff(l->box, l->owner))
				continue;

			double intersect_max = 0.0;
			for (auto& other : placed)
				intersect_max = std::max(intersect_max, other->box.getIntersection(l->box).getArea());


			if (intersect_max < RENDERER_LABEL_OVERLAP * l->box.getArea())
				placed.push_back(l);
		}
	}

	for (auto& l : contained) {
		double width = l->box.getWidth();
		double height = l->box.getHeight();
		FloatPoint trans[5] = {
			FloatPoint(0.0, 0.0),         // original
			FloatPoint(0.0, -height/2.0), // above
			FloatPoint(width/2.0, 0.0),   // to the right
			FloatPoint(0.0, height/2.0),  // below
			FloatPoint(width/2.0, 0.0)    // to the left
		};
		FloatRect possible[5];
		for (int i = 0; i < 5; i++)
			possible[i] = l->box.translate(trans[i].x, trans[i].y);

		// stores the size of the intersecting area
		double intersect_max[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
		for (auto& other : placed) {
			for (int i = 0; i < 5; i++) {
				FloatRect intersection = possible[i].getIntersection(other->box);
				intersect_max[i] = std::max(intersect_max[i], intersection.getArea());
			}
		}

		int min = 0;
		for (int i = 1; i < 5; i++)
			if (intersect_max[i] < intersect_max[min]
			 && bounds.contains(possible[i])) // don't push label outside of the bounding-box
				min = i;

		// only place label if intersecting area is 1/10 the label
		if (intersect_max[min] < RENDERER_LABEL_OVERLAP * l->box.getArea()) {
			l->translate(trans[min].x, trans[min].y);
			placed.push_back(l);
		}
	}
}
Пример #2
0
//! Place labels with greedy algorithm
void Renderer::placeShields(const std::list<shared_ptr<Shield> >& shields,
						   std::vector<shared_ptr<Shield> >& placed)
{
	std::vector<shared_ptr<Shield>> contained;
	contained.reserve(10);

	// first sort out all out-of-bounds labels
	for (auto& shield : shields) {
		if (!bounds.contains(shield->shield))
			continue;

		// stores the size of the intersecting area
		double intersect_max = 0.0;
		for (auto& other : placed) {
				FloatRect intersection = shield->box.getIntersection(other->box);
				intersect_max = std::max(intersect_max, intersection.getArea());
		}

		// only place label if intersecting area is 1/10 the label
		if (intersect_max < RENDERER_SHIELD_OVERLAP * shield->box.getArea())
			placed.push_back(shield);
	}
}