修复了一个线宽比例计算的bug

main
yang.yongquan 2023-03-29 18:54:56 +08:00
parent f9e316c547
commit 4360fad504
7 changed files with 54 additions and 46 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -72,17 +72,7 @@ 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();
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 (int j = i; j <= endIndex; j++) {
PointVector& l = inLines[j];
std::shared_ptr<Line> nowLine; std::shared_ptr<Line> nowLine;
switch (l.size()) { switch (l.size()) {
case 2: { case 2: {
@ -92,18 +82,8 @@ void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_p
case 4: nowLine = make_shared<CubicBezier>(l); break; case 4: nowLine = make_shared<CubicBezier>(l); break;
default: break; default: break;
} }
totalLength += nowLine->getIntegralByT(1);
tmpLines.push_back(nowLine);
}
//데딧뺏깻헹궐절
double prefixLength = 0;
for (auto nowLine : tmpLines) {
// 防止在同一直线与 X 轴平行上 // 防止在同一直线与 X 轴平行上
double nowLineLength = nowLine->getIntegralByT(1);
nowLine->setRate({ prefixLength / totalLength, (prefixLength + nowLineLength) / totalLength });
prefixLength += nowLineLength;
if (isOffset) { if (isOffset) {
nowLine->upwardOffsetForY(true, 1e-5); nowLine->upwardOffsetForY(true, 1e-5);
} }
@ -115,9 +95,6 @@ void LineTree::monotonization(vector<PointVector>& inLines, vector<std::shared_p
nowLine->monotonization(outLines); nowLine->monotonization(outLines);
outLines.push_back(nowLine); outLines.push_back(nowLine);
} }
tmpLines.clear();
i = endIndex;
}
// 防止在首尾直线在与 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()))
@ -131,6 +108,24 @@ 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;
@ -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();
} }

View File

@ -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);
}; };
} }

View File

@ -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] };

View File

@ -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);
}; };