解决单调化问题

dev-VirtualTexture
wuyize 2022-10-12 18:46:24 +08:00
parent 3d80d98513
commit 6ca1b334bf
4 changed files with 32 additions and 29 deletions

View File

@ -20,25 +20,18 @@ Point CubicBezier::calculateControlPoint(Point a, Point b) {
} }
void CubicBezier::findPointsOfDivison(vector<double> &p, vector<double>& res) { void CubicBezier::findPointsOfDivison(vector<double> &p, vector<double>& res) {
double a = -3 * p[0] + 3 * p[1] - 3 * p[2] + 3 * p[3]; double a = (-p[0] + 3 * p[1] - 3 * p[2] + p[3]);
double b = 6 * p[0] - 4 * p[1] + 2 * p[2];
double c = -3 * p[0] + p[1];
double deta = b * b - 4 * a * c, t = 0;
if (fabs(a) > eps) { if (fabs(a) > eps) {
if (deta < eps) return; double delta = (-p[0] * p[2] + p[0] * p[3] - p[1] * p[2] - p[1] * p[3] + p[1] * p[1] + p[2] * p[2]);
deta = sqrt(deta); if (delta < 0) return;
t = (-b + deta) / 2 * a; double t1 = (-p[0] + 2 * p[1] - p[2] + sqrt(delta)) / a, t2 = (-p[0] + 2 * p[1] - p[2] - sqrt(delta)) / a;
if (0 < t && t < 1) { if (0 < t1 && t1 < 1) res.push_back(t1);
res.push_back(t); if (0 < t2 && t2 < 1 && fabs(t1 - t2) > eps) res.push_back(t2);
}
if (fabs(deta) <= eps) return;
t = (-b - deta) / 2 * a;
if (0 < t && t < 1) {
res.push_back(t);
}
} }
else if(fabs(b) > eps) { else {
t = -c/b; double b = (2 * p[0] - 4 * p[1] + 2 * p[2]);
if (fabs(b) <= eps) return;
double t = (p[0] - p[1]) / (2 * p[0] - 4 * p[1] + 2 * p[2]);
if (0 < t && t < 1) { if (0 < t && t < 1) {
res.push_back(t); res.push_back(t);
} }
@ -81,12 +74,13 @@ void CubicBezier::monotonization(vector <LinePtr>& res) {
breakPointsT.clear(); breakPointsT.clear();
findPointsOfDivison(vX, breakPointsT); findPointsOfDivison(vX, breakPointsT);
findPointsOfDivison(vY, breakPointsT); findPointsOfDivison(vY, breakPointsT);
if (breakPointsT.empty()) return;
sort(breakPointsT.begin(), breakPointsT.end()); sort(breakPointsT.begin(), breakPointsT.end());
double lt = -1, x = 0, y = 0; for (auto& t : breakPointsT) {
for (double&t : breakPointsT) { if (fabs(t) <= eps || fabs(1 - t) <= eps) continue;
if (fabs(t - lt) <= eps) continue;
splitBezierCubic(t, res); splitBezierCubic(t, res);
lt = t; monotonization(res);
return;
} }
} }

View File

@ -192,7 +192,14 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
//vector<vector<Point>> lineSet = SvgParser("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", 100, 100).parse(); //vector<vector<Point>> lineSet = SvgParser("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", 100, 100).parse();
vector<vector<Point>> lineSet = SvgParser("M308.49,212.25l23,28.38-82,78.31c-14.28,13.64-26.34-20.6-53.44,9.32l-30.24-13.4,63.56-51.59L190.71,215.6l-32.92,26.72L149.5,232.1l32.92-26.72L173.2,194l-32.91,26.72-7.38-9.08L165.83,185l-38.69-47.66L94.22,164,85,152.65l32.91-26.72-9.21-11.35L75.79,141.3l-5.53-6.81,32.92-26.72L94,96.42,61.05,123.14l-12-14.76L37.72,117.6l12,14.75L30.41,148,0,110.55,136.2,0l30.4,37.46L147.31,53.12l-12-14.76L124,47.58l12,14.75L103.05,89.05l9.21,11.35,32.92-26.72,5.52,6.81-32.91,26.72L127,118.56l32.92-26.72,9.21,11.35-32.91,26.72,38.69,47.67,32.91-26.72,7.37,9.08-32.91,26.72L191.49,198l32.92-26.72,8.29,10.22-32.92,26.71,38.7,47.68L302,204.3l6.45,7.95Z", 331.52, 328.26).parse(); //vector<vector<Point>> lineSet = SvgParser("M308.49,212.25l23,28.38-82,78.31c-14.28,13.64-26.34-20.6-53.44,9.32l-30.24-13.4,63.56-51.59L190.71,215.6l-32.92,26.72L149.5,232.1l32.92-26.72L173.2,194l-32.91,26.72-7.38-9.08L165.83,185l-38.69-47.66L94.22,164,85,152.65l32.91-26.72-9.21-11.35L75.79,141.3l-5.53-6.81,32.92-26.72L94,96.42,61.05,123.14l-12-14.76L37.72,117.6l12,14.75L30.41,148,0,110.55,136.2,0l30.4,37.46L147.31,53.12l-12-14.76L124,47.58l12,14.75L103.05,89.05l9.21,11.35,32.92-26.72,5.52,6.81-32.91,26.72L127,118.56l32.92-26.72,9.21,11.35-32.91,26.72,38.69,47.67,32.91-26.72,7.37,9.08-32.91,26.72L191.49,198l32.92-26.72,8.29,10.22-32.92,26.71,38.7,47.68L302,204.3l6.45,7.95Z", 331.52, 328.26).parse();
vector < vector <Point>> lineSet = {
{{-0.5,0.9}, {0.1,0.3}},
{{0.1,0.3}, {0.0204656,0.379534}, {-0.2,0.0632573}, {-0.2,0.175736}},
{{-0.2,0.175736}, {-0.2,0.288215}, {-0.579534,0.220466}, {-0.5,0.3}},
{{-0.5,0.3}, {-0.420466,0.379534}, {-0.736743,0.6}, {-0.624264,0.6}},
{{-0.624264,0.6}, {-0.511785,0.6}, {-0.579534,0.979534}, {-0.5,0.9}}
};
qDebug() << lineSet.size(); qDebug() << lineSet.size();
for (vector<Point> line : lineSet) for (vector<Point> line : lineSet)
{ {

View File

@ -765,10 +765,12 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, inout vec3 deb
elementData[pointsOffset + 2 * p2Index + 1]); elementData[pointsOffset + 2 * p2Index + 1]);
vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index], vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index],
elementData[pointsOffset + 2 * p3Index + 1]); elementData[pointsOffset + 2 * p3Index + 1]);
if(distance(localUV, p0)<0.01) if( bound.z==p0.x && distance(localUV, p3)<0.01)
if( bound.z==p0.x ) {
debugBVH = vec3(0,0,1); debugBVH = vec3(0,0,1);
else debugBVH = vec3(1,1,1); }
else if(distance(localUV, p0)<0.01)
debugBVH = vec3(1,1,1);
if (p0 == p1 && p2 == p3) if (p0 == p1 && p2 == p3)
{ {
num_its += segment_int_test(localUV, p0, p3); num_its += segment_int_test(localUV, p0, p3);

View File

@ -45,7 +45,7 @@ void ShortCutTree::monotonization(vector<PointVector>& inL, vector<LinePtr>& out
} }
void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) { void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) {
Point p = {0, 0}; Point p = {0, 0};
set<pair<int, int> > pointSet; set<pair<int, int> > pointSet;
for (int & lineIndex : nowTreeNode.lineSet) { for (int & lineIndex : nowTreeNode.lineSet) {
int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), lineIndexBegin, lineIndexEnd; int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), lineIndexBegin, lineIndexEnd;
@ -56,8 +56,8 @@ void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) {
if (type == 3) { if (type == 3) {
p = allLine[lineIndex]->getBegin(); p = allLine[lineIndex]->getBegin();
} }
lineIndexBegin = getPointIndex({ p.x, nowTreeNode.bound.w() }); lineIndexBegin = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.w()});
lineIndexEnd = getPointIndex(p); lineIndexEnd = getPointIndex({ nowTreeNode.bound.z(), p.y });
auto iter = pointSet.find({ lineIndexBegin, lineIndexEnd }); auto iter = pointSet.find({ lineIndexBegin, lineIndexEnd });
if (iter != pointSet.end()) { if (iter != pointSet.end()) {
pointSet.erase(iter); pointSet.erase(iter);