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