37 QVector<QPolygonF> chains;
38 if (segs.isEmpty() || quantum <= 0.0)
return chains;
40 auto key = [quantum](
const QPointF &pt) -> quint64 {
41 const auto qx = qint32(std::lround(pt.x() / quantum));
42 const auto qy = qint32(std::lround(pt.y() / quantum));
43 return (quint64(quint32(qx)) << 32) | quint64(quint32(qy));
46 QMultiHash<quint64, int> byEndpoint;
47 byEndpoint.reserve(segs.size() * 2);
48 for (
int i = 0;
i < segs.size(); ++
i) {
49 byEndpoint.insert(
key(segs[
i].p1()),
i);
50 byEndpoint.insert(
key(segs[
i].p2()),
i);
53 QVector<bool> used(segs.size(),
false);
55 auto takeNext = [&](
const QPointF &
tip, QPointF &nextPt) ->
bool {
56 const auto range = byEndpoint.equal_range(
key(
tip));
57 for (
auto it = range.first; it != range.second; ++it) {
58 const int j = it.value();
59 if (used[j])
continue;
62 const QLineF &
s = segs[j];
69 for (
int i = 0;
i < segs.size(); ++
i) {
70 if (used[
i])
continue;
73 poly << segs[
i].p1() << segs[
i].p2();
76 while (takeNext(poly.last(), next)) poly.append(next);
77 while (takeNext(poly.first(), next)) poly.prepend(next);
78 chains.append(std::move(poly));