27 double average(
SPItem *
item, std::list<SPItem *> &others);
30 std::vector<SPItem *> unclump_remove_behind(
SPItem *
item,
SPItem *closest, std::list<SPItem *> &rest);
41 std::map<const gchar *, Geom::Point> c_cache;
42 std::map<const gchar *, Geom::Point> wh_cache;
50 std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(
item->
getId());
51 if (i != c_cache.end()) {
69 std::map<const gchar *, Geom::Point>::iterator i = wh_cache.find(
item->
getId());
70 if (i != wh_cache.end()) {
114 double dist_r = (
Geom::L2(c2 - c1) - r1 - r2);
119 if ((stretch1 > 1.5 || stretch1 < 0.66) && (stretch2 > 1.5 || stretch2 < 0.66)) {
120 std::vector<double> dists;
121 dists.push_back(dist_r);
124 std::vector<Geom::Point> c1_points(2);
146 std::vector<Geom::Point> c2_points(2);
168 for (
int i = 0; i < 2; i++) {
169 for (
int j = 0; j < 2; j++) {
170 dists.push_back(
Geom::L2(c1_points[i] - c2_points[j]));
175 return *std::min_element(dists.begin(), dists.end());
184double Unclump::average(
SPItem *
item, std::list<SPItem *> &others)
188 for (
SPItem *other : others) {
207 double min = HUGE_VAL;
208 SPItem *closest =
nullptr;
210 for (
SPItem *other : others) {
214 double dist = this->dist(
item, other);
215 if (dist < min && fabs(dist) < 1e6) {
229 double max = -HUGE_VAL;
230 SPItem *farthest =
nullptr;
232 for (
SPItem *other : others) {
236 double dist = this->dist(
item, other);
237 if (dist > max && fabs(dist) < 1e6) {
251std::vector<SPItem *> Unclump::unclump_remove_behind(
SPItem *
item,
SPItem *closest, std::list<SPItem *> &rest)
268 std::vector<SPItem *> out;
269 for (
SPItem *other : rest) {
276 if (val_item * val_other <= 1e-6) {
279 out.push_back(other);
289void Unclump::push(
SPItem *from,
SPItem *what,
double dist)
297 std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(what->
getId());
298 if (i != c_cache.end()) {
312void Unclump::pull(
SPItem *to,
SPItem *what,
double dist)
320 std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(what->
getId());
321 if (i != c_cache.end()) {
342 std::list<SPItem *> nei;
344 std::list<SPItem *> rest;
345 for (
size_t i = 0; i <
items.size(); i++) {
350 while (!rest.empty()) {
353 nei.push_front(closest);
354 rest.remove(closest);
355 std::vector<SPItem *> new_rest =
unclump.unclump_remove_behind(
item, closest, rest);
357 for (
size_t i = 0; i < new_rest.size(); i++) {
358 rest.push_front(new_rest[new_rest.size() - i - 1]);
365 if ((nei.size()) >= 2) {
372 double dist_farthest =
unclump.dist(farthest,
item);
377 if (fabs(ave) < 1e6 && fabs(dist_closest) < 1e6 && fabs(dist_farthest) < 1e6) {
381 unclump.push(closest,
item, 0.3 * (ave - dist_closest));
382 unclump.pull(farthest,
item, 0.35 * (dist_farthest - ave));
3x3 matrix representing an affine transformation.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
Base class for visual SVG elements.
void set_i2d_affine(Geom::Affine const &transform)
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Geom::OptRect desktopVisualBounds() const
Get item's visual bbox in desktop coordinate system.
void doWriteTransform(Geom::Affine const &transform, Geom::Affine const *adv=nullptr, bool compensate=true)
Set a new transform on an object.
char const * getId() const
Returns the objects current ID string.
double dist(const Point &a, const Point &b)
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
double atan2(Point const &p)
SBasis L2(D2< SBasis > const &a, unsigned k)
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
Point unit_vector(Point const &a)
D2< T > rot90(D2< T > const &a)
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
double sum(const double alpha[16], const double &x, const double &y)
void unclump(std::vector< SPItem * > &items)
Unclumps the items in items, reducing local unevenness in their distribution.