Parcourir la source

Cubic curve distance improvement

Chlumsky il y a 1 mois
Parent
commit
15833154b3
1 fichiers modifiés avec 9 ajouts et 8 suppressions
  1. 9 8
      core/edge-segments.cpp

+ 9 - 8
core/edge-segments.cpp

@@ -199,9 +199,9 @@ SignedDistance QuadraticSegment::signedDistance(Point2 origin, double &param) co
     double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
     param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
     {
-        epDir = direction(1);
         double distance = (p[2]-origin).length(); // distance from B
         if (distance < fabs(minDistance)) {
+            epDir = direction(1);
             minDistance = nonZeroSign(crossProduct(epDir, p[2]-origin))*distance;
             param = dotProduct(origin-p[1], epDir)/dotProduct(epDir, epDir);
         }
@@ -235,9 +235,9 @@ SignedDistance CubicSegment::signedDistance(Point2 origin, double &param) const
     double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
     param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
     {
-        epDir = direction(1);
         double distance = (p[3]-origin).length(); // distance from B
         if (distance < fabs(minDistance)) {
+            epDir = direction(1);
             minDistance = nonZeroSign(crossProduct(epDir, p[3]-origin))*distance;
             param = dotProduct(epDir-(p[3]-origin), epDir)/dotProduct(epDir, epDir);
         }
@@ -246,19 +246,20 @@ SignedDistance CubicSegment::signedDistance(Point2 origin, double &param) const
     for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i) {
         double t = (double) i/MSDFGEN_CUBIC_SEARCH_STARTS;
         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;
         for (int step = 0; step < MSDFGEN_CUBIC_SEARCH_STEPS; ++step) {
             // Improve t
-            Vector2 d1 = 3*ab+6*t*br+3*t*t*as;
             Vector2 d2 = 6*br+6*t*as;
             t -= dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
             if (t <= 0 || t >= 1)
                 break;
             qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
-            double distance = qe.length();
-            if (distance < fabs(minDistance)) {
-                minDistance = nonZeroSign(crossProduct(d1, qe))*distance;
-                param = t;
-            }
+            d1 = 3*ab+6*t*br+3*t*t*as;
+        }
+        double distance = qe.length();
+        if (distance < fabs(minDistance)) {
+            minDistance = nonZeroSign(crossProduct(d1, qe))*distance;
+            param = t;
         }
     }