修复了一个线宽比例计算的bug
parent
f9e316c547
commit
4360fad504
|
@ -83,6 +83,10 @@ void CubicBezier::splitBezierCubic(double t, vector<LinePtr>& res) {
|
||||||
setRate({ ratePoint, rate.second });
|
setRate({ ratePoint, rate.second });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double CubicBezier::getLength() {
|
||||||
|
return getIntegralByT(1);
|
||||||
|
}
|
||||||
|
|
||||||
void CubicBezier::monotonization(vector <LinePtr>& res) {
|
void CubicBezier::monotonization(vector <LinePtr>& res) {
|
||||||
transformToCubic();
|
transformToCubic();
|
||||||
vector<double> breakPointsT;
|
vector<double> breakPointsT;
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Renderer
|
||||||
public:
|
public:
|
||||||
virtual double findTByValue(double value, bool isY);
|
virtual double findTByValue(double value, bool isY);
|
||||||
virtual void monotonization(std::vector <LinePtr>& res);
|
virtual void monotonization(std::vector <LinePtr>& res);
|
||||||
|
virtual double getLength();
|
||||||
virtual double getLineValueByT(double t, bool isY);
|
virtual double getLineValueByT(double t, bool isY);
|
||||||
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
||||||
virtual double getMinDistanceFromPoint(Point p);
|
virtual double getMinDistanceFromPoint(Point p);
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace Renderer
|
||||||
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY) = 0;
|
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY) = 0;
|
||||||
virtual double getMinDistanceFromPoint(Point p) = 0;
|
virtual double getMinDistanceFromPoint(Point p) = 0;
|
||||||
bool judgeOneSideIntersectionWithWidth(double xy, double l, double r, bool isY, double width, int type);
|
bool judgeOneSideIntersectionWithWidth(double xy, double l, double r, bool isY, double width, int type);
|
||||||
|
virtual double getLength() = 0;
|
||||||
virtual double findTByValue(double value, bool isY) = 0;
|
virtual double findTByValue(double value, bool isY) = 0;
|
||||||
double getIntegralByT(double t);
|
double getIntegralByT(double t);
|
||||||
bool judgeIntersectionWithWidth(QVector4D bound, double width, int type);
|
bool judgeIntersectionWithWidth(QVector4D bound, double width, int type);
|
||||||
|
|
|
@ -72,55 +72,32 @@ bool LineTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const {
|
||||||
|
|
||||||
void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_ptr<Line>>& outLines) {
|
void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_ptr<Line>>& outLines) {
|
||||||
bool isOffset = false;
|
bool isOffset = false;
|
||||||
vector<std::shared_ptr<Line> > tmpLines;
|
for (PointVector& l : inLines) {
|
||||||
tmpLines.clear();
|
std::shared_ptr<Line> nowLine;
|
||||||
for (int i = 0; i < inLines.size(); i++) {
|
switch (l.size()) {
|
||||||
int endIndex = i;
|
case 2: {
|
||||||
double totalLength = 0;
|
nowLine = make_shared<StraightLine>(l);
|
||||||
while (endIndex < inLines.size() && *inLines[endIndex].rbegin() == *inLines[endIndex + 1].begin()) {
|
break;
|
||||||
endIndex++;
|
|
||||||
}
|
}
|
||||||
// 计算总长度
|
case 4: nowLine = make_shared<CubicBezier>(l); break;
|
||||||
for (int j = i; j <= endIndex; j++) {
|
default: break;
|
||||||
PointVector& l = inLines[j];
|
|
||||||
std::shared_ptr<Line> nowLine;
|
|
||||||
switch (l.size()) {
|
|
||||||
case 2: {
|
|
||||||
nowLine = make_shared<StraightLine>(l);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4: nowLine = make_shared<CubicBezier>(l); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
totalLength += nowLine->getIntegralByT(1);
|
|
||||||
tmpLines.push_back(nowLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//单调化并求比例
|
// 防止在同一直线与 X 轴平行上
|
||||||
double prefixLength = 0;
|
if (isOffset) {
|
||||||
for (auto nowLine : tmpLines) {
|
nowLine->upwardOffsetForY(true, 1e-5);
|
||||||
// 防止在同一直线与 X 轴平行上
|
|
||||||
double nowLineLength = nowLine->getIntegralByT(1);
|
|
||||||
nowLine->setRate({ prefixLength / totalLength, (prefixLength + nowLineLength) / totalLength });
|
|
||||||
prefixLength += nowLineLength;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
tmpLines.clear();
|
isOffset = false;
|
||||||
i = endIndex;
|
if (nowLine->direction(true) == 0) {
|
||||||
|
nowLine->upwardOffsetForY(false, 1e-5);
|
||||||
|
isOffset = true;
|
||||||
|
}
|
||||||
|
nowLine->monotonization(outLines);
|
||||||
|
outLines.push_back(nowLine);
|
||||||
}
|
}
|
||||||
// 防止在首尾直线在与 X 轴平行上
|
// 防止在首尾直线在与 X 轴平行上
|
||||||
int siz = outLines.size();
|
int siz = outLines.size();
|
||||||
if (!(outLines[0]->getBegin() == outLines[siz - 1]->getEnd()))
|
if (!(outLines[0]->getBegin() == outLines[siz - 1]->getEnd()))
|
||||||
return;
|
return;
|
||||||
if (isOffset) {
|
if (isOffset) {
|
||||||
outLines[0]->upwardOffsetForY(true, 1e-5);
|
outLines[0]->upwardOffsetForY(true, 1e-5);
|
||||||
|
@ -131,13 +108,31 @@ void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LineTree::countLinesRate(std::vector<std::shared_ptr<Line> >& lines) {
|
||||||
|
// 计算线的正确比例
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
int endIndex = i;
|
||||||
|
double totalLength = lines[i]->getLength();
|
||||||
|
while (endIndex + 1 < lines.size() && lines[endIndex]->getEnd() == lines[endIndex + 1]->getBegin()) {
|
||||||
|
totalLength += lines[++endIndex]->getLength();
|
||||||
|
}
|
||||||
|
double prefixLength = 0;
|
||||||
|
for (int j = i; j <= endIndex; j++) {
|
||||||
|
double nowLineLength = lines[j]->getLength();
|
||||||
|
lines[j]->setRate({ prefixLength / totalLength, (prefixLength + nowLineLength) / totalLength });
|
||||||
|
prefixLength += nowLineLength;
|
||||||
|
}
|
||||||
|
i = endIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LineTree::simplifyLineVector() {
|
void LineTree::simplifyLineVector() {
|
||||||
bool canPut = false;
|
bool canPut = false;
|
||||||
GLuint index = 0;
|
GLuint index = 0;
|
||||||
numLine = allLines.size();
|
numLine = allLines.size();
|
||||||
for (auto& nowLine : allLines) {
|
for (auto& nowLine : allLines) {
|
||||||
PointVector pointVector = nowLine->toPointVector();
|
PointVector pointVector = nowLine->toPointVector();
|
||||||
canPut = false;
|
canPut = false;
|
||||||
index = 0;
|
index = 0;
|
||||||
for (Point& p : pointVector) {
|
for (Point& p : pointVector) {
|
||||||
int pointIndex = getPointIndex(p);
|
int pointIndex = getPointIndex(p);
|
||||||
|
@ -165,8 +160,8 @@ bool LineTree::handleShortCutNode(LineTreeNode& fa, LineTreeNode& nowTreeNode, d
|
||||||
nowTreeNode.lineSet.push_back(lineIndex);
|
nowTreeNode.lineSet.push_back(lineIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nowTreeNode.lineSet.size() <= requiredLineMin
|
if (nowTreeNode.lineSet.size() <= requiredLineMin
|
||||||
|| (nowTreeNode.bound.z()-nowTreeNode.bound.x())*sqrt(2) <= lineWidth) {
|
|| (nowTreeNode.bound.z() - nowTreeNode.bound.x()) * sqrt(2) <= lineWidth) {
|
||||||
if (nowTreeNode.lineSet.empty())
|
if (nowTreeNode.lineSet.empty())
|
||||||
return false;
|
return false;
|
||||||
restOfTreeNodes.push_back(nowTreeNode);
|
restOfTreeNodes.push_back(nowTreeNode);
|
||||||
|
@ -263,6 +258,7 @@ void LineTree::buildLineTree(std::vector<PointVector>& lineSet, double width, in
|
||||||
lineWidth = width;
|
lineWidth = width;
|
||||||
lineType = type;
|
lineType = type;
|
||||||
monotonization(lineSet, allLines);
|
monotonization(lineSet, allLines);
|
||||||
|
countLinesRate(allLines);
|
||||||
spliteToLineTree();
|
spliteToLineTree();
|
||||||
simplifyLineVector();
|
simplifyLineVector();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Renderer {
|
||||||
: requiredLineMin(lineMin), numLine(0), numPoint(0) {}
|
: requiredLineMin(lineMin), numLine(0), numPoint(0) {}
|
||||||
void buildLineTree(std::vector<PointVector>& lineSet, double width, int type = 0);
|
void buildLineTree(std::vector<PointVector>& lineSet, double width, int type = 0);
|
||||||
static void monotonization(std::vector<PointVector>& inL, std::vector<std::shared_ptr<Line>>& outL);
|
static void monotonization(std::vector<PointVector>& inL, std::vector<std::shared_ptr<Line>>& outL);
|
||||||
|
static void countLinesRate(std::vector<std::shared_ptr<Line> >& lines);
|
||||||
std::vector<BvhTreeData> getPointLineAndBvhTree(std::vector<float>& pointSet, std::vector<GLuint>& lineSet);
|
std::vector<BvhTreeData> getPointLineAndBvhTree(std::vector<float>& pointSet, std::vector<GLuint>& lineSet);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -52,6 +52,10 @@ int StraightLine::judgeOneSideIntersection(double xy, double l, double r, bool i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double StraightLine::getLength() {
|
||||||
|
return sqrt((vX[1] - vX[0]) * (vX[1] - vX[0]) + (vY[1] - vY[0]) * (vY[1] - vY[0]));
|
||||||
|
}
|
||||||
|
|
||||||
double StraightLine::getMinDistanceFromPoint(Point p) {
|
double StraightLine::getMinDistanceFromPoint(Point p) {
|
||||||
Point se = { vX[1] - vX[0], vY[1] - vY[0] };
|
Point se = { vX[1] - vX[0], vY[1] - vY[0] };
|
||||||
Point dd = { p.x - vX[0], p.y - vY[0] };
|
Point dd = { p.x - vX[0], p.y - vY[0] };
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Renderer
|
||||||
virtual void monotonization(std::vector <LinePtr>& res) {};
|
virtual void monotonization(std::vector <LinePtr>& res) {};
|
||||||
virtual double findTByValue(double value, bool isY);
|
virtual double findTByValue(double value, bool isY);
|
||||||
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY);
|
||||||
|
virtual double getLength();
|
||||||
virtual double getMinDistanceFromPoint(Point p);
|
virtual double getMinDistanceFromPoint(Point p);
|
||||||
virtual double ValueOfFunctionS(double t);
|
virtual double ValueOfFunctionS(double t);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue