Example #1
0
// Hover-Hinzufuegung mehrerer Grafikobjekte beim Rahmenziehen (torussicher)
// Nutzt die Ueberlappungsfunktionen, die auch fuer die Vorder-/Hintergrund-
// angelegenheiten wichtig sind.
void Editor::find_check_frame
(GraLi& l, const int x1, const int y1, const int x2, const int y2)
{
    for (GraIt itr = l.begin(); itr != l.end(); ++itr)
     if (get_overlap(*itr, x1, y1, x2, y2, frame_torus_x, frame_torus_y))
     hover.push_back(Selection(&l, itr));
}
Example #2
0
int SkRTree::chooseSubtree(Node* root, Branch* branch) {
    SkASSERT(!root->isLeaf());
    if (1 < root->fLevel) {
        // root's child pointers do not point to leaves, so minimize area increase
        int32_t minAreaIncrease = SK_MaxS32;
        int32_t minArea         = SK_MaxS32;
        int32_t bestSubtree     = -1;
        for (int i = 0; i < root->fNumChildren; ++i) {
            const SkIRect& subtreeBounds = root->child(i)->fBounds;
            int32_t areaIncrease = get_area_increase(subtreeBounds, branch->fBounds);
            // break ties in favor of subtree with smallest area
            if (areaIncrease < minAreaIncrease || (areaIncrease == minAreaIncrease &&
                static_cast<int32_t>(get_area(subtreeBounds)) < minArea)) {
                minAreaIncrease = areaIncrease;
                minArea = get_area(subtreeBounds);
                bestSubtree = i;
            }
        }
        SkASSERT(-1 != bestSubtree);
        return bestSubtree;
    } else if (1 == root->fLevel) {
        // root's child pointers do point to leaves, so minimize overlap increase
        int32_t minOverlapIncrease = SK_MaxS32;
        int32_t minAreaIncrease    = SK_MaxS32;
        int32_t bestSubtree = -1;
        for (int32_t i = 0; i < root->fNumChildren; ++i) {
            const SkIRect& subtreeBounds = root->child(i)->fBounds;
            SkIRect expandedBounds = subtreeBounds;
            join_no_empty_check(branch->fBounds, &expandedBounds);
            int32_t overlap = 0;
            for (int32_t j = 0; j < root->fNumChildren; ++j) {
                if (j == i) continue;
                // Note: this would be more correct if we subtracted the original pre-expanded
                // overlap, but computing overlaps is expensive and omitting it doesn't seem to
                // hurt query performance. See get_overlap_increase()
                overlap += get_overlap(expandedBounds, root->child(j)->fBounds);
            }
            // break ties with lowest area increase
            if (overlap < minOverlapIncrease || (overlap == minOverlapIncrease &&
                static_cast<int32_t>(get_area_increase(branch->fBounds, subtreeBounds)) <
                minAreaIncrease)) {
                minOverlapIncrease = overlap;
                minAreaIncrease = get_area_increase(branch->fBounds, subtreeBounds);
                bestSubtree = i;
            }
        }
        return bestSubtree;
    } else {
        SkASSERT(false);
        return 0;
    }
}
Example #3
0
void
layout_boxes(Layouter *layouter)
{
  log_s(L_Layouter, "init\n");
  u32 passes = 0;
  b32 moved_rect = true;
  while (moved_rect && passes < MAX_PASSES)
  {
    log_s(L_Layouter, ">\n");
    moved_rect = false;

    for (u32 subject_index = 0;
         subject_index < layouter->next_free;
         ++subject_index)
    {
      log_s(L_Layouter, "  ");
      Rectangle *current_subject = layouter->rects + subject_index;

      for (u32 test_index = 0;
           test_index < layouter->next_free;
           ++test_index)
      {
        Rectangle *test = layouter->rects + test_index;

        if (test != current_subject)
        {
          if (overlaps(*current_subject, *test))
          {
            log_s(L_Layouter, "  ");
            moved_rect = true;
            Rectangle overlap = get_overlap(*current_subject, *test);

            r32 h_dist = overlap.end.x - overlap.start.x;
            r32 v_dist = overlap.end.y - overlap.start.y;

            V2 direction = vector_direction_or_1(get_center(*test) - get_center(*current_subject));

            if (h_dist < v_dist)
            {
              *test += (V2){h_dist, 0} * direction.x;
            }
            else
            {
              *test += (V2){0, v_dist} * direction.y;
            }

          }
          else
          {
            log_s(L_Layouter, "# ");
          }
        }
Example #4
0
void Editor::selection_fore_background(const bool fg, const bool total)
{
    if (total) for (SelIt sel=selection.begin(); sel!=selection.end(); ++sel) {
        GraIt itr = fg ? sel->l->begin() : sel->l->end();
        sel->l->insert(itr, *sel->o);
        sel->l->erase(sel->o);
        sel->o = --itr; // das Eingeschobene
        draw_required = true;
    }
    else for (SelIt sel = selection.begin(); sel != selection.end(); ++sel) {
        if (sel->l == &object[Object::TERRAIN]) {
            const int x1 = sel->o->get_x();
            const int y1 = sel->o->get_y();
            const int x2 = sel->o->get_x() + sel->o->get_xl() - 1;
            const int y2 = sel->o->get_y() + sel->o->get_yl() - 1;
            GraIt itr = sel->o;
            if (fg) --itr;
            else    ++itr;
            for (; itr != (fg ? --(sel->l->begin()) : sel->l->end());
                           fg ? -- itr              : ++itr)
             if (get_overlap(*itr, x1, y1, x2, y2, false, false)) {
                // Die Auswahl vor dem Iterator einschieben. Wenn wir allerdings
                // in den Hintergrund stellen: hinter dem Iterator == vor ++itr.
                // ++itr.
                if (!fg) ++itr;
                sel->l->insert(itr, *sel->o);
                sel->l->erase(sel->o);
                sel->o = --itr; // das Eingeschobene
                draw_required = true;
                break;
            }
        }
        // In other lists move back/forth a single place without taking into
        // account overlapping objects
        else {
            GraIt itr = sel->o;
            if (fg) {
                if (itr == sel->l->begin() || sel->l->size() == 1) continue;
                --itr;
            }
            else {
                if (itr == --sel->l->end() || sel->l->size() == 1) continue;
                ++(++itr);
            }
            sel->l->insert(itr, *sel->o);
            sel->l->erase(sel->o);
            sel->o = --itr; // das Eingeschobene
            draw_required = true;
}   }   }
Example #5
0
void ccdfs(int a[], int i, int rs[], int cs[], int ss[], int n)
{
	int j;

	//
	for(j=0; j<n; ++j)
		if(a[j]==0 && get_overlap(rs[i], cs[i], ss[i], rs[j], cs[j], ss[j])>0.75f)
		{
			//
			a[j] = a[i];

			//
			ccdfs(a, j, rs, cs, ss, n);
		}
}
Example #6
0
int SkRTree::distributeChildren(Branch* children) {
    // We have two sides to sort by on each of two axes:
    const static SortSide sorts[2][2] = {
        {&SkIRect::fLeft, &SkIRect::fRight},
        {&SkIRect::fTop, &SkIRect::fBottom}
    };

    // We want to choose an axis to split on, then a distribution along that axis; we'll need
    // three pieces of info: the split axis, the side to sort by on that axis, and the index
    // to split the sorted array on.
    int32_t sortSide = -1;
    int32_t k        = -1;
    int32_t axis     = -1;
    int32_t bestS    = SK_MaxS32;

    // Evaluate each axis, we want the min summed margin-value (s) over all distributions
    for (int i = 0; i < 2; ++i) {
        int32_t minOverlap   = SK_MaxS32;
        int32_t minArea      = SK_MaxS32;
        int32_t axisBestK    = 0;
        int32_t axisBestSide = 0;
        int32_t s = 0;

        // Evaluate each sort
        for (int j = 0; j < 2; ++j) {
            SkTQSort(children, children + fMaxChildren, RectLessThan(sorts[i][j]));

            // Evaluate each split index
            for (int32_t k = 1; k <= fMaxChildren - 2 * fMinChildren + 2; ++k) {
                SkIRect r1 = children[0].fBounds;
                SkIRect r2 = children[fMinChildren + k - 1].fBounds;
                for (int32_t l = 1; l < fMinChildren - 1 + k; ++l) {
                    join_no_empty_check(children[l].fBounds, &r1);
                }
                for (int32_t l = fMinChildren + k; l < fMaxChildren + 1; ++l) {
                    join_no_empty_check(children[l].fBounds, &r2);
                }

                int32_t area = get_area(r1) + get_area(r2);
                int32_t overlap = get_overlap(r1, r2);
                s += get_margin(r1) + get_margin(r2);

                if (overlap < minOverlap || (overlap == minOverlap && area < minArea)) {
                    minOverlap = overlap;
                    minArea = area;
                    axisBestSide = j;
                    axisBestK = k;
                }
            }
        }

        if (s < bestS) {
            bestS = s;
            axis = i;
            sortSide = axisBestSide;
            k = axisBestK;
        }
    }

    // replicate the sort of the winning distribution, (we can skip this if the last
    // sort ended up being best)
    if (!(axis == 1 && sortSide == 1)) {
        SkTQSort(children, children + fMaxChildren, RectLessThan(sorts[axis][sortSide]));
    }

    return fMinChildren - 1 + k;
}
Example #7
0
static inline uint32_t get_overlap_increase(const SkIRect& rect1, const SkIRect& rect2,
                                          SkIRect expandBy) {
    join_no_empty_check(rect1, &expandBy);
    return get_overlap(expandBy, rect2) - get_overlap(rect1, rect2);
}