diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp index db84c3c..026caea 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp @@ -8,6 +8,7 @@ using std::set; using std::pair; using std::vector; using std::queue; +using std::make_shared; void LineTree::init() { restOfTreeNodes.clear(); @@ -71,28 +72,51 @@ bool LineTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const { void LineTree::monotonization(vector& inLines, vector>& outLines) { bool isOffset = false; - for (PointVector& l : inLines) { - std::shared_ptr nowLine; - switch (l.size()) { - case 2: { - nowLine.reset(new StraightLine(l)); - break; + vector > tmpLines; + tmpLines.clear(); + for (int i = 0; i < inLines.size(); i++) { + int endIndex = i; + double totalLength = 0; + while (endIndex < inLines.size() && *inLines[endIndex].rbegin() == *inLines[endIndex + 1].begin()) { + endIndex++; } - case 3: case 4: nowLine.reset(new CubicBezier(l)); break; - default: break; + // 计算总长度 + for (int j = i; j <= endIndex; j++) { + PointVector& l = inLines[j]; + std::shared_ptr nowLine; + switch (l.size()) { + case 2: { + nowLine = make_shared(l); + break; + } + case 4: nowLine = make_shared(l); break; + default: break; + } + totalLength += nowLine->getIntegralByT(1); + tmpLines.push_back(nowLine); } - // 防止在同一直线与 X 轴平行上 - if (isOffset) { - nowLine->upwardOffsetForY(true, 1e-5); + //单调化并求比例 + double prefixLength = 0; + for (auto nowLine : tmpLines) { + // 防止在同一直线与 X 轴平行上 + double nowLineLength = nowLine->getIntegralByT(1); + nowLine->setRate({ prefixLength / totalLength, (prefixLength + nowLineLength) / totalLength }); + prefixLength += nowLineLength; + + if (isOffset) { + nowLine->upwardOffsetForY(true, 1e-5); + } + isOffset = false; + if (nowLine->direction(true) == 0) { + nowLine->upwardOffsetForY(false, 1e-5); + isOffset = true; + } + nowLine->monotonization(outLines); + outLines.push_back(nowLine); } - isOffset = false; - if (nowLine->direction(true) == 0) { - nowLine->upwardOffsetForY(false, 1e-5); - isOffset = true; - } - nowLine->monotonization(outLines); - outLines.push_back(nowLine); + tmpLines.clear(); + i = endIndex; } // 防止在首尾直线在与 X 轴平行上 int siz = outLines.size();