Exemple #1
0
/**
Unclumps the items in \a items, reducing local unevenness in their distribution. Produces an effect
similar to "engraver dots". The only distribution which is unchanged by unclumping is a hexagonal
grid. May be called repeatedly for stronger effect.
 */
void
unclump (std::vector<SPItem*> &items)
{
    c_cache.clear();
    wh_cache.clear();

    for (std::vector<SPItem*>::const_iterator i = items.begin(); i != items.end();++i) { //  for each original/clone x:
        SPItem *item = *i;

        std::list<SPItem*> nei;

        std::list<SPItem*> rest;
        for (int i=0; i < static_cast<int>(items.size()); i++) {
            rest.push_front(items[items.size() - i - 1]);
        }
        rest.remove(item);

        while (!rest.empty()) {
            SPItem *closest = unclump_closest (item, rest);
            if (closest) {
                nei.push_front(closest);
                rest.remove(closest);
                std::vector<SPItem*> new_rest = unclump_remove_behind (item, closest, rest);
                rest.clear();
                for (int i=0; i < static_cast<int>(new_rest.size()); i++) {
                    rest.push_front(new_rest[new_rest.size() - i - 1]);
                }
            } else {
                break;
            }
        }

        if ( (nei.size()) >= 2) {
            double ave = unclump_average (item, nei);

            SPItem *closest = unclump_closest (item, nei);
            SPItem *farest = unclump_farest (item, nei);

            double dist_closest = unclump_dist (closest, item);
            double dist_farest = unclump_dist (farest, item);

            //g_print ("NEI %d for item %s    closest %s at %g  farest %s at %g  ave %g\n", g_slist_length(nei), item->getId(), closest->getId(), dist_closest, farest->getId(), dist_farest, ave);

            if (fabs (ave) < 1e6 && fabs (dist_closest) < 1e6 && fabs (dist_farest) < 1e6) { // otherwise the items are bogus
                // increase these coefficients to make unclumping more aggressive and less stable
                // the pull coefficient is a bit bigger to counteract the long-term expansion trend
                unclump_push (closest, item, 0.3 * (ave - dist_closest));
                unclump_pull (farest, item, 0.35 * (dist_farest - ave));
            }
        }
    }
}
/**
Unclumps the items in \a items, reducing local unevenness in their distribution. Produces an effect
similar to "engraver dots". The only distribution which is unchanged by unclumping is a hexagonal
grid. May be called repeatedly for stronger effect.
 */
void
unclump (GSList *items)
{
    c_cache.clear();
    wh_cache.clear();

    for (GSList *i = items; i != NULL; i = i->next) { //  for each original/clone x:
        SPItem *item = SP_ITEM (i->data);

        GSList *nei = NULL;

        GSList *rest = g_slist_copy (items);
        rest = g_slist_remove (rest, item);

        while (rest != NULL) {
            SPItem *closest = unclump_closest (item, rest);
            if (closest) {
                nei = g_slist_prepend (nei, closest);
                rest = g_slist_remove (rest, closest);
                GSList *new_rest = unclump_remove_behind (item, closest, rest);
                g_slist_free (rest);
                rest = new_rest;
            } else {
                g_slist_free (rest);
                break;
            }
        }

        if (g_slist_length (nei) >= 2) {
            double ave = unclump_average (item, nei);

            SPItem *closest = unclump_closest (item, nei);
            SPItem *farest = unclump_farest (item, nei);

            double dist_closest = unclump_dist (closest, item);
            double dist_farest = unclump_dist (farest, item);

            //g_print ("NEI %d for item %s    closest %s at %g  farest %s at %g  ave %g\n", g_slist_length(nei), item->getId(), closest->getId(), dist_closest, farest->getId(), dist_farest, ave);

            if (fabs (ave) < 1e6 && fabs (dist_closest) < 1e6 && fabs (dist_farest) < 1e6) { // otherwise the items are bogus
                // increase these coefficients to make unclumping more aggressive and less stable
                // the pull coefficient is a bit bigger to counteract the long-term expansion trend
                unclump_push (closest, item, 0.3 * (ave - dist_closest));
                unclump_pull (farest, item, 0.35 * (dist_farest - ave));
            }
        }
    }
}