解决单调化问题
parent
3d80d98513
commit
6ca1b334bf
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue