初步完成了LineTree,待测试
parent
f3b0a3069c
commit
2745e8c47b
|
@ -1,6 +1,8 @@
|
|||
#include "CubicBezier.h"
|
||||
#include "CubicBezierSignedDistance.h"
|
||||
using namespace Renderer;
|
||||
using std::vector;
|
||||
using std::swap;
|
||||
double CubicBezier::getLineValueByT(double t, bool isY) {
|
||||
vector<double> p;
|
||||
if (isY) p = vY;
|
||||
|
@ -101,7 +103,7 @@ double CubicBezier::findTByValue(double value, bool isY) {
|
|||
return l;
|
||||
}
|
||||
|
||||
int CubicBezier::judgeBoundIntersection(double xy, double l, double r, bool isY) {
|
||||
int CubicBezier::judgeOneSideIntersection(double xy, double l, double r, bool isY) {
|
||||
double valueBegin = *vX.begin(), valueEnd = *vX.rbegin();
|
||||
if (isY) {
|
||||
valueBegin = *vY.begin();
|
||||
|
@ -114,4 +116,8 @@ int CubicBezier::judgeBoundIntersection(double xy, double l, double r, bool isY)
|
|||
return 1 + direction(isY);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double CubicBezier::getMinDistanceFromPoint(Point p) {
|
||||
return CubicBezierSignedDistance::cubic_bezier_dis(p, getBegin(), getPointByIndex(1), getPointByIndex(2), getEnd());
|
||||
}
|
|
@ -15,7 +15,8 @@ namespace Renderer
|
|||
virtual double findTByValue(double value, bool isY);
|
||||
virtual void monotonization(std::vector <LinePtr>& res);
|
||||
virtual double getLineValueByT(double t, bool isY);
|
||||
virtual int judgeBoundIntersection(double xy, double l, double r, bool isY);
|
||||
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
||||
virtual double getMinDistanceFromPoint(Point p);
|
||||
void transformToCubic();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ int Line::direction(bool isY) {
|
|||
|
||||
bool Line::judgeIntersection(QVector4D bound) {
|
||||
return isLineContained(bound)
|
||||
|| judgeBoundIntersection(bound.y(), bound.x(), bound.z(), true)
|
||||
|| judgeBoundIntersection(bound.w(), bound.x(), bound.z(), true)
|
||||
|| judgeBoundIntersection(bound.x(), bound.y(), bound.w(), false)
|
||||
|| judgeBoundIntersection(bound.z(), bound.y(), bound.w(), false);
|
||||
|| judgeOneSideIntersection(bound.y(), bound.x(), bound.z(), true)
|
||||
|| judgeOneSideIntersection(bound.w(), bound.x(), bound.z(), true)
|
||||
|| judgeOneSideIntersection(bound.x(), bound.y(), bound.w(), false)
|
||||
|| judgeOneSideIntersection(bound.z(), bound.y(), bound.w(), false);
|
||||
}
|
||||
|
||||
void Line::upwardOffsetForY(bool isStart, double offset) {
|
||||
|
@ -94,4 +94,58 @@ void Line::upwardOffsetForY(bool isStart, double offset) {
|
|||
else {
|
||||
vY[siz - 1] = vY[siz - 1] + offset;
|
||||
}
|
||||
}
|
||||
|
||||
Point Line::getMinDistancePointOnSide(double xy, double l, double r, bool isY) {
|
||||
Point pMid = { xy, l }, pMidr = { xy, r };
|
||||
if (isY) {
|
||||
swap(pMid.x, pMid.y);
|
||||
swap(pMidr.x, pMidr.y);
|
||||
}
|
||||
double mid, midr;
|
||||
while (fabs(r - l) > eps) {
|
||||
mid = (l + r) / 2;
|
||||
midr = (mid + r) / 2;
|
||||
if (isY) {
|
||||
pMid.x = mid;
|
||||
pMidr.x = midr;
|
||||
}
|
||||
else {
|
||||
pMid.y = mid;
|
||||
pMidr.y = midr;
|
||||
}
|
||||
if (getMinDistanceFromPoint(pMid) > getMinDistanceFromPoint(pMidr)) {
|
||||
l = mid;
|
||||
}
|
||||
else {
|
||||
r = midr;
|
||||
}
|
||||
}
|
||||
Point ans = { xy, l };
|
||||
if (isY) swap(ans.x, ans.y);
|
||||
return ans;
|
||||
}
|
||||
|
||||
int Line::getPointSideOfLine(Point p) {
|
||||
// 1 Ϊ×ó²à£¬ 2 ΪÓÒ²à
|
||||
double z = (p.x - vX[0]) * (*vY.rbegin() - vY[0]) - (p.y - vY[0]) * (*vX.rbegin() - vX[0]);
|
||||
if (z == 0) return 0;
|
||||
else if(z>0) return 1;
|
||||
else return 2;
|
||||
}
|
||||
|
||||
bool Line::judgeOneSideIntersectionWithWidth(double xy, double l, double r, bool isY, double width, int type) {
|
||||
Point p = getMinDistancePointOnSide(xy, l, r, isY);
|
||||
if (type && getPointSideOfLine(p) != type) {
|
||||
return false;
|
||||
}
|
||||
return getMinDistanceFromPoint(p) <= width;
|
||||
}
|
||||
|
||||
bool Line::judgeIntersectionWithWidth(QVector4D bound, double width, int type) {
|
||||
return isLineContained(bound)
|
||||
|| judgeOneSideIntersectionWithWidth(bound.y(), bound.x(), bound.z(), true, width, type)
|
||||
|| judgeOneSideIntersectionWithWidth(bound.w(), bound.x(), bound.z(), true, width, type)
|
||||
|| judgeOneSideIntersectionWithWidth(bound.x(), bound.y(), bound.w(), false, width, type)
|
||||
|| judgeOneSideIntersectionWithWidth(bound.z(), bound.y(), bound.w(), false, width, type);
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
@ -24,6 +25,9 @@ namespace Renderer
|
|||
bool operator< (const Point& a) const {
|
||||
return fabs(x - a.x) <= eps ? y < a.y : x < a.x;
|
||||
}
|
||||
operator glm::dvec2() {
|
||||
return glm::dvec2(x, y);
|
||||
}
|
||||
void show() {
|
||||
std::cout << '(' << x << ',' << y << ')' << ' ';
|
||||
}
|
||||
|
@ -45,8 +49,13 @@ namespace Renderer
|
|||
int direction(bool isY);
|
||||
virtual double getLineValueByT(double t, bool isY) = 0;
|
||||
virtual void monotonization(std::vector <LinePtr>& res) = 0;
|
||||
virtual int judgeBoundIntersection(double xy, double l, double r, bool isY) = 0;
|
||||
virtual bool judgeIntersection(QVector4D bound);
|
||||
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);
|
||||
bool judgeIntersectionWithWidth(QVector4D bound, double width, int type);
|
||||
bool judgeIntersection(QVector4D bound);
|
||||
int getPointSideOfLine(Point p);
|
||||
Point getMinDistancePointOnSide(double xy, double l, double r, bool isY);
|
||||
// virtual double minDistanceToLine(Point uv);
|
||||
void upwardOffsetForY(bool isStart, double offset);
|
||||
bool isLineContained(QVector4D bound);
|
||||
|
@ -57,4 +66,5 @@ namespace Renderer
|
|||
void push_back(Point now);
|
||||
virtual ~Line() {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
#include "LineTree.h"
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
using namespace Renderer;
|
||||
using std::set;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using std::queue;
|
||||
|
||||
void LineTree::init() {
|
||||
restOfTreeNodes.clear();
|
||||
allLine.clear();
|
||||
allLines.clear();
|
||||
pointMap.clear();
|
||||
lineIndexs.clear();
|
||||
numLine = numPoint = 0;
|
||||
}
|
||||
|
||||
void LineTree::setLineWidth(int width) {
|
||||
void LineTree::setLineWidth(double width) {
|
||||
lineWidth = width;
|
||||
}
|
||||
|
||||
|
@ -104,8 +108,8 @@ void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_p
|
|||
}
|
||||
|
||||
void LineTree::simplifyLineVector() {
|
||||
numLine = allLine.size();
|
||||
for (auto& nowLine : allLine) {
|
||||
numLine = allLines.size();
|
||||
for (auto& nowLine : allLines) {
|
||||
PointVector pointVector = nowLine->toPointVector();
|
||||
for (Point& p : pointVector) {
|
||||
int pointIndex = getPointIndex(p);
|
||||
|
@ -114,4 +118,148 @@ void LineTree::simplifyLineVector() {
|
|||
lineIndexs.push_back(pointIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LineTree::handleShortCutNode(LineTreeNode& fa, LineTreeNode& nowTreeNode, double yValue, std::vector<LineTreeNode>& v) {
|
||||
for (int& lineIndex : fa.lineSet) {
|
||||
if (allLines[lineIndex]->judgeIntersectionWithWidth(nowTreeNode.bound, lineWidth, lineType)) {
|
||||
nowTreeNode.lineSet.push_back(lineIndex);
|
||||
}
|
||||
}
|
||||
if (nowTreeNode.lineSet.size() <= requiredLineMin) {
|
||||
if (nowTreeNode.lineSet.empty())
|
||||
return false;
|
||||
restOfTreeNodes.push_back(nowTreeNode);
|
||||
nowTreeNode.divided = false;
|
||||
v.push_back(nowTreeNode);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
v.push_back(nowTreeNode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void LineTree::spliteToLineTree() {
|
||||
// 防止直线的点落在边界上
|
||||
set<double> xLineSet, yLineSet;
|
||||
for (int i = 0; i < allLines.size(); i++) {
|
||||
xLineSet.insert(allLines[i]->getBegin().x);
|
||||
xLineSet.insert(allLines[i]->getEnd().x);
|
||||
yLineSet.insert(allLines[i]->getBegin().y);
|
||||
yLineSet.insert(allLines[i]->getEnd().y);
|
||||
}
|
||||
// 生成方格
|
||||
queue<LineTreeNode> Q;
|
||||
queue<pair<double, double> > lineBound;
|
||||
LineTreeNode root;
|
||||
int nowEastGroup = 0, eastGroupSize = 1;
|
||||
root.bound = QVector4D(-1, -1, 1, 1);
|
||||
for (int i = 0; i < allLines.size(); i++) {
|
||||
root.lineSet.push_back(i);
|
||||
}
|
||||
root.eastGroup = eastGroupSize;
|
||||
Q.push(root);
|
||||
lineBound.push({ -1, 1 });
|
||||
vector<LineTreeNode> tmpTreeNodes, upperTreeNodes, lowerTreeNodes;
|
||||
bool isUpperDivided = false, isLowerDivided = false;
|
||||
while (!lineBound.empty()) {
|
||||
// 取出一行的所有可行方格
|
||||
++nowEastGroup;
|
||||
auto segment = lineBound.front(); lineBound.pop();
|
||||
double yMid = (segment.first + segment.second) / 2;
|
||||
yMid = findBorderValueNotOnLine(yMid, yLineSet);
|
||||
while (!Q.empty()) {
|
||||
auto nowTreeNode = Q.front();
|
||||
if (nowTreeNode.eastGroup == nowEastGroup) {
|
||||
tmpTreeNodes.push_back(nowTreeNode);
|
||||
Q.pop();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
isUpperDivided = false; isLowerDivided = false;
|
||||
upperTreeNodes.clear(); lowerTreeNodes.clear();
|
||||
// 处理方格;
|
||||
for (auto& nowTreeNode : tmpTreeNodes) {
|
||||
LineTreeNode 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());
|
||||
isUpperDivided |= handleShortCutNode(nowTreeNode, neTreeNode, yMid, upperTreeNodes);
|
||||
nwTreeNode.bound = QVector4D(nowTreeNode.bound.x(), yMid, xMid, nowTreeNode.bound.w());
|
||||
isUpperDivided |= handleShortCutNode(nowTreeNode, nwTreeNode, yMid, upperTreeNodes);
|
||||
// 下部分
|
||||
seTreeNode.bound = QVector4D(xMid, nowTreeNode.bound.y(), nowTreeNode.bound.z(), yMid);
|
||||
isLowerDivided |= handleShortCutNode(nowTreeNode, seTreeNode, segment.first, lowerTreeNodes);
|
||||
swTreeNode.bound = QVector4D(nowTreeNode.bound.x(), nowTreeNode.bound.y(), xMid, yMid);
|
||||
isLowerDivided |= handleShortCutNode(nowTreeNode, swTreeNode, segment.first, lowerTreeNodes);
|
||||
}
|
||||
if (isUpperDivided) {
|
||||
++eastGroupSize;
|
||||
lineBound.push({ yMid, segment.second });
|
||||
for (auto& nowTreeNode : upperTreeNodes) {
|
||||
nowTreeNode.eastGroup = eastGroupSize;
|
||||
Q.push(nowTreeNode);
|
||||
}
|
||||
}
|
||||
if (isLowerDivided) {
|
||||
++eastGroupSize;
|
||||
lineBound.push({ segment.first, yMid });
|
||||
for (auto& nowTreeNode : lowerTreeNodes) {
|
||||
nowTreeNode.eastGroup = eastGroupSize;
|
||||
Q.push(nowTreeNode);
|
||||
}
|
||||
}
|
||||
tmpTreeNodes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LineTree::buildLineTree(std::vector<PointVector>& lineSet, double width, int type) {
|
||||
init();
|
||||
lineWidth = width;
|
||||
lineType = type;
|
||||
monotonization(lineSet, allLines);
|
||||
spliteToLineTree();
|
||||
simplifyLineVector();
|
||||
}
|
||||
|
||||
vector<BvhTreeData> LineTree::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(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& nowLineIndex : lineIndexs) {
|
||||
resLines.push_back(nowLineIndex);
|
||||
std::cout << nowLineIndex << ' ';
|
||||
}
|
||||
std::cout << '\n';
|
||||
// 返回构造BvhTree数据
|
||||
vector<BvhTreeData> resBvhTreeData;
|
||||
for (auto& nowTreeNode : restOfTreeNodes) {
|
||||
BvhTreeData oneData;
|
||||
oneData.leftSon = resLines.size();
|
||||
//oneData.rightSon = rightSon;
|
||||
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';
|
||||
resBvhTreeData.push_back(oneData);
|
||||
}
|
||||
return resBvhTreeData;
|
||||
}
|
|
@ -27,10 +27,12 @@ namespace Renderer {
|
|||
typedef std::vector<int> PointIndexVector;
|
||||
private:
|
||||
std::vector<LineTreeNode> restOfTreeNodes;
|
||||
std::vector<std::shared_ptr<Line>> allLine;
|
||||
int requiredLineMin, numPoint, numLine, lineWidth;
|
||||
std::vector<std::shared_ptr<Line>> allLines;
|
||||
int requiredLineMin, numPoint, numLine;
|
||||
std::map<Point, int> pointMap;
|
||||
std::vector<int> lineIndexs;
|
||||
double lineWidth;
|
||||
int lineType;
|
||||
|
||||
int getPointIndex(Point nowPoint);
|
||||
void spliteToLineTree();
|
||||
|
@ -42,10 +44,10 @@ namespace Renderer {
|
|||
static void monotonization(std::vector<PointVector>& inL, std::vector<std::shared_ptr<Line>>& outL);
|
||||
public:
|
||||
void init();
|
||||
void setLineWidth(int width);
|
||||
void setLineWidth(double width);
|
||||
LineTree(int lineMin = 3, int width = 0.3)
|
||||
: requiredLineMin(lineMin), lineWidth(width), numLine(0), numPoint(0) {}
|
||||
void buildLineTree(std::vector<PointVector>& lineSet);
|
||||
void buildLineTree(std::vector<PointVector>& lineSet, double width, int type = 0);
|
||||
std::vector<BvhTreeData> getPointLineAndBvhTree(std::vector<float>& pointSet, std::vector<GLuint>& lineSet);
|
||||
};
|
||||
}
|
|
@ -9,7 +9,7 @@ using std::pair;
|
|||
using std::vector;
|
||||
void ShortCutTree::init() {
|
||||
restOfTreeNodes.clear();
|
||||
allLine.clear();
|
||||
allLines.clear();
|
||||
pointMap.clear();
|
||||
lineIndexs.clear();
|
||||
numLine = numPoint = 0;
|
||||
|
@ -80,13 +80,13 @@ void ShortCutTree::generateShortCutSegment(ShortCutNode& nowTreeNode) {
|
|||
Point p = {0, 0};
|
||||
set<pair<int, int> > pointSet;
|
||||
for (int & lineIndex : nowTreeNode.lineSet) {
|
||||
int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), lineIndexBegin, lineIndexEnd;
|
||||
int type = allLines[lineIndex]->judgeOneSideIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), lineIndexBegin, lineIndexEnd;
|
||||
if (type >= 2) {
|
||||
if (type == 2) {
|
||||
p = allLine[lineIndex]->getEnd();
|
||||
p = allLines[lineIndex]->getEnd();
|
||||
}
|
||||
if (type == 3) {
|
||||
p = allLine[lineIndex]->getBegin();
|
||||
p = allLines[lineIndex]->getBegin();
|
||||
}
|
||||
lineIndexBegin = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.w()});
|
||||
lineIndexEnd = getPointIndex({ nowTreeNode.bound.z(), p.y });
|
||||
|
@ -123,12 +123,12 @@ void ShortCutTree::generateShortCutSegment(ShortCutNode& nowTreeNode) {
|
|||
bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, double 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);
|
||||
int type = allLines[lineIndex]->judgeOneSideIntersection(yValue, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
if (type == 2)
|
||||
sumIncrement++;
|
||||
if (type == 3)
|
||||
sumIncrement--;
|
||||
if (allLine[lineIndex]->judgeIntersection(nowTreeNode.bound)) {
|
||||
if (allLines[lineIndex]->judgeIntersection(nowTreeNode.bound)) {
|
||||
nowTreeNode.lineSet.push_back(lineIndex);
|
||||
}
|
||||
}
|
||||
|
@ -149,8 +149,8 @@ bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNod
|
|||
}
|
||||
|
||||
void ShortCutTree::simplifyLineVector() {
|
||||
numLine = allLine.size();
|
||||
for (auto& nowLine : allLine) {
|
||||
numLine = allLines.size();
|
||||
for (auto& nowLine : allLines) {
|
||||
PointVector pointVector = nowLine->toPointVector();
|
||||
for (Point& p : pointVector) {
|
||||
int pointIndex = getPointIndex(p);
|
||||
|
@ -167,11 +167,11 @@ 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);
|
||||
for (int i = 0; i < allLines.size(); i++) {
|
||||
xLineSet.insert(allLines[i]->getBegin().x);
|
||||
xLineSet.insert(allLines[i]->getEnd().x);
|
||||
yLineSet.insert(allLines[i]->getBegin().y);
|
||||
yLineSet.insert(allLines[i]->getEnd().y);
|
||||
}
|
||||
// 生成方格
|
||||
queue<ShortCutNode> Q;
|
||||
|
@ -179,7 +179,7 @@ void ShortCutTree::spliteToShortCutTree() {
|
|||
ShortCutNode root;
|
||||
int nowEastGroup = 0, eastGroupSize = 1;
|
||||
root.bound = QVector4D(-1, -1, 1, 1);
|
||||
for (int i = 0; i < allLine.size(); i++) {
|
||||
for (int i = 0; i < allLines.size(); i++) {
|
||||
root.lineSet.push_back(i);
|
||||
}
|
||||
root.eastGroup = eastGroupSize;
|
||||
|
@ -212,13 +212,13 @@ void ShortCutTree::spliteToShortCutTree() {
|
|||
if (!nowTreeNode.divided) {
|
||||
for (int& lineIndex : nowTreeNode.lineSet) {
|
||||
// 上半部分
|
||||
int type = allLine[lineIndex]->judgeBoundIntersection(yMid, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
int type = allLines[lineIndex]->judgeOneSideIntersection(yMid, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
if (type == 2)
|
||||
sumUpperIncrement++;
|
||||
if (type == 3)
|
||||
sumUpperIncrement--;
|
||||
// 下半部分
|
||||
type = allLine[lineIndex]->judgeBoundIntersection(segment.first, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
type = allLines[lineIndex]->judgeOneSideIntersection(segment.first, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
|
||||
if (type == 2)
|
||||
sumLowerIncrement++;
|
||||
if (type == 3)
|
||||
|
@ -265,7 +265,7 @@ void ShortCutTree::spliteToShortCutTree() {
|
|||
|
||||
void ShortCutTree::buildShortCutTree(vector<PointVector>& lineSet) {
|
||||
init();
|
||||
monotonization(lineSet, allLine);
|
||||
monotonization(lineSet, allLines);
|
||||
spliteToShortCutTree();
|
||||
simplifyLineVector();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Renderer
|
|||
typedef std::vector<int> PointIndexVector;
|
||||
private:
|
||||
std::vector<ShortCutNode> restOfTreeNodes;
|
||||
std::vector<std::shared_ptr<Line>> allLine;
|
||||
std::vector<std::shared_ptr<Line>> allLines;
|
||||
int requiredLineMin, numPoint, numLine;
|
||||
std::map<Point, int> pointMap;
|
||||
std::vector<int> lineIndexs;
|
||||
|
|
|
@ -26,7 +26,7 @@ double StraightLine::findTByValue(double value, bool isY) {
|
|||
}
|
||||
}
|
||||
|
||||
int StraightLine::judgeBoundIntersection(double xy, double l, double r, bool isY) {
|
||||
int StraightLine::judgeOneSideIntersection(double xy, double l, double r, bool isY) {
|
||||
Point pointBegin = getBegin(), pointEnd = getEnd();
|
||||
if (isY) {
|
||||
swap(pointBegin.x, pointBegin.y);
|
||||
|
@ -46,4 +46,16 @@ int StraightLine::judgeBoundIntersection(double xy, double l, double r, bool isY
|
|||
return 1;
|
||||
}
|
||||
return 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] };
|
||||
double d = se.x * se.x + se.y * se.y;
|
||||
double t = se.x * dd.x + se.y * dd.y;
|
||||
if (d > 0) t /= d;
|
||||
if (t < 0) t = 0;
|
||||
else if (t > 1) t = 1;
|
||||
double dx = vX[0] + t * se.x - p.x, dy = vY[0] + t * se.y - p.y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
|
@ -5,9 +5,11 @@ namespace Renderer
|
|||
class StraightLine : public Line
|
||||
{
|
||||
using Line::Line;
|
||||
public:
|
||||
virtual double getLineValueByT(double t, bool isY);
|
||||
virtual void monotonization(std::vector <LinePtr>& res) {};
|
||||
virtual double findTByValue(double value, bool isY);
|
||||
virtual int judgeBoundIntersection(double xy, double l, double r, bool isY);
|
||||
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
||||
virtual double getMinDistanceFromPoint(Point p);
|
||||
};
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
#include "MainWindow.h"
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QGuiApplication>
|
||||
#include "Renderer/Painting/CubicBezier.h"
|
||||
|
||||
using Renderer::CubicBezier;
|
||||
|
||||
extern "C" {
|
||||
_declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
|
||||
|
@ -8,10 +11,6 @@ extern "C" {
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue