Cubic curve distance optimization

This commit is contained in:
Chlumsky 2025-06-20 16:50:26 +02:00
parent 9e7901aa7c
commit e3ced1e362
1 changed files with 14 additions and 9 deletions

View File

@ -244,17 +244,22 @@ SignedDistance CubicSegment::signedDistance(Point2 origin, double &param) const
} }
// Iterative minimum distance search // Iterative minimum distance search
for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i) { for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i) {
double t = (double) i/MSDFGEN_CUBIC_SEARCH_STARTS; double t = 1./MSDFGEN_CUBIC_SEARCH_STARTS*i;
Vector2 qe = qa+3*t*ab+3*t*t*br+t*t*t*as; Vector2 qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
Vector2 d1 = 3*ab+6*t*br+3*t*t*as; Vector2 d1 = 3*ab+6*t*br+3*t*t*as;
for (int step = 0; step < MSDFGEN_CUBIC_SEARCH_STEPS; ++step) { Vector2 d2 = 6*br+6*t*as;
// Improve t double improvedT = t-dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
Vector2 d2 = 6*br+6*t*as; if (improvedT > 0 && improvedT < 1) {
t -= dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2)); int remainingSteps = MSDFGEN_CUBIC_SEARCH_STEPS;
if (t <= 0 || t >= 1) do {
break; t = improvedT;
qe = qa+3*t*ab+3*t*t*br+t*t*t*as; qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
d1 = 3*ab+6*t*br+3*t*t*as; d1 = 3*ab+6*t*br+3*t*t*as;
if (!--remainingSteps)
break;
d2 = 6*br+6*t*as;
improvedT = t-dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
} while (improvedT > 0 && improvedT < 1);
double distance = qe.length(); double distance = qe.length();
if (distance < fabs(minDistance)) { if (distance < fabs(minDistance)) {
minDistance = nonZeroSign(crossProduct(d1, qe))*distance; minDistance = nonZeroSign(crossProduct(d1, qe))*distance;