103 std::vector<Geom::Rect>::iterator it,
104 std::vector<Geom::Rect>::iterator
end,
105 std::vector<Geom::Rect> &vec,
111 std::vector<Geom::Rect>::iterator next_bbox = it;
112 std::vector<Geom::Rect>::iterator _next_bbox = it;
119 while (std::next(next_bbox) !=
end) {
120 auto first_dist = distance_func(source_bbox, *next_bbox);
124 std::vector<Geom::Rect>
result;
125 if (_findSidewaysSnaps(*next_bbox, ++it,
end,
result, first_dist, tol, distance_func, ++level)) {
126 if (
result.size() > max_length) {
129 optimum_start = *next_bbox;
130 max_length =
result.size();
141 if (max_length == 0) {
142 vec.push_back(*_next_bbox);
146 vec.insert(vec.begin(), optimum_start);
153 vec.push_back(source_bbox);
155 if (it ==
end || level > 10)
158 int og_level = level;
159 std::vector<Geom::Rect> best_result;
161 while (next_bbox !=
end) {
164 Geom::Coord next_dist = distance_func(source_bbox, *next_bbox);
166 std::vector<Geom::Rect> temp_result;
171 this_dist = next_dist;
172 if (_findSidewaysSnaps(*next_bbox, ++it,
end, temp_result, this_dist, tol, distance_func, ++level)) {
173 if (temp_result.size() > 0) {
175 best_result = temp_result;
180 }
else if (
compare_double(dist, next_dist, level * DISTRIBUTION_SNAPPING_EPSILON)) {
182 if (_findSidewaysSnaps(*next_bbox, ++it,
end, temp_result, dist, tol, distance_func, ++level)) {
183 if (temp_result.size() > 0) {
184 best_result = temp_result;
190 if (best_result.size() > 10)
196 vec.insert(vec.end(), best_result.begin(), best_result.end());
307 std::vector<SnapCandidatePoint> *unselected_nodes,
311 bool consider_x =
true;
312 bool consider_y =
true;
313 if (!
c.isUndefined() &&
c.isLinear()) {
314 if (
c.getDirection().x() == 0)
332 bool snap_x =
false, snap_y =
false;
337 std::vector<Geom::Rect> vecRight;
338 std::vector<Geom::Rect> vecLeft;
339 if (consider_x && _bboxes_right->size() > 0) {
340 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_right->begin(), _bboxes_right->end(), vecRight, equal_dist, getSnapperTolerance(), &
DistributionSnapper::distRight)) {
341 auto first_dist = distRight(*bbox_to_snap, vecRight.front());
346 Geom::Rect bbox = *bbox_to_snap * translation;
347 vecRight.insert(vecRight.begin(), bbox);
349 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
351 if (_bboxes_left->size() > 0) {
352 first_dist = distLeft(bbox, _bboxes_left->front());
355 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_left->begin(), _bboxes_left->end(), vecLeft, left_dist, getSnapperTolerance(), &
DistributionSnapper::distLeft)) {
357 std::reverse(vecLeft.begin(), vecLeft.end());
358 vecRight.insert(vecRight.begin(), vecLeft.begin(), vecLeft.end());
362 vecRight.insert(vecRight.begin(), vecLeft.front());
367 sx =
SnappedPoint(target, vecRight, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_RIGHT, dist_x, getSnapperTolerance(),
always,
false,
true);
375 if (consider_x && !snap_x && _bboxes_left->size() > 0) {
377 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_left->begin(), _bboxes_left->end(), vecLeft, equal_dist, getSnapperTolerance(), &
DistributionSnapper::distLeft)) {
378 auto first_dist = distLeft(*bbox_to_snap, vecLeft.front());
384 Geom::Rect bbox = *bbox_to_snap * translation;
385 std::reverse(vecLeft.begin(), vecLeft.end());
386 vecLeft.push_back(bbox);
388 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
390 if (_bboxes_right->size() > 0) {
391 first_dist = distRight(bbox, _bboxes_right->front());
394 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_right->begin(), _bboxes_right->end(), vecRight, right_dist, getSnapperTolerance(), &
DistributionSnapper::distRight)) {
396 vecLeft.insert(vecLeft.end(), vecRight.begin(), vecRight.end());
400 vecLeft.push_back(vecRight.front());
405 sx =
SnappedPoint(target, vecLeft, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_LEFT, dist_x, getSnapperTolerance(),
always,
false,
true);
411 if (consider_x && !snap_x && vecRight.size() > 0 && vecLeft.size() > 0) {
412 auto x =
Geom::Point((vecRight.front().min() + vecLeft.front().max()) / 2).
x();
413 offset = abs(x - bbox_to_snap->midpoint().x());
414 if (
offset < getSnapperTolerance()) {
418 Geom::Rect bbox = *bbox_to_snap * translation;
419 std::vector<Geom::Rect> bboxes = {vecLeft.front(), bbox, vecRight.front()};
421 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
423 equal_dist = bbox.
min().x() - vecLeft.front().max().x();
424 sx =
SnappedPoint(target, bboxes, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_X,
offset, getSnapperTolerance(),
always,
false,
true);
432 std::vector<Geom::Rect> vecUp;
433 std::vector<Geom::Rect> vecDown;
434 if (consider_y && _bboxes_up->size() > 0) {
435 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_up->begin(), _bboxes_up->end(), vecUp, equal_dist, getSnapperTolerance(), &
DistributionSnapper::distUp)) {
436 auto first_dist = distUp(*bbox_to_snap, vecUp.front());
442 Geom::Rect bbox = *bbox_to_snap * translation;
443 std::reverse(vecUp.begin(), vecUp.end());
444 vecUp.push_back(bbox);
446 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
448 if (_bboxes_down->size() > 0) {
449 first_dist = distDown(bbox, _bboxes_down->front());
452 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_down->begin(), _bboxes_down->end(), vecDown, down_dist,
454 if (abs(down_dist - equal_dist) < 1e-4) {
455 vecUp.insert(vecUp.end(), vecDown.begin(), vecDown.end());
458 }
else if (abs(first_dist - equal_dist) < 1e-4) {
459 vecUp.insert(vecUp.end(), vecDown.front());
464 sy =
SnappedPoint(target, vecUp, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_UP, dist_y, getSnapperTolerance(),
always,
false,
true);
472 if (consider_y && !snap_y && _bboxes_down->size() > 0) {
474 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_down->begin(), _bboxes_down->end(), vecDown, equal_dist, getSnapperTolerance(), &
DistributionSnapper::distDown)) {
475 auto first_dist = distDown(*bbox_to_snap, vecDown.front());
481 Geom::Rect bbox = *bbox_to_snap * translation;
482 vecDown.insert(vecDown.begin(), bbox);
484 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
486 if (_bboxes_up->size() > 0) {
487 first_dist = distUp(bbox, _bboxes_up->front());
491 if (_findSidewaysSnaps(*bbox_to_snap, _bboxes_up->begin(), _bboxes_up->end(), vecUp, up_dist, getSnapperTolerance(), &
DistributionSnapper::distUp)) {
493 std::reverse(vecUp.begin(), vecUp.end());
494 vecDown.insert(vecDown.begin(), vecUp.begin(), vecUp.end());
497 vecDown.insert(vecDown.begin(), vecUp.front());
502 sy =
SnappedPoint(target, vecDown, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_DOWN, dist_y, getSnapperTolerance(),
always,
false,
true);
508 if (consider_y && !snap_y && vecUp.size() > 0 && vecDown.size() > 0) {
509 auto y =
Geom::Point((vecUp.front().max() + vecDown.front().min()) / 2).
y();
510 offset = abs(y - bbox_to_snap->midpoint().y());
511 if (consider_y &&
offset < getSnapperTolerance()) {
515 Geom::Rect bbox = *bbox_to_snap * translation;
516 std::vector<Geom::Rect> bboxes = {vecUp.front(), bbox, vecDown.front()};
518 _correctSelectionBBox(target, p.
getPoint(), *bbox_to_snap);
520 equal_dist = bbox.
min().y() - vecUp.front().max().y();
521 sy =
SnappedPoint(target, bboxes, bbox, equal_dist, p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_Y,
offset, getSnapperTolerance(),
always,
false,
true);
526 if (snap_x && snap_y) {
529 Geom::Rect bbox = *bbox_to_snap * translation;
530 std::vector<Geom::Rect> bboxes_x = sx.
getBBoxes();
531 std::vector<Geom::Rect> bboxes_y = sy.
getBBoxes();
535 auto si =
SnappedPoint(target, bboxes_x, bboxes_y, bbox, sx.
getDistributionDistance(), sy.
getDistributionDistance(), p.
getSourceType(), p.
getSourceNum(),
SNAPTARGET_DISTRIBUTION_XY,
offset, getSnapperTolerance(),
always,
false,
true);