diff --git a/ArchitectureColoredPainting/Line.cpp b/ArchitectureColoredPainting/Line.cpp index 2585b49..427b158 100644 --- a/ArchitectureColoredPainting/Line.cpp +++ b/ArchitectureColoredPainting/Line.cpp @@ -12,7 +12,7 @@ int Line::size() { return siz; } -vector Line::toVectorPoint() const { +vector Line::toPointVector() const { vector vL; for (int i = 0; i < siz; i++) { vL.push_back({vX[i], vY[i]}); diff --git a/ArchitectureColoredPainting/Line.h b/ArchitectureColoredPainting/Line.h index c1e259d..61e20e3 100644 --- a/ArchitectureColoredPainting/Line.h +++ b/ArchitectureColoredPainting/Line.h @@ -54,7 +54,7 @@ public: bool isLineContained(QVector4D bound); point operator[](int index) const; point getPointByIndex(int index) const; - vector toVectorPoint() const; + vector toPointVector() const; void setPointByIndex(int index, point now); void push_back(point now); virtual ~Line() {} diff --git a/ArchitectureColoredPainting/ShortCutTree.cpp b/ArchitectureColoredPainting/ShortCutTree.cpp index 84ee8fd..755d8ad 100644 --- a/ArchitectureColoredPainting/ShortCutTree.cpp +++ b/ArchitectureColoredPainting/ShortCutTree.cpp @@ -1,27 +1,27 @@ #include "ShortCutTree.h" void ShortCutTree::init() { - outTree.clear(); + restOfTreeNodes.clear(); allLine.clear(); pointMap.clear(); - lineIndexSet.clear(); + lineIndexs.clear(); numLine = numPoint = 0; } -int ShortCutTree::getPointIndex(point now) { - auto iter = pointMap.find(now); +int ShortCutTree::getPointIndex(point nowPoint) { + auto iter = pointMap.find(nowPoint); if (iter != pointMap.end()) { return iter->second; } else { int res = numPoint; - pointMap.insert({ now, numPoint }); + pointMap.insert({ nowPoint, numPoint }); ++numPoint; return res; } } -bool ShortCutTree::isLineEqual(LineIndex& a, LineIndex& b) const { +bool ShortCutTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const { if (a.size() != b.size()) return false; for (int i = 0; i < a.size(); i++) @@ -30,79 +30,79 @@ bool ShortCutTree::isLineEqual(LineIndex& a, LineIndex& b) const { return true; } -void ShortCutTree::monotonization(vector& inL, vector& outL) { - for (vLine &l: inL) { - LinePtr now; +void ShortCutTree::monotonization(vector& inL, vector& outL) { + for (PointVector&l: inL) { + LinePtr nowLine; switch(l.size()) { - case 2: now.reset(new StraightLine(l)); break; - case 3: case 4: now.reset(new CubicBezier(l)); break; + case 2: nowLine.reset(new StraightLine(l)); break; + case 3: case 4: nowLine.reset(new CubicBezier(l)); break; default: break; } - now->monotonization(outL); - outL.push_back(now); + nowLine->monotonization(outL); + outL.push_back(nowLine); } } -void ShortCutTree::generateShortCutSegement(ShortCutNode& now) { - point p; +void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) { + point p = {0, 0}; vector v; - for (int &index : now.lineSet) { - int type = allLine[index]->judgeBoundIntersection(now.bound.z(), now.bound.y(), now.bound.w(), false), be, en; + for (int & lineIndex : nowTreeNode.lineSet) { + int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), be, en; if (type >= 2) { v.push_back(numLine); if (type == 2) { - p = allLine[index]->getEnd(); + p = allLine[lineIndex]->getEnd(); } if (type == 3) { - p = allLine[index]->getBegin(); + p = allLine[lineIndex]->getBegin(); } - be = getPointIndex({ p.x, now.bound.w() }); + be = getPointIndex({ p.x, nowTreeNode.bound.w() }); en = getPointIndex(p); - lineIndexSet.push_back(be); - lineIndexSet.push_back(be); - lineIndexSet.push_back(en); - lineIndexSet.push_back(en); + lineIndexs.push_back(be); + lineIndexs.push_back(be); + lineIndexs.push_back(en); + lineIndexs.push_back(en); numLine++; } } - if (now.windingIncrement != 0) { + if (nowTreeNode.windingIncrement != 0) { v.push_back(numLine); - int be = getPointIndex({now.bound.z(), now.bound.y()}); - int en = getPointIndex({ now.bound.z(), now.bound.w() }); - lineIndexSet.push_back(be); - lineIndexSet.push_back(be); - lineIndexSet.push_back(en); - lineIndexSet.push_back(en); + int be = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.y()}); + int en = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.w() }); + lineIndexs.push_back(be); + lineIndexs.push_back(be); + lineIndexs.push_back(en); + lineIndexs.push_back(en); numLine++; } - for (int& index : v) { - now.lineSet.push_back(index); + for (int& lineIndex : v) { + nowTreeNode.lineSet.push_back(lineIndex); } } -bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float yValue, vector& v, int& sumIncrement) { - now.windingIncrement = sumIncrement; - for (int &index : fa.lineSet) { - int type = allLine[index]->judgeBoundIntersection(yValue, now.bound.x(), now.bound.z(), true); +bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector& v, int& sumIncrement) { + nowTreeNode.windingIncrement = sumIncrement; + for (int & lineIndex : fa.lineSet) { + int type = allLine[lineIndex]->judgeBoundIntersection(yValue, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true); if (type == 2) sumIncrement++; if (type == 3) sumIncrement--; - if (allLine[index]->judgeIntersection(now.bound)) { - now.lineSet.push_back(index); + if (allLine[lineIndex]->judgeIntersection(nowTreeNode.bound)) { + nowTreeNode.lineSet.push_back(lineIndex); } } - if (now.lineSet.size() <= RequiredLineMin) { - if (now.lineSet.empty() && now.windingIncrement == 0) + if (nowTreeNode.lineSet.size() <= RequiredLineMin) { + if (nowTreeNode.lineSet.empty() && nowTreeNode.windingIncrement == 0) return false; - outTree.push_back(now); - now.divided = false; - v.push_back(now); + restOfTreeNodes.push_back(nowTreeNode); + nowTreeNode.divided = false; + v.push_back(nowTreeNode); return false; } else { - v.push_back(now); + v.push_back(nowTreeNode); return true; } @@ -110,17 +110,17 @@ bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float void ShortCutTree::simplifyLineVector() { numLine = allLine.size(); - for (auto& l : allLine) { - vLine vl = l->toVectorPoint(); - for (point& p : vl) { - int index = getPointIndex(p); - lineIndexSet.push_back(index); - if (vl.size() == 2) - lineIndexSet.push_back(index); + for (auto& nowLine : allLine) { + PointVector pointVector = nowLine->toPointVector(); + for (point& p : pointVector) { + int pointIndex = getPointIndex(p); + lineIndexs.push_back(pointIndex); + if (pointVector.size() == 2) + lineIndexs.push_back(pointIndex); } } - for (auto& now : outTree) { - generateShortCutSegement(now); + for (auto& nowTreeNode : restOfTreeNodes) { + generateShortCutsegmentement(nowTreeNode); } } @@ -134,16 +134,16 @@ void ShortCutTree::spliteToShortCutTree() { } Q.push(root); lineBound.push({ -1, 1 }); - vector v, vn; + vector tmpTreeNodes, generatedTreeNodes; while (!lineBound.empty()) { // 取出一行的所有可行方格 - auto seg = lineBound.front(); - float yMid = (seg.first + seg.second) / 2; + auto segment = lineBound.front(); + float yMid = (segment.first + segment.second) / 2; lineBound.pop(); while (!Q.empty()) { - auto now = Q.front(); - if (now.bound.y() <= seg.first && seg.second <= now.bound.w()) { - v.push_back(now); + auto nowTreeNode = Q.front(); + if (nowTreeNode.bound.y() <= segment.first && segment.second <= nowTreeNode.bound.w()) { + tmpTreeNodes.push_back(nowTreeNode); Q.pop(); } else { @@ -152,99 +152,99 @@ void ShortCutTree::spliteToShortCutTree() { } int sumIncrement = 0; bool isDivided = false; - vn.clear(); + generatedTreeNodes.clear(); // 上部分; - for (auto& now : v) { - if (!now.divided) { - for (int& index : now.lineSet) { - int type = allLine[index]->judgeBoundIntersection(yMid, now.bound.x(), now.bound.z(), true); + for (auto& nowTreeNode : tmpTreeNodes) { + if (!nowTreeNode.divided) { + for (int& lineIndex : nowTreeNode.lineSet) { + int type = allLine[lineIndex]->judgeBoundIntersection(yMid, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true); if (type == 2) sumIncrement++; if (type == 3) sumIncrement--; } - vn.push_back(now); + generatedTreeNodes.push_back(nowTreeNode); } else { - ShortCutNode nw, ne; - float xMid = (now.bound.x() + now.bound.z()) / 2; - ne.bound = QVector4D(xMid, yMid, now.bound.z(), now.bound.w()); - isDivided |= handleShortCutNode(now, ne, yMid, vn, sumIncrement); - nw.bound = QVector4D(now.bound.x(), yMid, xMid, now.bound.w()); - isDivided |= handleShortCutNode(now, nw, yMid, vn, sumIncrement); + ShortCutNode nwTreeNode, neTreeNode; + float xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2; + neTreeNode.bound = QVector4D(xMid, yMid, nowTreeNode.bound.z(), nowTreeNode.bound.w()); + isDivided |= handleShortCutNode(nowTreeNode, neTreeNode, yMid, generatedTreeNodes, sumIncrement); + nwTreeNode.bound = QVector4D(nowTreeNode.bound.x(), yMid, xMid, nowTreeNode.bound.w()); + isDivided |= handleShortCutNode(nowTreeNode, nwTreeNode, yMid, generatedTreeNodes, sumIncrement); } } if (isDivided) { - lineBound.push({yMid, seg.second}); - for (auto& now : vn) { - Q.push(now); + lineBound.push({yMid, segment.second}); + for (auto& nowTreeNode : generatedTreeNodes) { + Q.push(nowTreeNode); } } // 下部分 - vn.clear(); + generatedTreeNodes.clear(); sumIncrement = 0; isDivided = false; - for (auto& now : v) { - if (!now.divided) { - sumIncrement += now.windingIncrement; - vn.push_back(now); + for (auto& nowTreeNode : tmpTreeNodes) { + if (!nowTreeNode.divided) { + sumIncrement += nowTreeNode.windingIncrement; + generatedTreeNodes.push_back(nowTreeNode); } else { - ShortCutNode se, sw; - float xMid = (now.bound.x() + now.bound.z()) / 2; - yMid = (now.bound.y() + now.bound.w()) / 2; - se.bound = QVector4D(xMid, now.bound.y(), now.bound.z(), yMid); - isDivided |= handleShortCutNode(now, se, seg.first, vn, sumIncrement); - sw.bound = QVector4D(now.bound.x(), now.bound.y(), xMid, yMid); - isDivided |= handleShortCutNode(now, sw, seg.first, vn, sumIncrement); + ShortCutNode seTreeNode, swTreeNode; + float xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2; + yMid = (nowTreeNode.bound.y() + nowTreeNode.bound.w()) / 2; + seTreeNode.bound = QVector4D(xMid, nowTreeNode.bound.y(), nowTreeNode.bound.z(), yMid); + isDivided |= handleShortCutNode(nowTreeNode, seTreeNode, segment.first, generatedTreeNodes, sumIncrement); + swTreeNode.bound = QVector4D(nowTreeNode.bound.x(), nowTreeNode.bound.y(), xMid, yMid); + isDivided |= handleShortCutNode(nowTreeNode, swTreeNode, segment.first, generatedTreeNodes, sumIncrement); } } if (isDivided) { - lineBound.push({seg.first, yMid}); - for (auto& now : vn) { - Q.push(now); + lineBound.push({segment.first, yMid}); + for (auto& nowTreeNode : generatedTreeNodes) { + Q.push(nowTreeNode); } } } } -void ShortCutTree::buildShortCutTree(vector& lineSet) { +void ShortCutTree::buildShortCutTree(vector& lineSet) { init(); monotonization(lineSet, allLine); spliteToShortCutTree(); simplifyLineVector(); } -vector ShortCutTree::getPointLineAndBvhTree(vector& pointSet, vector& lineSet) { - vector > vp; vp.clear(); - for (auto& now : pointMap) { - vp.push_back({ now.second , now.first}); +vector ShortCutTree::getPointLineAndBvhTree(vector& resPoints, vector& resLines) { + vector > tmpPoints; tmpPoints.clear(); + for (auto& mapIter : pointMap) { + tmpPoints.push_back({ mapIter.second , mapIter.first}); } - sort(vp.begin(), vp.end()); - for (auto& now : vp) { - pointSet.push_back(now.second.x); - pointSet.push_back(now.second.y); - now.second.show(); + sort(tmpPoints.begin(), tmpPoints.end()); + for (auto& vectorIter : tmpPoints) { + resPoints.push_back(vectorIter.second.x); + resPoints.push_back(vectorIter.second.y); + vectorIter.second.show(); std::cout << '\n'; } - for (auto& now : lineIndexSet) { - lineSet.push_back(now); - std::cout << now << ' '; + for (auto& nowLineIndex : lineIndexs) { + resLines.push_back(nowLineIndex); + std::cout << nowLineIndex << ' '; } std::cout << '\n'; - vector v; - for (auto& now : outTree) { + vector resBvhTreeData; + for (auto& nowTreeNode : restOfTreeNodes) { BvhTreeData oneData; - oneData.leftSon = lineSet.size(); - oneData.bound = now.bound; - std::cout << now.lineSet.size() << ' '; - lineSet.push_back(now.lineSet.size()); - for (auto& index : now.lineSet) { - lineSet.push_back(index); - std::cout << index << ' '; + oneData.leftSon = resLines.size(); + oneData.bound = nowTreeNode.bound; + std::cout << nowTreeNode.lineSet.size() << ' '; + resLines.push_back(nowTreeNode.lineSet.size()); + for (auto& lineIndex : nowTreeNode.lineSet) { + resLines.push_back(lineIndex); + std::cout << lineIndex << ' '; } std::cout << '\n'; - v.push_back(oneData); + resBvhTreeData.push_back(oneData); } - return v; + return resBvhTreeData; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/ShortCutTree.h b/ArchitectureColoredPainting/ShortCutTree.h index 3f92381..6ee81c9 100644 --- a/ArchitectureColoredPainting/ShortCutTree.h +++ b/ArchitectureColoredPainting/ShortCutTree.h @@ -9,7 +9,7 @@ using std::map; using std::for_each; struct ShortCutNode { - typedef vector vLine; + typedef vector vectorPoint; int windingIncrement; bool divided; /* type 代表进入广度优先搜索队列的节点种类: @@ -27,21 +27,21 @@ struct ShortCutNode { }; class ShortCutTree { - typedef vector vLine; - typedef vector LineIndex; + typedef vector PointVector; + typedef vector PointIndexVector; private: - vector outTree; + vector restOfTreeNodes; vector allLine; int RequiredLineMin, numPoint, numLine; map pointMap; - vector lineIndexSet; + vector lineIndexs; - int getPointIndex(point now); - void generateShortCutSegement(ShortCutNode& now); - bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float yValue, vector& v, int& sumIncrement); + int getPointIndex(point nowPoint); + void generateShortCutsegmentement(ShortCutNode& nowTreeNode); + bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector& v, int& sumIncrement); void spliteToShortCutTree(); - static void monotonization(vector& inL, vector &outL); - bool isLineEqual(LineIndex& a, LineIndex& b) const; + static void monotonization(vector& inL, vector &outL); + bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const; void simplifyLineVector(); public: void init(); @@ -49,7 +49,7 @@ public: ShortCutTree(int lineMin = 3) :RequiredLineMin(lineMin), numPoint(0), numLine(0) {} // 传入一个vector > 作为所有输入的线 - void buildShortCutTree(vector& lineSet); + void buildShortCutTree(vector& lineSet); // 获得点集合和线集合 返回输入BvhTree的数据集合 vector getPointLineAndBvhTree(vector &pointSet, vector &lineSet); ~ShortCutTree() {}