进行了简单的代码重构
parent
09f2a32fc6
commit
e849479236
|
@ -12,7 +12,7 @@ int Line::size() {
|
|||
return siz;
|
||||
}
|
||||
|
||||
vector<point> Line::toVectorPoint() const {
|
||||
vector<point> Line::toPointVector() const {
|
||||
vector<point> vL;
|
||||
for (int i = 0; i < siz; i++) {
|
||||
vL.push_back({vX[i], vY[i]});
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
bool isLineContained(QVector4D bound);
|
||||
point operator[](int index) const;
|
||||
point getPointByIndex(int index) const;
|
||||
vector<point> toVectorPoint() const;
|
||||
vector<point> toPointVector() const;
|
||||
void setPointByIndex(int index, point now);
|
||||
void push_back(point now);
|
||||
virtual ~Line() {}
|
||||
|
|
|
@ -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<vLine>& inL, vector<LinePtr>& outL) {
|
||||
for (vLine &l: inL) {
|
||||
LinePtr now;
|
||||
void ShortCutTree::monotonization(vector<PointVector>& inL, vector<LinePtr>& 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<int> 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<ShortCutNode>& 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<ShortCutNode>& 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<ShortCutNode> v, vn;
|
||||
vector<ShortCutNode> 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<vLine>& lineSet) {
|
||||
void ShortCutTree::buildShortCutTree(vector<PointVector>& lineSet) {
|
||||
init();
|
||||
monotonization(lineSet, allLine);
|
||||
spliteToShortCutTree();
|
||||
simplifyLineVector();
|
||||
}
|
||||
|
||||
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& pointSet, vector<GLuint>& lineSet) {
|
||||
vector<pair<GLuint, point> > vp; vp.clear();
|
||||
for (auto& now : pointMap) {
|
||||
vp.push_back({ now.second , now.first});
|
||||
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& resPoints, vector<GLuint>& resLines) {
|
||||
vector<pair<GLuint, point> > 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<BvhTreeData> v;
|
||||
for (auto& now : outTree) {
|
||||
vector<BvhTreeData> 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;
|
||||
}
|
|
@ -9,7 +9,7 @@ using std::map;
|
|||
using std::for_each;
|
||||
|
||||
struct ShortCutNode {
|
||||
typedef vector<point> vLine;
|
||||
typedef vector<point> vectorPoint;
|
||||
int windingIncrement;
|
||||
bool divided;
|
||||
/* type 代表进入广度优先搜索队列的节点种类:
|
||||
|
@ -27,21 +27,21 @@ struct ShortCutNode {
|
|||
};
|
||||
class ShortCutTree
|
||||
{
|
||||
typedef vector<point> vLine;
|
||||
typedef vector<int> LineIndex;
|
||||
typedef vector<point> PointVector;
|
||||
typedef vector<int> PointIndexVector;
|
||||
private:
|
||||
vector<ShortCutNode> outTree;
|
||||
vector<ShortCutNode> restOfTreeNodes;
|
||||
vector<LinePtr> allLine;
|
||||
int RequiredLineMin, numPoint, numLine;
|
||||
map<point, int> pointMap;
|
||||
vector<int> lineIndexSet;
|
||||
vector<int> lineIndexs;
|
||||
|
||||
int getPointIndex(point now);
|
||||
void generateShortCutSegement(ShortCutNode& now);
|
||||
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
|
||||
int getPointIndex(point nowPoint);
|
||||
void generateShortCutsegmentement(ShortCutNode& nowTreeNode);
|
||||
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
|
||||
void spliteToShortCutTree();
|
||||
static void monotonization(vector<vLine>& inL, vector<LinePtr> &outL);
|
||||
bool isLineEqual(LineIndex& a, LineIndex& b) const;
|
||||
static void monotonization(vector<PointVector>& inL, vector<LinePtr> &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<vector<point> > 作为所有输入的线
|
||||
void buildShortCutTree(vector<vLine>& lineSet);
|
||||
void buildShortCutTree(vector<PointVector>& lineSet);
|
||||
// 获得点集合和线集合 返回输入BvhTree的数据集合
|
||||
vector<BvhTreeData> getPointLineAndBvhTree(vector<float> &pointSet, vector<GLuint> &lineSet);
|
||||
~ShortCutTree() {}
|
||||
|
|
Loading…
Reference in New Issue