shape ops work in progress
authorcaryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 19 Feb 2013 12:49:33 +0000 (12:49 +0000)
committercaryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 19 Feb 2013 12:49:33 +0000 (12:49 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@7766 2bbb7eff-a529-9590-31e7-b0007b416f81

experimental/Intersection/CubicIntersection.cpp
experimental/Intersection/QuadraticUtilities.cpp
experimental/Intersection/QuadraticUtilities.h
experimental/Intersection/Simplify.cpp
experimental/Intersection/SimplifyNew_Test.cpp
experimental/Intersection/op.htm

index d92c8bf..f4a7ef7 100644 (file)
@@ -11,6 +11,7 @@
 #include "IntersectionUtilities.h"
 #include "LineIntersection.h"
 #include "LineUtilities.h"
+#include "QuadraticUtilities.h"
 
 #if ONE_OFF_DEBUG
 static const double tLimits[2][2] = {{0.516980827, 0.516981209}, {0.647714088, 0.64771447}};
@@ -496,29 +497,17 @@ bool intersect3(const Cubic& c1, const Cubic& c2, Intersections& i) {
     return result;
 }
 
+// Up promote the quad to a cubic.
+// OPTIMIZATION If this is a common use case, optimize by duplicating
+// the intersect 3 loop to avoid the promotion  / demotion code
 int intersect(const Cubic& cubic, const Quadratic& quad, Intersections& i) {
-    SkTDArray<double> ts;
-    double precision = calcPrecision(cubic);
-    cubic_to_quadratics(cubic, precision, ts);
-    double tStart = 0;
-    Cubic part;
-    int tsCount = ts.count();
-    for (int idx = 0; idx <= tsCount; ++idx) {
-        double t = idx < tsCount ? ts[idx] : 1;
-        Quadratic q1;
-        sub_divide(cubic, tStart, t, part);
-        demote_cubic_to_quad(part, q1);
-        Intersections locals;
-        intersect2(q1, quad, locals);
-        for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
-            double globalT = tStart + (t - tStart) * locals.fT[0][tIdx];
-            i.insert(globalT, locals.fT[1][tIdx], locals.fPt[tIdx]);
-        }
-        tStart = t;
-    }
+    Cubic up;
+    toCubic(quad, up);
+    (void) intersect3(cubic, up, i);
     return i.used();
 }
 
+// FIXME: this needs to be recursive like intersect 3
 bool intersect(const Cubic& cubic, Intersections& i) {
     SkTDArray<double> ts;
     double precision = calcPrecision(cubic);
index fa8acea..7133e2e 100644 (file)
@@ -197,6 +197,16 @@ int quadraticRootsReal(const double A, const double B, const double C, double s[
 #endif
 }
 
+void toCubic(const Quadratic& quad, Cubic& cubic) {
+    cubic[0] = quad[0];
+    cubic[2] = quad[1];
+    cubic[3] = quad[2];
+    cubic[1].x = (cubic[0].x + cubic[2].x * 2) / 3;
+    cubic[1].y = (cubic[0].y + cubic[2].y * 2) / 3;
+    cubic[2].x = (cubic[3].x + cubic[2].x * 2) / 3;
+    cubic[2].y = (cubic[3].y + cubic[2].y * 2) / 3;
+}
+
 static double derivativeAtT(const double* quad, double t) {
     double a = t - 1;
     double b = 1 - 2 * t;
index 8308f38..74ab809 100644 (file)
@@ -36,6 +36,7 @@ inline void set_abc(const double* quad, double& a, double& b, double& c) {
 int quadraticRootsReal(double A, double B, double C, double t[2]);
 int quadraticRootsValidT(const double A, const double B, const double C, double s[2]);
 void sub_divide(const Quadratic& src, double t1, double t2, Quadratic& dst);
+void toCubic(const Quadratic& , Cubic& );
 _Point top(const Quadratic& , double startT, double endT);
 void xy_at_t(const Quadratic& , double t, double& x, double& y);
 _Point xy_at_t(const Quadratic& , double t);
index 5cfc388..2c71039 100644 (file)
@@ -2786,7 +2786,7 @@ public:
         // topmost tangent from y-min to first pt is closer to horizontal
         SkASSERT(!done());
         int firstT = -1;
-        SkPoint topPt = activeLeftTop(onlySortable, &firstT);
+        /* SkPoint topPt = */ activeLeftTop(onlySortable, &firstT);
         SkASSERT(firstT >= 0);
         // sort the edges to find the leftmost
         int step = 1;
index 4c83be7..78b815a 100644 (file)
@@ -3832,12 +3832,26 @@ static void cubicOp19i() {
     testShapeOp(path, pathB, kIntersect_Op);
 }
 
-static void (*firstTest)() = cubicOp19i;
+static void cubicOp20d() {
+    SkPath path, pathB;
+    path.setFillType(SkPath::kWinding_FillType);
+    path.moveTo(0,1);
+    path.cubicTo(0,1, 6,0, 2,1);
+    path.close();
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(0,6);
+    pathB.cubicTo(1,2, 1,0, 1,0);
+    pathB.close();
+    testShapeOp(path, pathB, kDifference_Op);
+}
+
+static void (*firstTest)() = cubicOp20d;
 
 static struct {
     void (*fun)();
     const char* str;
 } tests[] = {
+    TEST(cubicOp20d),
     TEST(cubicOp19i),
     TEST(cubicOp18d),
     TEST(cubicOp17d),
index 6d45854..9c2ce8e 100644 (file)
@@ -3589,11 +3589,23 @@ path.addRect(4, 13, 13, 16, SkPath::kCCW_Direction);
     pathB.close();
 </div>
 
+<div id="cubicOp20d">
+    path.setFillType(SkPath::kWinding_FillType);
+    path.moveTo(0,1);
+    path.cubicTo(0,1, 6,0, 2,1);
+    path.close();
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(0,6);
+    pathB.cubicTo(1,2, 1,0, 1,0);
+    pathB.close();
+</div>
+
 </div>
 
 <script type="text/javascript">
 
 var testDivs = [
+    cubicOp20d,
     cubicOp19i,
     cubicOp18d,
     cubicOp17d,