初步解决了线在方格边界上的特殊情况
parent
656fa704a7
commit
e279007d88
|
@ -22,6 +22,32 @@ int ShortCutTree::getPointIndex(Point nowPoint) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ShortCutTree::IsBorderValueResonable(double value, set <double>& 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 ShortCutTree::findBorderValueNotOnLine(double value, set<double>& 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 ShortCutTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const {
|
||||
if (a.size() != b.size())
|
||||
return false;
|
||||
|
@ -31,16 +57,16 @@ bool ShortCutTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ShortCutTree::monotonization(vector<PointVector>& inL, vector<LinePtr>& outL) {
|
||||
for (PointVector&l: inL) {
|
||||
void ShortCutTree::monotonization(vector<PointVector>& inLines, vector<LinePtr>& outLines) {
|
||||
for (PointVector&l: inLines) {
|
||||
LinePtr nowLine;
|
||||
switch(l.size()) {
|
||||
case 2: nowLine.reset(new StraightLine(l)); break;
|
||||
case 3: case 4: nowLine.reset(new CubicBezier(l)); break;
|
||||
default: break;
|
||||
}
|
||||
nowLine->monotonization(outL);
|
||||
outL.push_back(nowLine);
|
||||
nowLine->monotonization(outLines);
|
||||
outLines.push_back(nowLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +159,15 @@ void ShortCutTree::simplifyLineVector() {
|
|||
}
|
||||
|
||||
void ShortCutTree::spliteToShortCutTree() {
|
||||
// 防止直线的点落在边界上
|
||||
set<double> xLineSet, yLineSet;
|
||||
for (int i = 0; i < allLine.size(); i++) {
|
||||
xLineSet.insert(allLine[i]->getBegin().x);
|
||||
xLineSet.insert(allLine[i]->getEnd().x);
|
||||
yLineSet.insert(allLine[i]->getBegin().y);
|
||||
yLineSet.insert(allLine[i]->getEnd().y);
|
||||
}
|
||||
// 生成方格
|
||||
queue<ShortCutNode> Q;
|
||||
queue<pair<double, double> > lineBound;
|
||||
ShortCutNode root;
|
||||
|
@ -144,13 +179,15 @@ void ShortCutTree::spliteToShortCutTree() {
|
|||
root.eastGroup = eastGroupSize;
|
||||
Q.push(root);
|
||||
lineBound.push({ -1, 1 });
|
||||
vector<ShortCutNode> tmpTreeNodes, generatedTreeNodes;
|
||||
vector<ShortCutNode> tmpTreeNodes, upperTreeNodes, lowerTreeNodes;
|
||||
int sumUpperIncrement = 0, sumLowerIncrement = 0;
|
||||
bool isUpperDivided = false, isLowerDivided = false;
|
||||
while (!lineBound.empty()) {
|
||||
// 取出一行的所有可行方格
|
||||
++nowEastGroup;
|
||||
auto segment = lineBound.front();
|
||||
auto segment = lineBound.front(); lineBound.pop();
|
||||
double yMid = (segment.first + segment.second) / 2;
|
||||
lineBound.pop();
|
||||
yMid = findBorderValueNotOnLine(yMid, yLineSet);
|
||||
while (!Q.empty()) {
|
||||
auto nowTreeNode = Q.front();
|
||||
if (nowTreeNode.eastGroup == nowEastGroup) {
|
||||
|
@ -161,66 +198,57 @@ void ShortCutTree::spliteToShortCutTree() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
int sumIncrement = 0;
|
||||
bool isDivided = false;
|
||||
generatedTreeNodes.clear();
|
||||
// Éϲ¿·Ö;
|
||||
sumUpperIncrement = 0; sumLowerIncrement = 0;
|
||||
isUpperDivided = false; isLowerDivided = false;
|
||||
upperTreeNodes.clear(); lowerTreeNodes.clear();
|
||||
// 处理方格;
|
||||
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++;
|
||||
sumUpperIncrement++;
|
||||
if (type == 3)
|
||||
sumIncrement--;
|
||||
sumUpperIncrement--;
|
||||
// 下半部分
|
||||
type = allLine[lineIndex]->judgeBoundIntersection(segment.first, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
if (type == 2)
|
||||
sumLowerIncrement++;
|
||||
if (type == 3)
|
||||
sumLowerIncrement--;
|
||||
}
|
||||
generatedTreeNodes.push_back(nowTreeNode);
|
||||
upperTreeNodes.push_back(nowTreeNode);
|
||||
lowerTreeNodes.push_back(nowTreeNode);
|
||||
}
|
||||
else {
|
||||
ShortCutNode nwTreeNode, neTreeNode;
|
||||
ShortCutNode nwTreeNode, neTreeNode, seTreeNode, swTreeNode;
|
||||
double xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2;
|
||||
xMid = findBorderValueNotOnLine(xMid, xLineSet);
|
||||
// 上部分
|
||||
neTreeNode.bound = QVector4D(xMid, yMid, nowTreeNode.bound.z(), nowTreeNode.bound.w());
|
||||
isDivided |= handleShortCutNode(nowTreeNode, neTreeNode, yMid, generatedTreeNodes, sumIncrement);
|
||||
isUpperDivided |= handleShortCutNode(nowTreeNode, neTreeNode, yMid, upperTreeNodes, sumUpperIncrement);
|
||||
nwTreeNode.bound = QVector4D(nowTreeNode.bound.x(), yMid, xMid, nowTreeNode.bound.w());
|
||||
isDivided |= handleShortCutNode(nowTreeNode, nwTreeNode, yMid, generatedTreeNodes, sumIncrement);
|
||||
isUpperDivided |= handleShortCutNode(nowTreeNode, nwTreeNode, yMid, upperTreeNodes, sumUpperIncrement);
|
||||
// 下部分
|
||||
seTreeNode.bound = QVector4D(xMid, nowTreeNode.bound.y(), nowTreeNode.bound.z(), yMid);
|
||||
isLowerDivided |= handleShortCutNode(nowTreeNode, seTreeNode, segment.first, lowerTreeNodes, sumLowerIncrement);
|
||||
swTreeNode.bound = QVector4D(nowTreeNode.bound.x(), nowTreeNode.bound.y(), xMid, yMid);
|
||||
isLowerDivided |= handleShortCutNode(nowTreeNode, swTreeNode, segment.first, lowerTreeNodes, sumLowerIncrement);
|
||||
}
|
||||
}
|
||||
if (isDivided) {
|
||||
if (isUpperDivided) {
|
||||
++eastGroupSize;
|
||||
lineBound.push({yMid, segment.second});
|
||||
for (auto nowTreeNode : generatedTreeNodes) {
|
||||
for (auto& nowTreeNode : upperTreeNodes) {
|
||||
nowTreeNode.eastGroup = eastGroupSize;
|
||||
Q.push(nowTreeNode);
|
||||
}
|
||||
}
|
||||
// ϲ¿·Ö
|
||||
generatedTreeNodes.clear();
|
||||
sumIncrement = 0;
|
||||
isDivided = false;
|
||||
for (auto& nowTreeNode : tmpTreeNodes) {
|
||||
if (!nowTreeNode.divided) {
|
||||
for (int& lineIndex : nowTreeNode.lineSet) {
|
||||
int type = allLine[lineIndex]->judgeBoundIntersection(segment.first, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
if (type == 2)
|
||||
sumIncrement++;
|
||||
if (type == 3)
|
||||
sumIncrement--;
|
||||
}
|
||||
generatedTreeNodes.push_back(nowTreeNode);
|
||||
}
|
||||
else {
|
||||
ShortCutNode seTreeNode, swTreeNode;
|
||||
float xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2+1e-5;
|
||||
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) {
|
||||
if (isLowerDivided) {
|
||||
++eastGroupSize;
|
||||
lineBound.push({segment.first, yMid});
|
||||
for (auto nowTreeNode : generatedTreeNodes) {
|
||||
lineBound.push({ segment.first, yMid });
|
||||
for (auto& nowTreeNode : lowerTreeNodes) {
|
||||
nowTreeNode.eastGroup = eastGroupSize;
|
||||
Q.push(nowTreeNode);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ private:
|
|||
static void monotonization(vector<PointVector>& inL, vector<LinePtr> &outL);
|
||||
bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
|
||||
void simplifyLineVector();
|
||||
// 需要测试,随机获得合理的边界
|
||||
static bool IsBorderValueResonable(double value, set <double>& valueSet);
|
||||
static double findBorderValueNotOnLine(double value, set <double>& valueSet);
|
||||
public:
|
||||
void init();
|
||||
//lineMin最小线数目,即划分终止条件
|
||||
|
|
Loading…
Reference in New Issue