From 4360fad5042f0ebd04efec11a4416355440ee1e0 Mon Sep 17 00:00:00 2001 From: "yang.yongquan" <3395816735@qq.com> Date: Wed, 29 Mar 2023 18:54:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=BA=BF=E5=AE=BD=E6=AF=94=E4=BE=8B=E8=AE=A1=E7=AE=97=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Renderer/Painting/CubicBezier.cpp | 4 + .../src/Renderer/Painting/CubicBezier.h | 1 + .../src/Renderer/Painting/Line.h | 1 + .../src/Renderer/Painting/LineTree.cpp | 88 +++++++++---------- .../src/Renderer/Painting/LineTree.h | 1 + .../src/Renderer/Painting/StraightLine.cpp | 4 + .../src/Renderer/Painting/StraightLine.h | 1 + 7 files changed, 54 insertions(+), 46 deletions(-) diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp index 442a6d2..37fcc32 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp @@ -83,6 +83,10 @@ void CubicBezier::splitBezierCubic(double t, vector& res) { setRate({ ratePoint, rate.second }); } +double CubicBezier::getLength() { + return getIntegralByT(1); +} + void CubicBezier::monotonization(vector & res) { transformToCubic(); vector breakPointsT; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h index e479f67..c0d75d8 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h @@ -15,6 +15,7 @@ namespace Renderer public: virtual double findTByValue(double value, bool isY); virtual void monotonization(std::vector & res); + virtual double getLength(); virtual double getLineValueByT(double t, bool isY); virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY); virtual double getMinDistanceFromPoint(Point p); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h index 2198f8c..9251071 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h @@ -69,6 +69,7 @@ namespace Renderer virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY) = 0; virtual double getMinDistanceFromPoint(Point p) = 0; bool judgeOneSideIntersectionWithWidth(double xy, double l, double r, bool isY, double width, int type); + virtual double getLength() = 0; virtual double findTByValue(double value, bool isY) = 0; double getIntegralByT(double t); bool judgeIntersectionWithWidth(QVector4D bound, double width, int type); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp index 026caea..490adc2 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp @@ -72,55 +72,32 @@ bool LineTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const { void LineTree::monotonization(vector& inLines, vector>& outLines) { bool isOffset = false; - 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++; + for (PointVector& l : inLines) { + std::shared_ptr nowLine; + switch (l.size()) { + case 2: { + nowLine = make_shared(l); + 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); + case 4: nowLine = make_shared(l); break; + default: break; } - //单调化并求比例 - 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); + // 防止在同一直线与 X 轴平行上 + if (isOffset) { + nowLine->upwardOffsetForY(true, 1e-5); } - tmpLines.clear(); - i = endIndex; + isOffset = false; + if (nowLine->direction(true) == 0) { + nowLine->upwardOffsetForY(false, 1e-5); + isOffset = true; + } + nowLine->monotonization(outLines); + outLines.push_back(nowLine); } // 防止在首尾直线在与 X 轴平行上 int siz = outLines.size(); - if (!(outLines[0]->getBegin() == outLines[siz - 1]->getEnd())) + if (!(outLines[0]->getBegin() == outLines[siz - 1]->getEnd())) return; if (isOffset) { outLines[0]->upwardOffsetForY(true, 1e-5); @@ -131,13 +108,31 @@ void LineTree::monotonization(vector& inLines, vector >& lines) { + // 计算线的正确比例 + for (int i = 0; i < lines.size(); i++) { + int endIndex = i; + double totalLength = lines[i]->getLength(); + while (endIndex + 1 < lines.size() && lines[endIndex]->getEnd() == lines[endIndex + 1]->getBegin()) { + totalLength += lines[++endIndex]->getLength(); + } + double prefixLength = 0; + for (int j = i; j <= endIndex; j++) { + double nowLineLength = lines[j]->getLength(); + lines[j]->setRate({ prefixLength / totalLength, (prefixLength + nowLineLength) / totalLength }); + prefixLength += nowLineLength; + } + i = endIndex; + } +} + void LineTree::simplifyLineVector() { - bool canPut = false; + bool canPut = false; GLuint index = 0; numLine = allLines.size(); for (auto& nowLine : allLines) { PointVector pointVector = nowLine->toPointVector(); - canPut = false; + canPut = false; index = 0; for (Point& p : pointVector) { int pointIndex = getPointIndex(p); @@ -165,8 +160,8 @@ bool LineTree::handleShortCutNode(LineTreeNode& fa, LineTreeNode& nowTreeNode, d nowTreeNode.lineSet.push_back(lineIndex); } } - if (nowTreeNode.lineSet.size() <= requiredLineMin - || (nowTreeNode.bound.z()-nowTreeNode.bound.x())*sqrt(2) <= lineWidth) { + if (nowTreeNode.lineSet.size() <= requiredLineMin + || (nowTreeNode.bound.z() - nowTreeNode.bound.x()) * sqrt(2) <= lineWidth) { if (nowTreeNode.lineSet.empty()) return false; restOfTreeNodes.push_back(nowTreeNode); @@ -263,6 +258,7 @@ void LineTree::buildLineTree(std::vector& lineSet, double width, in lineWidth = width; lineType = type; monotonization(lineSet, allLines); + countLinesRate(allLines); spliteToLineTree(); simplifyLineVector(); } diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h index 09fd26f..820665f 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h @@ -48,6 +48,7 @@ namespace Renderer { : requiredLineMin(lineMin), numLine(0), numPoint(0) {} void buildLineTree(std::vector& lineSet, double width, int type = 0); static void monotonization(std::vector& inL, std::vector>& outL); + static void countLinesRate(std::vector >& lines); std::vector getPointLineAndBvhTree(std::vector& pointSet, std::vector& lineSet); }; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp index 101b5f8..d083fb7 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp @@ -52,6 +52,10 @@ int StraightLine::judgeOneSideIntersection(double xy, double l, double r, bool i return 0; } +double StraightLine::getLength() { + return sqrt((vX[1] - vX[0]) * (vX[1] - vX[0]) + (vY[1] - vY[0]) * (vY[1] - vY[0])); +} + double StraightLine::getMinDistanceFromPoint(Point p) { Point se = { vX[1] - vX[0], vY[1] - vY[0] }; Point dd = { p.x - vX[0], p.y - vY[0] }; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h index 73625c0..e902c87 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h @@ -10,6 +10,7 @@ namespace Renderer virtual void monotonization(std::vector & res) {}; virtual double findTByValue(double value, bool isY); virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY); + virtual double getLength(); virtual double getMinDistanceFromPoint(Point p); virtual double ValueOfFunctionS(double t); };