// 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)); }
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; } }
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, "# "); } }
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; } } }
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); } }
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; }
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); }