From 66d652fa30b728feac1aea15e7bf9327771657a1 Mon Sep 17 00:00:00 2001
From: "yang.yongquan" <3395816735@qq.com>
Date: Sun, 20 Nov 2022 16:46:17 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=AF=B9=E4=BA=8E?=
=?UTF-8?q?=E4=B8=8EX=E8=BD=B4=E5=B9=B3=E8=A1=8C=E7=9B=B4=E7=BA=BF?=
=?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ArchitectureColoredPainting.vcxproj | 4 +
...rchitectureColoredPainting.vcxproj.filters | 10 ++
.../src/Renderer/Painting/Line.cpp | 9 ++
.../src/Renderer/Painting/Line.h | 2 +
.../src/Renderer/Painting/LineTree.cpp | 117 ++++++++++++++++++
.../src/Renderer/Painting/LineTree.h | 51 ++++++++
.../src/Renderer/Painting/ShortCutTree.cpp | 6 +-
.../src/Renderer/Painting/ShortCutTree.h | 9 +-
.../src/Renderer/Painting/StraightLine.h | 1 +
9 files changed, 201 insertions(+), 8 deletions(-)
create mode 100644 ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp
create mode 100644 ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
index 1c52dfd..148dec9 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
@@ -113,6 +113,7 @@
+
@@ -132,6 +133,8 @@
+
+
@@ -153,6 +156,7 @@
+
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
index b73c477..8c848f9 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
@@ -129,6 +129,9 @@
Source Files\Editor
+
+ Source Files\Renderer\Painting
+
@@ -211,6 +214,10 @@
Resource Files
+
+ Source Files
+
+
@@ -272,6 +279,9 @@
Header Files\Editor
+
+ Header Files\Renderer\Painting
+
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp
index b5ed91a..439abd9 100644
--- a/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp
@@ -85,4 +85,13 @@ bool Line::judgeIntersection(QVector4D bound) {
|| judgeBoundIntersection(bound.w(), bound.x(), bound.z(), true)
|| judgeBoundIntersection(bound.x(), bound.y(), bound.w(), false)
|| judgeBoundIntersection(bound.z(), bound.y(), bound.w(), false);
+}
+
+void Line::upwardOffsetForY(bool isStart, double offset) {
+ if (isStart) {
+ vY[0] = vY[0] + offset;
+ }
+ else {
+ vY[siz - 1] = vY[siz - 1] + offset;
+ }
}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h
index 6b0e57e..c0677cb 100644
--- a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h
@@ -46,6 +46,8 @@ namespace Renderer
virtual void monotonization(std::vector & res) = 0;
virtual int judgeBoundIntersection(double xy, double l, double r, bool isY) = 0;
virtual bool judgeIntersection(QVector4D bound);
+ virtual double minDistanceToLine(Point uv);
+ void upwardOffsetForY(bool isStart, double offset);
bool isLineContained(QVector4D bound);
Point operator[](int index) const;
Point getPointByIndex(int index) const;
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp
new file mode 100644
index 0000000..93af7c2
--- /dev/null
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp
@@ -0,0 +1,117 @@
+#include "LineTree.h"
+#include
+
+using namespace Renderer;
+using std::set;
+using std::vector;
+
+void LineTree::init() {
+ restOfTreeNodes.clear();
+ allLine.clear();
+ pointMap.clear();
+ lineIndexs.clear();
+ numLine = numPoint = 0;
+}
+
+void LineTree::setLineWidth(int width) {
+ lineWidth = width;
+}
+
+int LineTree::getPointIndex(Point nowPoint) {
+ auto iter = pointMap.find(nowPoint);
+ if (iter != pointMap.end()) {
+ return iter->second;
+ }
+ else {
+ int res = numPoint;
+ pointMap.insert({ nowPoint, numPoint });
+ ++numPoint;
+ return res;
+ }
+}
+
+bool LineTree::IsBorderValueResonable(double value, set & valueSet) {
+ bool isResonable = true;
+ auto iter = valueSet.lower_bound(value);
+ if (iter != valueSet.end() && fabs(*iter - value) <= eps) {
+ isResonable = false;
+ }
+ if (iter != valueSet.begin()) {
+ iter--;
+ if (fabs(*iter - value) <= eps) {
+ isResonable = false;
+ }
+ }
+ return isResonable;
+}
+
+double LineTree::findBorderValueNotOnLine(double value, set& valueSet) {
+ if (IsBorderValueResonable(value, valueSet)) return value;
+ for (int i = 1; i <= 200; i++) {
+ double changedValue = value + rand() % 50 * 1e-5 + 1e-5;
+ if (IsBorderValueResonable(changedValue, valueSet)) {
+ return changedValue;
+ }
+ }
+ return value;
+}
+
+bool LineTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const {
+ if (a.size() != b.size())
+ return false;
+ for (int i = 0; i < a.size(); i++)
+ if (a[i] != b[i])
+ return false;
+ return true;
+}
+
+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;
+ }
+ case 3: case 4: nowLine.reset(new CubicBezier(l)); break;
+ default: break;
+ }
+
+ // 防止在同一直线与 X 轴平行上
+ 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 轴平行上
+ int siz = outLines.size();
+ if (!(outLines[0]->getBegin() == outLines[siz - 1]->getEnd()))
+ return;
+ if (isOffset) {
+ outLines[0]->upwardOffsetForY(true, 1e-5);
+ }
+ if (outLines[0]->direction(true) == 0) {
+ outLines[0]->upwardOffsetForY(true, 2e-5);
+ outLines[outLines.size() - 1]->upwardOffsetForY(false, 2e-5);
+ }
+}
+
+void LineTree::simplifyLineVector() {
+ numLine = allLine.size();
+ 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h
new file mode 100644
index 0000000..bf839ec
--- /dev/null
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.h
@@ -0,0 +1,51 @@
+#pragma once
+#include "CubicBezier.h"
+#include "StraightLine.h"
+#include "BvhTree.h"
+#include
+#include
+
+namespace Renderer {
+ struct LineTreeNode {
+ int eastGroup;
+ bool divided;
+ /*
+ 0:不需要拆开的节点
+ 1:需要拆分*/
+ QVector4D bound;
+ std::vector lineSet;
+ LineTreeNode() {
+ eastGroup = 0;
+ divided = true;
+ bound = { 0, 0, 0, 0 };
+ lineSet.clear();
+ }
+ ~LineTreeNode() {}
+ };
+ class LineTree {
+ typedef std::vector PointVector;
+ typedef std::vector PointIndexVector;
+ private:
+ std::vector restOfTreeNodes;
+ std::vector> allLine;
+ int requiredLineMin, numPoint, numLine, lineWidth;
+ std::map pointMap;
+ std::vector lineIndexs;
+
+ int getPointIndex(Point nowPoint);
+ void spliteToLineTree();
+ void simplifyLineVector();
+ bool handleShortCutNode(LineTreeNode& fa, LineTreeNode& nowTreeNode, double yValue, std::vector& v);
+ bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
+ static bool IsBorderValueResonable(double value, std::set & valueSet);
+ static double findBorderValueNotOnLine(double value, std::set & valueSet);
+ static void monotonization(std::vector& inL, std::vector>& outL);
+ public:
+ void init();
+ void setLineWidth(int width);
+ LineTree(int lineMin = 3, int width = 0.3)
+ : requiredLineMin(lineMin), lineWidth(width), numLine(0), numPoint(0) {}
+ void buildLineTree(std::vector& lineSet);
+ std::vector getPointLineAndBvhTree(std::vector& pointSet, std::vector& lineSet);
+ };
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp
index 8a1069b..60f4b64 100644
--- a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp
@@ -76,7 +76,7 @@ void ShortCutTree::monotonization(vector& inLines, vector > pointSet;
for (int & lineIndex : nowTreeNode.lineSet) {
@@ -133,7 +133,7 @@ bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNod
}
}
qDebug() << nowTreeNode.lineSet.size() ;
- if (nowTreeNode.lineSet.size() <= RequiredLineMin) {
+ if (nowTreeNode.lineSet.size() <= requiredLineMin) {
if (nowTreeNode.lineSet.empty() && nowTreeNode.windingIncrement == 0)
return false;
restOfTreeNodes.push_back(nowTreeNode);
@@ -160,7 +160,7 @@ void ShortCutTree::simplifyLineVector() {
}
}
for (auto& nowTreeNode : restOfTreeNodes) {
- generateShortCutsegmentement(nowTreeNode);
+ generateShortCutSegment(nowTreeNode);
}
}
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.h b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.h
index cf58e99..527a4c3 100644
--- a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.h
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.h
@@ -9,10 +9,9 @@ namespace Renderer
struct ShortCutNode {
- typedef std::vector vectorPoint;
int windingIncrement, eastGroup;
bool divided;
- /* type 代表进入广度优先搜索队列的节点种类:
+ /*
0:不需要拆开的节点
1:需要拆分*/
QVector4D bound;
@@ -33,12 +32,12 @@ namespace Renderer
private:
std::vector restOfTreeNodes;
std::vector> allLine;
- int RequiredLineMin, numPoint, numLine;
+ int requiredLineMin, numPoint, numLine;
std::map pointMap;
std::vector lineIndexs;
int getPointIndex(Point nowPoint);
- void generateShortCutsegmentement(ShortCutNode& nowTreeNode);
+ void generateShortCutSegment(ShortCutNode& nowTreeNode);
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, double yValue, std::vector& v, int& sumIncrement);
void spliteToShortCutTree();
static void monotonization(std::vector& inL, std::vector>& outL);
@@ -51,7 +50,7 @@ namespace Renderer
void init();
//lineMin最小线数目,即划分终止条件
ShortCutTree(int lineMin = 3)
- :RequiredLineMin(lineMin), numPoint(0), numLine(0) {}
+ :requiredLineMin(lineMin), numPoint(0), numLine(0) {}
// 传入一个vector > 作为所有输入的线
void buildShortCutTree(std::vector& lineSet);
// 获得点集合和线集合 返回输入BvhTree的数据集合
diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h
index 38f6b2c..c5ebeda 100644
--- a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h
+++ b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h
@@ -1,3 +1,4 @@
+#pragma once
#include "Line.h"
namespace Renderer
{