port of collision class

This commit is contained in:
Konstantin Käfer
2014-03-17 16:53:40 +01:00
parent 88af0b8b6c
commit 1f2c71ec8b
9 changed files with 415 additions and 22 deletions

View File

@@ -0,0 +1,78 @@
#ifndef LLMR_TEXT_COLLISION
#define LLMR_TEXT_COLLISION
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <llmr/text/rotation_range.hpp>
namespace llmr {
// These are the glyph boxes that we want to have placed.
struct GlyphBox {
GlyphBox() {}
GlyphBox(const CollisionRect &bbox, const CollisionRect &box,
float minScale)
: bbox(bbox), box(box), minScale(minScale) {}
CollisionAnchor anchor;
CollisionRect bbox;
CollisionRect box;
bool rotate = false;
float minScale = 0.0f;
float maxScale = std::numeric_limits<float>::infinity();
};
typedef std::vector<GlyphBox> GlyphBoxes;
// These are the placed boxes contained in the rtree.
struct PlacementBox {
CollisionAnchor anchor;
CollisionRect bbox;
CollisionRect box;
bool rotate = false;
PlacementRange placementRange = {{0.0f, 0.0f}};
float placementScale = 0.0f;
float maxScale = std::numeric_limits<float>::infinity();
float padding = 0.0f;
};
struct Placement {
Placement() {}
Placement(float zoom, const PlacementRange &rotationRange)
: zoom(zoom), rotationRange(rotationRange) {}
float zoom = -1.0f;
PlacementRange rotationRange = {{0.0f, 0.0f}};
};
class Collision {
typedef boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> Point;
typedef boost::geometry::model::box<Point> Box;
typedef std::pair<Box, PlacementBox> PlacementValue;
typedef boost::geometry::index::rtree<
PlacementValue, boost::geometry::index::quadratic<16>> Tree;
public:
Collision();
Placement place(const GlyphBoxes &boxes, const CollisionAnchor &anchor,
float minPlacementScale, float maxPlacementScale, float padding,
bool horizontal);
float getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale,
float maxPlacementScale, float pad);
PlacementRange getPlacementRange(const GlyphBoxes &glyphs,
float placementScale);
void insert(const GlyphBoxes &glyphs, const CollisionAnchor &anchor,
float placementScale, const PlacementRange &placementRange,
bool horizontal, float padding);
private:
Tree tree;
};
}
#endif

View File

@@ -31,13 +31,6 @@ struct CollisionRect {
: tl(tl), br(br) {}
};
struct CollisionBox {
CollisionRect box;
CollisionPoint anchor;
bool rotate = false;
PlacementRange placementRange;
};
/*
* Combine an array of collision ranges to form a continuous
* range that includes 0. Collisions within the ignoreRange are ignored
@@ -76,8 +69,9 @@ CollisionList rotatingFixedCollisions(const CollisionRect &rotating,
/*
* Calculate the range a box conflicts with a second box
*/
CollisionRange rotationRange(const CollisionBox &inserting,
const CollisionBox &blocker, double scale);
template <typename InsertingBox, typename BlockingBox>
CollisionRange rotationRange(const InsertingBox &inserting,
const BlockingBox &blocker, float scale);
}
#endif

View File

@@ -15,11 +15,31 @@ inline T max(T a, T b) {
return b > a ? b : a;
}
template <typename T>
inline T max(T a, T b, T c) {
return max(max(a, b), c);
}
template <typename T>
inline T max(T a, T b, T c, T d) {
return max(max(a, b), max(c, d));
}
template <typename T>
inline T min(T a, T b) {
return b < a ? b : a;
}
template <typename T>
inline T min(T a, T b, T c) {
return min(min(a, b), c);
}
template <typename T>
inline T min(T a, T b, T c, T d) {
return min(min(a, b), min(c, d));
}
// Find the angle of the two vectors, solving the formula for the cross product
// a x b = |a||b|sin(θ) for θ.
template <typename T = double, typename S>