Intersection work in progress
Review URL: https://codereview.appspot.com/5576043

git-svn-id: http://skia.googlecode.com/svn/trunk@3087 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/CubicParameterization.cpp b/experimental/Intersection/CubicParameterization.cpp
index 9f45ba2..c14dd7e 100644
--- a/experimental/Intersection/CubicParameterization.cpp
+++ b/experimental/Intersection/CubicParameterization.cpp
@@ -226,7 +226,7 @@
 
 /* Control points to parametric coefficients
     s = 1 - t
-    Attt + 3Btt2 + 3Ctss + Dsss ==
+    Attt + 3Btts + 3Ctss + Dsss ==
     Attt + 3B(1 - t)tt + 3C(1 - t)(t - tt) + D(1 - t)(1 - 2t + tt) ==
     Attt + 3B(tt - ttt) + 3C(t - tt - tt + ttt) + D(1-2t+tt-t+2tt-ttt) ==
     Attt + 3Btt - 3Bttt + 3Ct - 6Ctt + 3Cttt + D - 3Dt + 3Dtt - Dttt ==
@@ -236,6 +236,23 @@
     c =           3*C - 3*D
     d =                   D
  */
+ 
+ /* http://www.algorithmist.net/bezier3.html
+    p = 3 * A
+    q = 3 * B
+    r = 3 * C
+    a = A
+    b = q - p
+    c = p - 2 * q + r
+    d = D - A + q - r
+
+ B(t) = a + t * (b + t * (c + t * d))
+ 
+ so
+ 
+ B(t) = a + t*b + t*t*(c + t*d)
+      = a + t*b + t*t*c + t*t*t*d
+  */
 static void set_abcd(const double* cubic, double& a, double& b, double& c,
                      double& d) {
     a = cubic[0];     // a = A
@@ -251,22 +268,47 @@
     b -= c;     // b = 3*B - 6*C + 3*D
 }
 
+static void alt_set_abcd(const double* cubic, double& a, double& b, double& c,
+                     double& d) {
+    a = cubic[0];
+    double p = 3 * a;
+    double q = 3 * cubic[2];
+    double r = 3 * cubic[4];
+    b = q - p;
+    c = p - 2 * q + r;
+    d = cubic[6] - a + q - r;
+}
+
+const bool try_alt = true;
+
 bool implicit_matches(const Cubic& one, const Cubic& two) {
     double p1[coeff_count]; // a'xxx , b'xxy , c'xyy , d'xx , e'xy , f'yy, etc.
     double p2[coeff_count];
     double a1, b1, c1, d1;
-    set_abcd(&one[0].x, a1, b1, c1, d1);
+    if (try_alt)
+        alt_set_abcd(&one[0].x, a1, b1, c1, d1);
+    else
+        set_abcd(&one[0].x, a1, b1, c1, d1);
     double e1, f1, g1, h1;
-    set_abcd(&one[0].y, e1, f1, g1, h1);
+    if (try_alt)
+        alt_set_abcd(&one[0].y, e1, f1, g1, h1);
+    else
+        set_abcd(&one[0].y, e1, f1, g1, h1);
     calc_ABCD(a1, e1, p1);
     double a2, b2, c2, d2;
-    set_abcd(&two[0].x, a2, b2, c2, d2);
+    if (try_alt)
+        alt_set_abcd(&two[0].x, a2, b2, c2, d2);
+    else
+        set_abcd(&two[0].x, a2, b2, c2, d2);
     double e2, f2, g2, h2;
-    set_abcd(&two[0].y, e2, f2, g2, h2);
+    if (try_alt)
+        alt_set_abcd(&two[0].y, e2, f2, g2, h2);
+    else
+        set_abcd(&two[0].y, e2, f2, g2, h2);
     calc_ABCD(a2, e2, p2);
     int first = 0;
     for (int index = 0; index < coeff_count; ++index) {
-        if (index == xx_coeff) {
+        if (!try_alt && index == xx_coeff) {
             calc_bc(d1, b1, c1);
             calc_bc(h1, f1, g1);
             calc_bc(d2, b2, c2);
@@ -304,3 +346,7 @@
     result.y = tangent(&cubic[0].y, t);
 }
 
+// unit test to return and validate parametric coefficients
+#include "CubicParameterization_TestUtility.cpp"
+
+