From: caryclark@google.com Date: Wed, 25 Jan 2012 18:57:23 +0000 (+0000) Subject: Intersection work in progress X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~16932 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27accef223a27fba437f5e825d99edbae20a045b;p=platform%2Fupstream%2FlibSkiaSharp.git 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/ConvexHull_Test.cpp b/experimental/Intersection/ConvexHull_Test.cpp index dffca6d..74329c7 100644 --- a/experimental/Intersection/ConvexHull_Test.cpp +++ b/experimental/Intersection/ConvexHull_Test.cpp @@ -1,5 +1,5 @@ #include "CubicIntersection.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" #include "IntersectionUtilities.h" const Cubic convex[] = { diff --git a/experimental/Intersection/CubeRoot.cpp b/experimental/Intersection/CubeRoot.cpp index e188b34..37c8844 100644 --- a/experimental/Intersection/CubeRoot.cpp +++ b/experimental/Intersection/CubeRoot.cpp @@ -2,7 +2,7 @@ // #include -#include "CubicIntersection.h" +#include "CubicUtilities.h" #define TEST_ALTERNATIVES 0 #if TEST_ALTERNATIVES diff --git a/experimental/Intersection/CubicBezierClip_Test.cpp b/experimental/Intersection/CubicBezierClip_Test.cpp index 3228d89..1e7942d 100644 --- a/experimental/Intersection/CubicBezierClip_Test.cpp +++ b/experimental/Intersection/CubicBezierClip_Test.cpp @@ -1,8 +1,8 @@ #include "CubicIntersection.h" #include "CubicIntersection_TestData.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" -void BezierClip_Test() { +void CubicBezierClip_Test() { for (size_t index = 0; index < tests_count; ++index) { const Cubic& cubic1 = tests[index][0]; const Cubic& cubic2 = tests[index][1]; diff --git a/experimental/Intersection/CubicCoincidence.cpp b/experimental/Intersection/CubicCoincidence.cpp deleted file mode 100644 index e2ec641..0000000 --- a/experimental/Intersection/CubicCoincidence.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - Suppose two cubics are coincident. Then a third cubic exists described by two - of the four endpoints. The coincident endpoints must be on or inside the convex - hulls of both cubics. - - The coincident control points, while unknown, must lie on the line segment from - the coincident end point to its original control point. - - Given a cubic c1, c2, A, and D: - A = c1[0]*(1 - t1)*(1 - t1)*(1 - t1) + 3*c1[1]*t1*(1 - t1)*(1 - t1) + 3*c1[2]*t1*t1*(1 - t1) + c1[3]*t1*t1*t1 - D = c2[0]*(1 - t2)*(1 - t2)*(1 - t2) + 3*c2[1]*t2*(1 - t2)*(1 - t2) + 3*c2[2]*t2*t2*(1 - t2) + c213]*t2*t2*t2 - - Assuming that A was originally from c2: - - B = c2[0]*(1 - t2) + c2[1]*t2 - C = c1[0]*(1 - t1) + c1[0]*t1 - - - - If both ends of the same cubic is contained in the convex hull of the other, - then, are there t values of the larger cubic that describe the end points; is - the mid-value of those ts on the smaller cubic, and, are the tangents at the - smaller ends the same as on both. - - This all requires knowing the t values. - - - - Maybe solving the cubic is possible. Given x, find t. Given t, find y. - -see en.wikipedia.org/wiki/Cubic_polynomial - - Another way of writing the solution may be obtained by noting that the proof of above formula shows that the product of the two cube roots is rational. This gives the following formula in which or stands for any choice of the square or cube root, if - -If and , the sign of has to be chosen to have . -If and , the three roots are equal: - -If Q = 0 and , the above expression for the roots is correct but misleading, hiding the fact that no radical is needed to represent the roots. In fact, in this case, there is a double root, - -and a simple root - - - - */ - diff --git a/experimental/Intersection/CubicIntersection.h b/experimental/Intersection/CubicIntersection.h index dd6c52e..e5d74c0 100644 --- a/experimental/Intersection/CubicIntersection.h +++ b/experimental/Intersection/CubicIntersection.h @@ -9,23 +9,27 @@ void chop_at(const Cubic& src, CubicPair& dst, double t); void chop_at(const Quadratic& src, QuadraticPair& dst, double t); int convex_hull(const Cubic& cubic, char order[4]); bool convex_x_hull(const Cubic& cubic, char connectTo0[2], char connectTo3[2]); -double cube_root(double x); -int cubic_roots(const double coeff[4], double tValues[3]); bool implicit_matches(const Cubic& cubic1, const Cubic& cubic2); bool implicit_matches(const Quadratic& quad1, const Quadratic& quad2); -int quadratic_roots(const double coeff[3], double tValues[2]); void sub_divide(const Cubic& src, double t1, double t2, Cubic& dst); void sub_divide(const Quadratic& src, double t1, double t2, Quadratic& dst); void tangent(const Cubic& cubic, double t, _Point& result); void tangent(const Quadratic& cubic, double t, _Point& result); +// utilities used only for unit testing +bool point_on_parameterized_curve(const Cubic& cubic, const _Point& point); +bool point_on_parameterized_curve(const Quadratic& quad, const _Point& point); + // main functions enum ReduceOrder_Flags { kReduceOrder_NoQuadraticsAllowed, kReduceOrder_QuadraticsAllowed }; int reduceOrder(const Cubic& cubic, Cubic& reduction, ReduceOrder_Flags ); +int reduceOrder(const _Line& line, _Line& reduction); int reduceOrder(const Quadratic& quad, Quadratic& reduction); -bool intersectStart(const Cubic& cubic1, const Cubic& cubic2, Intersections& ); +//bool intersectStart(const Cubic& cubic1, const Cubic& cubic2, Intersections& ); bool intersectStartT(const Cubic& cubic1, const Cubic& cubic2, Intersections& ); +bool intersectStart(const Cubic& cubic, const _Line& line, Intersections& ); bool intersectStart(const Quadratic& q1, const Quadratic& q2, Intersections& ); +bool intersectStart(const Quadratic& quad, const _Line& line, Intersections& ); diff --git a/experimental/Intersection/CubicIntersectionT.cpp b/experimental/Intersection/CubicIntersectionT.cpp index d58bcb9..615c3a7 100644 --- a/experimental/Intersection/CubicIntersectionT.cpp +++ b/experimental/Intersection/CubicIntersectionT.cpp @@ -44,9 +44,11 @@ bool intersect(double minT1, double maxT1, double minT2, double maxT2) { sub_divide(cubic1, minT1, maxT1, intersections.swapped() ? larger : smaller); sub_divide(cubic2, minT2, maxT2, intersections.swapped() ? smaller : larger); Cubic smallResult; - if (reduceOrder(smaller, smallResult, kReduceOrder_NoQuadraticsAllowed) <= 2) { + if (reduceOrder(smaller, smallResult, + kReduceOrder_NoQuadraticsAllowed) <= 2) { Cubic largeResult; - if (reduceOrder(larger, largeResult, kReduceOrder_NoQuadraticsAllowed) <= 2) { + if (reduceOrder(larger, largeResult, + kReduceOrder_NoQuadraticsAllowed) <= 2) { _Point pt; const _Line& smallLine = (const _Line&) smallResult; const _Line& largeLine = (const _Line&) largeResult; @@ -87,16 +89,23 @@ bool intersect(double minT1, double maxT1, double minT2, double maxT2) { double newMinT1 = interp(minT1, maxT1, minT); double newMaxT1 = interp(minT1, maxT1, maxT); split = (newMaxT1 - newMinT1 > (maxT1 - minT1) * tClipLimit) << 1; - printf("%s d=%d s=%d new1=(%g,%g) old1=(%g,%g) split=%d\n", __FUNCTION__, depth, - splits, newMinT1, newMaxT1, minT1, maxT1, split); +#define VERBOSE 0 +#if VERBOSE + printf("%s d=%d s=%d new1=(%g,%g) old1=(%g,%g) split=%d\n", + __FUNCTION__, depth, splits, newMinT1, newMaxT1, minT1, maxT1, + split); +#endif minT1 = newMinT1; maxT1 = newMaxT1; } else { double newMinT2 = interp(minT2, maxT2, minT); double newMaxT2 = interp(minT2, maxT2, maxT); split = newMaxT2 - newMinT2 > (maxT2 - minT2) * tClipLimit; - printf("%s d=%d s=%d new2=(%g,%g) old2=(%g,%g) split=%d\n", __FUNCTION__, depth, - splits, newMinT2, newMaxT2, minT2, maxT2, split); +#if VERBOSE + printf("%s d=%d s=%d new2=(%g,%g) old2=(%g,%g) split=%d\n", + __FUNCTION__, depth, splits, newMinT2, newMaxT2, minT2, maxT2, + split); +#endif minT2 = newMinT2; maxT2 = newMaxT2; } diff --git a/experimental/Intersection/CubicIntersection_Test.cpp b/experimental/Intersection/CubicIntersection_Test.cpp index 0ae1749..208fbaa 100644 --- a/experimental/Intersection/CubicIntersection_Test.cpp +++ b/experimental/Intersection/CubicIntersection_Test.cpp @@ -1,6 +1,6 @@ #include "CubicIntersection.h" #include "CubicIntersection_TestData.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" #include "Intersections.h" #include "TestUtilities.h" @@ -14,51 +14,37 @@ void CubicIntersection_Test() { int order1 = reduceOrder(cubic1, reduce1, kReduceOrder_NoQuadraticsAllowed); int order2 = reduceOrder(cubic2, reduce2, kReduceOrder_NoQuadraticsAllowed); if (order1 < 4) { - printf("[%d] cubic1 order=%d\n", (int) index, order1); + printf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1); + continue; } if (order2 < 4) { - printf("[%d] cubic2 order=%d\n", (int) index, order2); + printf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2); + continue; } - if (order1 == 4 && order2 == 4) { - Intersections tIntersections; - intersectStartT(reduce1, reduce2, tIntersections); -#ifdef COMPUTE_BY_CUBIC_SUBDIVISION - Intersections intersections; - intersectStart(reduce1, reduce2, intersections); -#endif - if (tIntersections.intersected()) { - for (int pt = 0; pt < tIntersections.used(); ++pt) { -#ifdef COMPUTE_BY_CUBIC_SUBDIVISION - double t1 = intersections.fT[0][pt]; - double x1, y1; - xy_at_t(cubic1, t1, x1, y1); - double t2 = intersections.fT[1][pt]; - double x2, y2; - xy_at_t(cubic2, t2, x2, y2); - if (!approximately_equal(x1, x2)) { - printf("%s [%d] (1) t1=%g (%g,%g) t2=%g (%g,%g)\n", - __FUNCTION__, pt, t1, x1, y1, t2, x2, y2); - } - if (!approximately_equal(y1, y2)) { - printf("%s [%d] (2) t1=%g (%g,%g) t2=%g (%g,%g)\n", - __FUNCTION__, pt, t1, x1, y1, t2, x2, y2); - } -#endif - double tt1 = tIntersections.fT[0][pt]; - double tx1, ty1; - xy_at_t(cubic1, tt1, tx1, ty1); - double tt2 = tIntersections.fT[1][pt]; - double tx2, ty2; - xy_at_t(cubic2, tt2, tx2, ty2); - if (!approximately_equal(tx1, tx2)) { - printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", - __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); - } - if (!approximately_equal(ty1, ty2)) { - printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n", - __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); - } - } + if (implicit_matches(reduce1, reduce2)) { + printf("%s [%d] coincident\n", __FUNCTION__, (int) index); + continue; + } + Intersections tIntersections; + intersectStartT(reduce1, reduce2, tIntersections); + if (!tIntersections.intersected()) { + printf("%s [%d] no intersection\n", __FUNCTION__, (int) index); + continue; + } + for (int pt = 0; pt < tIntersections.used(); ++pt) { + double tt1 = tIntersections.fT[0][pt]; + double tx1, ty1; + xy_at_t(cubic1, tt1, tx1, ty1); + double tt2 = tIntersections.fT[1][pt]; + double tx2, ty2; + xy_at_t(cubic2, tt2, tx2, ty2); + if (!approximately_equal(tx1, tx2)) { + printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + if (!approximately_equal(ty1, ty2)) { + printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); } } } diff --git a/experimental/Intersection/CubicIntersection_TestData.cpp b/experimental/Intersection/CubicIntersection_TestData.cpp index 95d44d7..05d08af 100644 --- a/experimental/Intersection/CubicIntersection_TestData.cpp +++ b/experimental/Intersection/CubicIntersection_TestData.cpp @@ -167,9 +167,6 @@ const size_t notLines_count = sizeof(notLines) / sizeof(notLines[0]); static const double E = PointEpsilon * 2; static const double F = PointEpsilon * 3; -static const double H = PointEpsilon * 4; -static const double J = PointEpsilon * 5; -static const double K = PointEpsilon * 8; // INVESTIGATE: why are larger multiples necessary? const Cubic modEpsilonLines[] = { {{0, E}, {0, 0}, {0, 0}, {1, 0}}, // horizontal @@ -305,69 +302,3 @@ const Cubic negEpsilonLines[] = { }; const size_t negEpsilonLines_count = sizeof(negEpsilonLines) / sizeof(negEpsilonLines[0]); - -const Quadratic quadraticLines[] = { - {{0, 0}, {0, 0}, {1, 0}}, - {{0, 0}, {1, 0}, {0, 0}}, - {{1, 0}, {0, 0}, {0, 0}}, - {{1, 0}, {2, 0}, {3, 0}}, - {{0, 0}, {0, 0}, {0, 1}}, - {{0, 0}, {0, 1}, {0, 0}}, - {{0, 1}, {0, 0}, {0, 0}}, - {{0, 1}, {0, 2}, {0, 3}}, - {{0, 0}, {0, 0}, {1, 1}}, - {{0, 0}, {1, 1}, {0, 0}}, - {{1, 1}, {0, 0}, {0, 0}}, - {{1, 1}, {2, 2}, {3, 3}}, - {{1, 1}, {3, 3}, {3, 3}}, - {{1, 1}, {1, 1}, {2, 2}}, - {{1, 1}, {2, 2}, {1, 1}}, - {{1, 1}, {1, 1}, {3, 3}}, - {{1, 1}, {2, 2}, {4, 4}}, // no coincident - {{1, 1}, {3, 3}, {4, 4}}, - {{1, 1}, {3, 3}, {2, 2}}, - {{1, 1}, {4, 4}, {2, 2}}, - {{1, 1}, {4, 4}, {3, 3}}, - {{2, 2}, {1, 1}, {3, 3}}, - {{2, 2}, {1, 1}, {4, 4}}, - {{2, 2}, {3, 3}, {1, 1}}, - {{2, 2}, {3, 3}, {4, 4}}, - {{2, 2}, {4, 4}, {1, 1}}, - {{2, 2}, {4, 4}, {3, 3}}, -}; - -const size_t quadraticLines_count = sizeof(quadraticLines) / sizeof(quadraticLines[0]); - -const Quadratic quadraticModEpsilonLines[] = { - {{0, F}, {0, 0}, {1, 0}}, - {{0, 0}, {1, 0}, {0, F}}, - {{1, 0}, {0, F}, {0, 0}}, - {{1, H}, {2, 0}, {3, 0}}, - {{F, 0}, {0, 0}, {0, 1}}, - {{0, 0}, {0, 1}, {F, 0}}, - {{0, 1}, {F, 0}, {0, 0}}, - {{H, 1}, {0, 2}, {0, 3}}, - {{0, F}, {0, 0}, {1, 1}}, - {{0, 0}, {1, 1}, {F, 0}}, - {{1, 1}, {F, 0}, {0, 0}}, - {{1, 1+J}, {2, 2}, {3, 3}}, - {{1, 1}, {3, 3}, {3+F, 3}}, - {{1, 1}, {1+F, 1}, {2, 2}}, - {{1, 1}, {2, 2}, {1, 1+F}}, - {{1, 1}, {1, 1+F}, {3, 3}}, - {{1+H, 1}, {2, 2}, {4, 4}}, // no coincident - {{1, 1+K}, {3, 3}, {4, 4}}, - {{1, 1}, {3+F, 3}, {2, 2}}, - {{1, 1}, {4, 4+F}, {2, 2}}, - {{1, 1}, {4, 4}, {3+F, 3}}, - {{2, 2}, {1, 1}, {3, 3+F}}, - {{2+F, 2}, {1, 1}, {4, 4}}, - {{2, 2+F}, {3, 3}, {1, 1}}, - {{2, 2}, {3+F, 3}, {4, 4}}, - {{2, 2}, {4, 4+F}, {1, 1}}, - {{2, 2}, {4, 4}, {3+F, 3}}, -}; - -const size_t quadraticModEpsilonLines_count = sizeof(quadraticModEpsilonLines) / sizeof(quadraticModEpsilonLines[0]); - - diff --git a/experimental/Intersection/CubicIntersection_TestData.h b/experimental/Intersection/CubicIntersection_TestData.h index 931a0c7..6ed0f49 100644 --- a/experimental/Intersection/CubicIntersection_TestData.h +++ b/experimental/Intersection/CubicIntersection_TestData.h @@ -12,8 +12,6 @@ extern const Cubic notLines[]; extern const Cubic modEpsilonLines[]; extern const Cubic lessEpsilonLines[]; extern const Cubic negEpsilonLines[]; -extern const Quadratic quadraticLines[]; -extern const Quadratic quadraticModEpsilonLines[]; extern const size_t pointDegenerates_count; extern const size_t notPointDegenerates_count; @@ -24,5 +22,3 @@ extern const size_t notLines_count; extern const size_t modEpsilonLines_count; extern const size_t lessEpsilonLines_count; extern const size_t negEpsilonLines_count; -extern const size_t quadraticLines_count; -extern const size_t quadraticModEpsilonLines_count; diff --git a/experimental/Intersection/CubicIntersection_Tests.cpp b/experimental/Intersection/CubicIntersection_Tests.cpp deleted file mode 100644 index 14e5821..0000000 --- a/experimental/Intersection/CubicIntersection_Tests.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "CubicIntersection_Tests.h" - -void CubicIntersection_Tests() { - // tests are in dependency order - Inline_Tests(); - ConvexHull_Test(); - ConvexHull_X_Test(); - LineParameter_Test(); - LineIntersection_Test(); - QuadraticCoincidence_Test(); - CubicCoincidence_Test(); - ReduceOrder_Test(); - // BezierClip_Test(); - CubicIntersection_Test(); -} diff --git a/experimental/Intersection/CubicIntersection_Tests.h b/experimental/Intersection/CubicIntersection_Tests.h deleted file mode 100644 index 7c85284..0000000 --- a/experimental/Intersection/CubicIntersection_Tests.h +++ /dev/null @@ -1,11 +0,0 @@ -void BezierClip_Test(); -void ConvexHull_Test(); -void ConvexHull_X_Test(); -void CubicCoincidence_Test(); -void CubicIntersection_Test(); -void CubicIntersection_Tests(); -void Inline_Tests(); -void LineIntersection_Test(); -void LineParameter_Test(); -void QuadraticCoincidence_Test(); -void ReduceOrder_Test(); 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 @@ static double (*calc_proc[])(double a, double b, double c, double d, /* 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 @@ static double (*calc_proc[])(double a, double b, double c, double d, 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 @@ static void calc_bc(const double d, double& b, double& c) { 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 @@ void tangent(const Cubic& cubic, double t, _Point& result) { result.y = tangent(&cubic[0].y, t); } +// unit test to return and validate parametric coefficients +#include "CubicParameterization_TestUtility.cpp" + + diff --git a/experimental/Intersection/CubicParameterizationCode.cpp b/experimental/Intersection/CubicParameterizationCode.cpp index 9e7a3f6..d799b15 100644 --- a/experimental/Intersection/CubicParameterizationCode.cpp +++ b/experimental/Intersection/CubicParameterizationCode.cpp @@ -4,7 +4,7 @@ * Resultant[a*t^3 + b*t^2 + c*t + d - x, e*t^3 + f*t^2 + g*t + h - y, t] */ -const char result[] = +const char result1[] = "-d^3 e^3 + c d^2 e^2 f - b d^2 e f^2 + a d^2 f^3 - c^2 d e^2 g + " " 2 b d^2 e^2 g + b c d e f g - 3 a d^2 e f g - a c d f^2 g - " " b^2 d e g^2 + 2 a c d e g^2 + a b d f g^2 - a^2 d g^3 + c^3 e^2 h - " @@ -31,7 +31,48 @@ const char result[] = " 3 a^2 d e y^2 + a b^2 f y^2 - 2 a^2 c f y^2 - a^2 b g y^2 + " " 3 a^3 h y^2 + 3 a^2 e x y^2 - a^3 y^3"; -const size_t len = sizeof(result) - 1; +const size_t len1 = sizeof(result1) - 1; + +/* Given: + * Expand[ + * Det[{{a, b, c, (d - x), 0, 0}, + * {0, a, b, c, (d - x), 0}, + * {0, 0, a, b, c, (d - x)}, + * {e, f, g, (h - y), 0, 0}, + * {0, e, f, g, (h - y), 0}, + * {0, 0, e, f, g, (h - y)}}]] + */ + // result1 and result2 are the same. 102 factors: +const char result2[] = +"-d^3 e^3 + c d^2 e^2 f - b d^2 e f^2 + a d^2 f^3 - c^2 d e^2 g + " +" 2 b d^2 e^2 g + b c d e f g - 3 a d^2 e f g - a c d f^2 g - " +" b^2 d e g^2 + 2 a c d e g^2 + a b d f g^2 - a^2 d g^3 + c^3 e^2 h - " +" 3 b c d e^2 h + 3 a d^2 e^2 h - b c^2 e f h + 2 b^2 d e f h + " +" a c d e f h + a c^2 f^2 h - 2 a b d f^2 h + b^2 c e g h - " +" 2 a c^2 e g h - a b d e g h - a b c f g h + 3 a^2 d f g h + " +" a^2 c g^2 h - b^3 e h^2 + 3 a b c e h^2 - 3 a^2 d e h^2 + " +" a b^2 f h^2 - 2 a^2 c f h^2 - a^2 b g h^2 + a^3 h^3 + 3 d^2 e^3 x - " +" 2 c d e^2 f x + 2 b d e f^2 x - 2 a d f^3 x + c^2 e^2 g x - " +" 4 b d e^2 g x - b c e f g x + 6 a d e f g x + a c f^2 g x + " +" b^2 e g^2 x - 2 a c e g^2 x - a b f g^2 x + a^2 g^3 x + " +" 3 b c e^2 h x - 6 a d e^2 h x - 2 b^2 e f h x - a c e f h x + " +" 2 a b f^2 h x + a b e g h x - 3 a^2 f g h x + 3 a^2 e h^2 x - " +" 3 d e^3 x^2 + c e^2 f x^2 - b e f^2 x^2 + a f^3 x^2 + " +" 2 b e^2 g x^2 - 3 a e f g x^2 + 3 a e^2 h x^2 + e^3 x^3 - " +" c^3 e^2 y + 3 b c d e^2 y - 3 a d^2 e^2 y + b c^2 e f y - " +" 2 b^2 d e f y - a c d e f y - a c^2 f^2 y + 2 a b d f^2 y - " +" b^2 c e g y + 2 a c^2 e g y + a b d e g y + a b c f g y - " +" 3 a^2 d f g y - a^2 c g^2 y + 2 b^3 e h y - 6 a b c e h y + " +" 6 a^2 d e h y - 2 a b^2 f h y + 4 a^2 c f h y + 2 a^2 b g h y - " +" 3 a^3 h^2 y - 3 b c e^2 x y + 6 a d e^2 x y + 2 b^2 e f x y + " +" a c e f x y - 2 a b f^2 x y - a b e g x y + 3 a^2 f g x y - " +" 6 a^2 e h x y - 3 a e^2 x^2 y - b^3 e y^2 + 3 a b c e y^2 - " +" 3 a^2 d e y^2 + a b^2 f y^2 - 2 a^2 c f y^2 - a^2 b g y^2 + " +" 3 a^3 h y^2 + 3 a^2 e x y^2 - a^3 y^3"; + + +const size_t len2 = sizeof(result2) - 1; + const int factors = 8; struct coeff { @@ -56,91 +97,93 @@ enum { typedef std::vector coeffs; typedef std::vector n_coeffs; -static char skipSpace(size_t& index) { +static char skipSpace(const char* str, size_t& index) { do { ++index; - } while (result[index] == ' '); - return result[index]; + } while (str[index] == ' '); + return str[index]; } -static char backSkipSpace(size_t& end) { - while (result[end - 1] == ' ') { +static char backSkipSpace(const char* str, size_t& end) { + while (str[end - 1] == ' ') { --end; } - return result[end - 1]; + return str[end - 1]; } -static void match(coeffs& co, const char pattern[]) { +static void match(const char* str, size_t len, coeffs& co, const char pattern[]) { size_t patternLen = strlen(pattern); size_t index = 0; while (index < len) { - char ch = result[index]; + char ch = str[index]; if (ch != '-' && ch != '+') { printf("missing sign\n"); } size_t end = index + 1; - while (result[end] != '+' && result[end] != '-' && ++end < len) { + while (str[end] != '+' && str[end] != '-' && ++end < len) { ; } - backSkipSpace(end); + backSkipSpace(str, end); size_t idx = index; index = end; - skipSpace(index); - if (!strncmp(&result[end - patternLen], pattern, patternLen) == 0) { + skipSpace(str, index); + if (!strncmp(&str[end - patternLen], pattern, patternLen) == 0) { continue; } size_t endCoeff = end - patternLen; - char last = backSkipSpace(endCoeff); + char last = backSkipSpace(str, endCoeff); if (last == '2' || last == '3') { - last = result[endCoeff - 3]; // skip ^2 + last = str[endCoeff - 3]; // skip ^2 } if (last == 'x' || last == 'y') { continue; } coeff c; - c.s = result[idx] == '-' ? -1 : 1; + c.s = str[idx] == '-' ? -1 : 1; bzero(c.n, sizeof(c.n)); - ch = skipSpace(idx); + ch = skipSpace(str, idx); if (ch >= '2' && ch <= '6') { c.s *= ch - '0'; - ch = skipSpace(idx); + ch = skipSpace(str, idx); } while (idx < endCoeff) { - char x = result[idx]; + char x = str[idx]; if (x < 'a' || x > 'a' + factors) { printf("expected factor\n"); } idx++; int pow = 1; - if (result[idx] == '^') { + if (str[idx] == '^') { idx++; - char exp = result[idx]; + char exp = str[idx]; if (exp < '2' || exp > '3') { printf("expected exponent\n"); } pow = exp - '0'; } - skipSpace(idx); + skipSpace(str, idx); c.n[x - 'a'] = pow; } co.push_back(c); } } -void cubecode_test(); +void cubecode_test(int test); -void cubecode_test() { +void cubecode_test(int test) { + const char* str = test ? result2 : result1; + size_t len = strlen(str); n_coeffs c(coeff_count); - match(c[xxx_coeff], "x^3"); // 1 factor - match(c[xxy_coeff], "x^2 y"); // 1 factor - match(c[xyy_coeff], "x y^2"); // 1 factor - match(c[yyy_coeff], "y^3"); // 1 factor - match(c[xx_coeff], "x^2"); // 7 factors - match(c[xy_coeff], "x y"); // 8 factors - match(c[yy_coeff], "y^2"); // 7 factors - match(c[x_coeff], "x"); // 21 factors - match(c[y_coeff], "y"); // 21 factors - match(c[c_coeff], ""); // 34 factors + match(str, len, c[xxx_coeff], "x^3"); // 1 factor + match(str, len, c[xxy_coeff], "x^2 y"); // 1 factor + match(str, len, c[xyy_coeff], "x y^2"); // 1 factor + match(str, len, c[yyy_coeff], "y^3"); // 1 factor + match(str, len, c[xx_coeff], "x^2"); // 7 factors + match(str, len, c[xy_coeff], "x y"); // 8 factors + match(str, len, c[yy_coeff], "y^2"); // 7 factors + match(str, len, c[x_coeff], "x"); // 21 factors + match(str, len, c[y_coeff], "y"); // 21 factors + match(str, len, c[c_coeff], ""); // 34 factors : total 102 #define COMPUTE_MOST_FREQUENT_EXPRESSION_TRIPLETS 0 #define WRITE_AS_NONOPTIMIZED_C_CODE 0 #if COMPUTE_MOST_FREQUENT_EXPRESSION_TRIPLETS diff --git a/experimental/Intersection/CubicParameterization_Test.cpp b/experimental/Intersection/CubicParameterization_Test.cpp index 9bb2253..18322c8 100644 --- a/experimental/Intersection/CubicParameterization_Test.cpp +++ b/experimental/Intersection/CubicParameterization_Test.cpp @@ -1,5 +1,5 @@ #include "CubicIntersection.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" #include "TestUtilities.h" const Quadratic quadratics[] = { @@ -42,3 +42,61 @@ void CubicCoincidence_Test() { } } } + +// pairs of coincident cubics +// The on curve points of each cubic should be on both parameterized cubics. +const Cubic cubics[] = { + { + {1, -1}, + {.333, 1}, + {-.333, -1}, + {-1, 1} + }, + { + {-1, 1}, + {-.333, -1}, + {.333, 1}, + {1, -1} + }, + { + {0, 2}, + {0, 1}, + {1, 0}, + {2, 0} + }, { + {2, 0}, + {1, 0}, + {0, 1}, + {0, 2} + }, + { + {315.74799999999999, 312.83999999999997}, + {312.64400000000001, 318.13400000000001}, + {305.83600000000001, 319.90899999999999}, + {300.54199999999997, 316.80399999999997} + }, { + {317.12200000000001, 309.05000000000001}, + {316.11200000000002, 315.10199999999998}, + {310.38499999999999, 319.19}, + {304.33199999999999, 318.17899999999997} + } +}; + +const size_t cubics_count = sizeof(cubics) / sizeof(cubics[0]); + +int firstCubicParameterizationTest = 0; + +void CubicParameterization_Test() { + for (size_t index = firstCubicParameterizationTest; index < cubics_count; ++index) { + for (size_t inner = 0; inner < 4; inner += 3) { + if (!point_on_parameterized_curve(cubics[index], cubics[index][inner])) { + printf("%s [%zu,%zu] 1 parameterization failed\n", + __FUNCTION__, index, inner); + } + if (!point_on_parameterized_curve(cubics[index], cubics[index ^ 1][inner])) { + printf("%s [%zu,%zu] 2 parameterization failed\n", + __FUNCTION__, index, inner); + } + } + } +} diff --git a/experimental/Intersection/CubicParameterization_TestUtility.cpp b/experimental/Intersection/CubicParameterization_TestUtility.cpp new file mode 100644 index 0000000..2423a7c --- /dev/null +++ b/experimental/Intersection/CubicParameterization_TestUtility.cpp @@ -0,0 +1,39 @@ +// included by CubicParameterization.cpp +// accesses internal functions to validate parameterized coefficients + +static void parameter_coeffs(const Cubic& cubic, double coeffs[coeff_count]) { + double ax, bx, cx, dx; + if (try_alt) + alt_set_abcd(&cubic[0].x, ax, bx, cx, dx); + else + set_abcd(&cubic[0].x, ax, bx, cx, dx); + double ay, by, cy, dy; + if (try_alt) + alt_set_abcd(&cubic[0].y, ay, by, cy, dy); + else + set_abcd(&cubic[0].y, ay, by, cy, dy); + calc_ABCD(ax, ay, coeffs); + if (!try_alt) calc_bc(dx, bx, cx); + if (!try_alt) calc_bc(dy, by, cy); + for (int index = xx_coeff; index < coeff_count; ++index) { + int procIndex = index - xx_coeff; + coeffs[index] = (*calc_proc[procIndex])(ax, bx, cx, dx, ay, by, cy, dy); + } +} + +bool point_on_parameterized_curve(const Cubic& cubic, const _Point& point) { + double coeffs[coeff_count]; + parameter_coeffs(cubic, coeffs); + double xxx = coeffs[xxx_coeff] * point.x * point.x * point.x; + double xxy = coeffs[xxy_coeff] * point.x * point.x * point.y; + double xyy = coeffs[xyy_coeff] * point.x * point.y * point.y; + double yyy = coeffs[yyy_coeff] * point.y * point.y * point.y; + double xx = coeffs[ xx_coeff] * point.x * point.x; + double xy = coeffs[ xy_coeff] * point.x * point.y; + double yy = coeffs[ yy_coeff] * point.y * point.y; + double x = coeffs[ x_coeff] * point.x; + double y = coeffs[ y_coeff] * point.y; + double c = coeffs[ c_coeff]; + double sum = xxx + xxy + xyy + yyy + xx + xy + yy + x + y + c; + return approximately_zero(sum); +} diff --git a/experimental/Intersection/CubicReduceOrder_Test.cpp b/experimental/Intersection/CubicReduceOrder_Test.cpp new file mode 100644 index 0000000..1957ba1 --- /dev/null +++ b/experimental/Intersection/CubicReduceOrder_Test.cpp @@ -0,0 +1,138 @@ +#include "CubicIntersection.h" +#include "CubicIntersection_TestData.h" +#include "Intersection_Tests.h" +#include "QuadraticIntersection_TestData.h" +#include "TestUtilities.h" + +void CubicReduceOrder_Test() { + size_t index; + Cubic reduce; + int order; + enum { + RunAll, + RunPointDegenerates, + RunNotPointDegenerates, + RunLines, + RunNotLines, + RunModEpsilonLines, + RunLessEpsilonLines, + RunNegEpsilonLines, + RunQuadraticLines, + RunQuadraticModLines, + RunComputedLines, + RunNone + } run = RunAll; + int firstTestIndex = 0; +#if 0 + run = RunComputedLines; + firstTestIndex = 18; +#endif + int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : INT_MAX; + int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : INT_MAX; + int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : INT_MAX; + int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : INT_MAX; + int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : INT_MAX; + int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : INT_MAX; + int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : INT_MAX; + int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX; + int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX; + int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : INT_MAX; + + for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) { + const Cubic& cubic = pointDegenerates[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 1) { + printf("[%d] pointDegenerates order=%d\n", (int) index, order); + } + } + for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) { + const Cubic& cubic = notPointDegenerates[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order == 1) { + printf("[%d] notPointDegenerates order=%d\n", (int) index, order); + } + } + for (index = firstLinesTest; index < lines_count; ++index) { + const Cubic& cubic = lines[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 2) { + printf("[%d] lines order=%d\n", (int) index, order); + } + } + for (index = firstNotLinesTest; index < notLines_count; ++index) { + const Cubic& cubic = notLines[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order == 2) { + printf("[%d] notLines order=%d\n", (int) index, order); + } + } + for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) { + const Cubic& cubic = modEpsilonLines[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order == 2) { + printf("[%d] line mod by epsilon order=%d\n", (int) index, order); + } + } + for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) { + const Cubic& cubic = lessEpsilonLines[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 2) { + printf("[%d] line less by epsilon/2 order=%d\n", (int) index, order); + } + } + for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) { + const Cubic& cubic = negEpsilonLines[index]; + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 2) { + printf("[%d] line neg by epsilon/2 order=%d\n", (int) index, order); + } + } + for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) { + const Quadratic& quad = quadraticLines[index]; + Cubic cubic; + quad_to_cubic(quad, cubic); + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 2) { + printf("[%d] line quad order=%d\n", (int) index, order); + } + } + for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) { + const Quadratic& quad = quadraticModEpsilonLines[index]; + Cubic cubic; + quad_to_cubic(quad, cubic); + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (order != 3) { + printf("[%d] line mod quad order=%d\n", (int) index, order); + } + } + + // test if computed line end points are valid + for (index = firstComputedLinesTest; index < lines_count; ++index) { + const Cubic& cubic = lines[index]; + bool controlsInside = controls_inside(cubic); + order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed); + if (reduce[0].x == reduce[1].x && reduce[0].y == reduce[1].y) { + printf("[%d] line computed ends match order=%d\n", (int) index, order); + } + if (controlsInside) { + if ( reduce[0].x != cubic[0].x && reduce[0].x != cubic[3].x + || reduce[0].y != cubic[0].y && reduce[0].y != cubic[3].y + || reduce[1].x != cubic[0].x && reduce[1].x != cubic[3].x + || reduce[1].y != cubic[0].y && reduce[1].y != cubic[3].y) { + printf("[%d] line computed ends order=%d\n", (int) index, order); + } + } else { + // binary search for extrema, compare against actual results + // while a control point is outside of bounding box formed by end points, split + _Rect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}; + find_tight_bounds(cubic, bounds); + if ( !approximately_equal(reduce[0].x, bounds.left) && !approximately_equal(reduce[0].x, bounds.right) + || !approximately_equal(reduce[0].y, bounds.top) && !approximately_equal(reduce[0].y, bounds.bottom) + || !approximately_equal(reduce[1].x, bounds.left) && !approximately_equal(reduce[1].x, bounds.right) + || !approximately_equal(reduce[1].y, bounds.top) && !approximately_equal(reduce[1].y, bounds.bottom)) { + printf("[%d] line computed tight bounds order=%d\n", (int) index, order); + } + + } + } +} diff --git a/experimental/Intersection/CubicRoots.cpp b/experimental/Intersection/CubicRoots.cpp index a3da700..f776c2d 100644 --- a/experimental/Intersection/CubicRoots.cpp +++ b/experimental/Intersection/CubicRoots.cpp @@ -1,40 +1,32 @@ -#include "CubicIntersection.h" - -//http://planetmath.org/encyclopedia/CubicEquation.html -/* the roots of x^3 + ax^2 + bx + c are -j = -2a^3 + 9ab - 27c -k = sqrt((2a^3 - 9ab + 27c)^2 + 4(-a^2 + 3b)^3) -t1 = -a/3 + cuberoot((j + k) / 54) + cuberoot((j - k) / 54) -t2 = -a/3 - ( 1 + i*cuberoot(3))/2 * cuberoot((j + k) / 54) - + (-1 + i*cuberoot(3))/2 * cuberoot((j - k) / 54) -t3 = -a/3 + (-1 + i*cuberoot(3))/2 * cuberoot((j + k) / 54) - - ( 1 + i*cuberoot(3))/2 * cuberoot((j - k) / 54) -*/ +#include "CubicUtilities.h" +#include "DataTypes.h" +#include "QuadraticUtilities.h" +const double PI = 4 * atan(1); static bool is_unit_interval(double x) { return x > 0 && x < 1; } -const double PI = 4 * atan(1); - -// from SkGeometry.cpp -int cubic_roots(const double coeff[4], double tValues[3]) { - if (approximately_zero(coeff[0])) // we're just a quadratic +// from SkGeometry.cpp (and Numeric Solutions, 5.6) +int cubicRoots(double A, double B, double C, double D, double t[3]) { + if (approximately_zero(A)) { // we're just a quadratic + return quadraticRoots(B, C, D, t); + } + double a, b, c; { - return quadratic_roots(&coeff[1], tValues); + double invA = 1 / A; + a = B * invA; + b = C * invA; + c = D * invA; } - double inva = 1 / coeff[0]; - double a = coeff[1] * inva; - double b = coeff[2] * inva; - double c = coeff[3] * inva; double a2 = a * a; double Q = (a2 - b * 3) / 9; double R = (2 * a2 * a - 9 * a * b + 27 * c) / 54; double Q3 = Q * Q * Q; double R2MinusQ3 = R * R - Q3; double adiv3 = a / 3; - double* roots = tValues; + double* roots = t; double r; if (R2MinusQ3 < 0) // we have 3 real roots @@ -68,5 +60,5 @@ int cubic_roots(const double coeff[4], double tValues[3]) { if (is_unit_interval(r)) *roots++ = r; } - return (int)(roots - tValues); + return (int)(roots - t); } diff --git a/experimental/Intersection/CubicUtilities.h b/experimental/Intersection/CubicUtilities.h new file mode 100644 index 0000000..db887a5 --- /dev/null +++ b/experimental/Intersection/CubicUtilities.h @@ -0,0 +1,2 @@ +double cube_root(double x); +int cubicRoots(double A, double B, double C, double D, double t[3]); diff --git a/experimental/Intersection/EdgeApp.cpp b/experimental/Intersection/EdgeApp.cpp index 58ff153..9bf419d 100644 --- a/experimental/Intersection/EdgeApp.cpp +++ b/experimental/Intersection/EdgeApp.cpp @@ -20,8 +20,7 @@ #include "SkTouchGesture.h" #include "SkTypeface.h" -#include "CubicIntersection_Tests.h" -#include "CubicIntersection_TestData.h" +#include "Intersection_Tests.h" extern void CreateSweep(SkBitmap* , float width); extern void CreateHorz(SkBitmap* ); @@ -162,16 +161,11 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { return new EdgeWindow(hwnd); } -void cubecode_test(); - void application_init() { - unsigned foo = 4; SkGraphics::Init(); SkEvent::Init(); - cubecode_test(); - convert_testx(); - CubicIntersection_Tests(); + Intersection_Tests(); SkAntiEdge_Test(); } diff --git a/experimental/Intersection/Inline_Tests.cpp b/experimental/Intersection/Inline_Tests.cpp index 59caf30..d8b0e49 100644 --- a/experimental/Intersection/Inline_Tests.cpp +++ b/experimental/Intersection/Inline_Tests.cpp @@ -1,5 +1,5 @@ #include "CubicIntersection.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" #include "IntersectionUtilities.h" static void assert_that(int x, int y, const char* s) { diff --git a/experimental/Intersection/Intersection_Tests.cpp b/experimental/Intersection/Intersection_Tests.cpp new file mode 100644 index 0000000..e213de4 --- /dev/null +++ b/experimental/Intersection/Intersection_Tests.cpp @@ -0,0 +1,29 @@ +#include "CubicIntersection_TestData.h" +#include "Intersection_Tests.h" + +void cubecode_test(int test); + +void Intersection_Tests() { + cubecode_test(1); + convert_testx(); + // tests are in dependency / complexity order + Inline_Tests(); + ConvexHull_Test(); + ConvexHull_X_Test(); + + LineParameter_Test(); + LineIntersection_Test(); + LineQuadraticIntersection_Test(); + LineCubicIntersection_Test(); + + QuadraticCoincidence_Test(); + QuadraticReduceOrder_Test(); + QuadraticBezierClip_Test(); + QuadraticIntersection_Test(); + + CubicParameterization_Test(); + CubicCoincidence_Test(); + CubicReduceOrder_Test(); + CubicBezierClip_Test(); + CubicIntersection_Test(); +} diff --git a/experimental/Intersection/Intersection_Tests.h b/experimental/Intersection/Intersection_Tests.h new file mode 100644 index 0000000..deb08ca --- /dev/null +++ b/experimental/Intersection/Intersection_Tests.h @@ -0,0 +1,18 @@ +void ConvexHull_Test(); +void ConvexHull_X_Test(); +void CubicBezierClip_Test(); +void CubicCoincidence_Test(); +void CubicIntersection_Test(); +void CubicParameterization_Test(); +void CubicReduceOrder_Test(); +void Inline_Tests(); +void Intersection_Tests(); +void LineCubicIntersection_Test(); +void LineIntersection_Test(); +void LineParameter_Test(); +void LineQuadraticIntersection_Test(); +void QuadraticBezierClip_Test(); +void QuadraticCoincidence_Test(); +void QuadraticIntersection_Test(); +void QuadraticParameterization_Test(); +void QuadraticReduceOrder_Test(); diff --git a/experimental/Intersection/LineCubicIntersection.cpp b/experimental/Intersection/LineCubicIntersection.cpp new file mode 100644 index 0000000..f37507b --- /dev/null +++ b/experimental/Intersection/LineCubicIntersection.cpp @@ -0,0 +1,139 @@ +#include "CubicIntersection.h" +#include "CubicUtilities.h" +#include "Intersections.h" +#include "LineUtilities.h" + +/* +Find the interection of a line and cubic by solving for valid t values. + +Analogous to line-quadratic intersection, solve line-cubic intersection by +representing the cubic as: + x = a(1-t)^3 + 2b(1-t)^2t + c(1-t)t^2 + dt^3 + y = e(1-t)^3 + 2f(1-t)^2t + g(1-t)t^2 + ht^3 +and the line as: + y = i*x + j (if the line is more horizontal) +or: + x = i*y + j (if the line is more vertical) + +Then using Mathematica, solve for the values of t where the cubic intersects the +line: + + (in) Resultant[ + a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - x, + e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - i*x - j, x] + (out) -e + j + + 3 e t - 3 f t - + 3 e t^2 + 6 f t^2 - 3 g t^2 + + e t^3 - 3 f t^3 + 3 g t^3 - h t^3 + + i ( a - + 3 a t + 3 b t + + 3 a t^2 - 6 b t^2 + 3 c t^2 - + a t^3 + 3 b t^3 - 3 c t^3 + d t^3 ) + +if i goes to infinity, we can rewrite the line in terms of x. Mathematica: + + (in) Resultant[ + a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - i*y - j, + e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - y, y] + (out) a - j - + 3 a t + 3 b t + + 3 a t^2 - 6 b t^2 + 3 c t^2 - + a t^3 + 3 b t^3 - 3 c t^3 + d t^3 - + i ( e - + 3 e t + 3 f t + + 3 e t^2 - 6 f t^2 + 3 g t^2 - + e t^3 + 3 f t^3 - 3 g t^3 + h t^3 ) + +Solving this with Mathematica produces an expression with hundreds of terms; +instead, use Numeric Solutions recipe to solve the cubic. + +The near-horizontal case, in terms of: Ax^3 + Bx^2 + Cx + D == 0 + A = (-(-e + 3*f - 3*g + h) + i*(-a + 3*b - 3*c + d) ) + B = 3*(-( e - 2*f + g ) + i*( a - 2*b + c ) ) + C = 3*(-(-e + f ) + i*(-a + b ) ) + D = (-( e ) + i*( a ) + j ) + +The near-vertical case, in terms of: Ax^3 + Bx^2 + Cx + D == 0 + A = ( (-a + 3*b - 3*c + d) - i*(-e + 3*f - 3*g + h) ) + B = 3*( ( a - 2*b + c ) - i*( e - 2*f + g ) ) + C = 3*( (-a + b ) - i*(-e + f ) ) + D = ( ( a ) - i*( e ) - j ) + */ + +class LineCubicIntersections : public Intersections { +public: + +LineCubicIntersections(const Cubic& c, const _Line& l, Intersections& i) + : cubic(c) + , line(l) + , intersections(i) { +} + +bool intersect() { + double slope; + double axisIntercept; + moreHorizontal = implicitLine(line, slope, axisIntercept); + double A = cubic[3].x; // d + double B = cubic[2].x * 3; // 3*c + double C = cubic[1].x * 3; // 3*b + double D = cubic[0].x; // a + A -= D - C + B; // A = -a + 3*b - 3*c + d + B += 3 * D - 2 * C; // B = 3*a - 6*b + 3*c + C -= 3 * D; // C = -3*a + 3*b + double E = cubic[3].y; // h + double F = cubic[2].y * 3; // 3*g + double G = cubic[1].y * 3; // 3*f + double H = cubic[0].y; // e + E -= H - G + F; // E = -e + 3*f - 3*g + h + F += 3 * H - 2 * G; // F = 3*e - 6*f + 3*g + G -= 3 * H; // G = -3*e + 3*f + if (moreHorizontal) { + A = A * slope - E; + B = B * slope - F; + C = C * slope - G; + D = D * slope - H + axisIntercept; + } else { + A = A - E * slope; + B = B - F * slope; + C = C - G * slope; + D = D - H * slope - axisIntercept; + } + double t[3]; + int roots = cubicRoots(A, B, C, D, t); + for (int x = 0; x < roots; ++x) { + intersections.add(t[x], findLineT(t[x])); + } + return roots > 0; +} + +protected: + +double findLineT(double t) { + const double* cPtr; + const double* lPtr; + if (moreHorizontal) { + cPtr = &cubic[0].x; + lPtr = &line[0].x; + } else { + cPtr = &cubic[0].y; + lPtr = &line[0].y; + } + double s = 1 - t; + double cubicVal = cPtr[0] * s * s * s + 3 * cPtr[2] * s * s * t + + 3 * cPtr[4] * s * t * t + cPtr[6] * t * t * t; + return (cubicVal - lPtr[0]) / (lPtr[2] - lPtr[0]); +} + +private: + +const Cubic& cubic; +const _Line& line; +Intersections& intersections; +bool moreHorizontal; + +}; + +bool intersectStart(const Cubic& cubic, const _Line& line, Intersections& i) { + LineCubicIntersections c(cubic, line, i); + return c.intersect(); +} diff --git a/experimental/Intersection/LineCubicIntersection_Test.cpp b/experimental/Intersection/LineCubicIntersection_Test.cpp new file mode 100644 index 0000000..3f2c622 --- /dev/null +++ b/experimental/Intersection/LineCubicIntersection_Test.cpp @@ -0,0 +1,55 @@ +#include "CubicIntersection.h" +#include "Intersection_Tests.h" +#include "Intersections.h" +#include "LineUtilities.h" +#include "TestUtilities.h" + +struct lineCubic { + Cubic cubic; + _Line line; +} lineCubicTests[] = { + {{{0, 0}, {0, 1}, {0, 1}, {1, 1}}, {{0, 1}, {1, 0}}} +}; + +size_t lineCubicTests_count = sizeof(lineCubicTests) / sizeof(lineCubicTests[0]); + +const int firstLineCubicIntersectionTest = 0; + +void LineCubicIntersection_Test() { + for (size_t index = firstLineCubicIntersectionTest; index < lineCubicTests_count; ++index) { + const Cubic& cubic = lineCubicTests[index].cubic; + const _Line& line = lineCubicTests[index].line; + Cubic reduce1; + _Line reduce2; + int order1 = reduceOrder(cubic, reduce1, kReduceOrder_NoQuadraticsAllowed); + int order2 = reduceOrder(line, reduce2); + if (order1 < 4) { + printf("[%d] cubic order=%d\n", (int) index, order1); + } + if (order2 < 2) { + printf("[%d] line order=%d\n", (int) index, order2); + } + if (order1 == 4 && order2 == 2) { + Intersections intersections; + intersectStart(reduce1, reduce2, intersections); + if (intersections.intersected()) { + for (int pt = 0; pt < intersections.used(); ++pt) { + double tt1 = intersections.fT[0][pt]; + double tx1, ty1; + xy_at_t(cubic, tt1, tx1, ty1); + double tt2 = intersections.fT[1][pt]; + double tx2, ty2; + xy_at_t(line, tt2, tx2, ty2); + if (!approximately_equal(tx1, tx2)) { + printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + if (!approximately_equal(ty1, ty2)) { + printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + } + } + } + } +} diff --git a/experimental/Intersection/LineIntersection.cpp b/experimental/Intersection/LineIntersection.cpp index d23401e..c9bc616 100644 --- a/experimental/Intersection/LineIntersection.cpp +++ b/experimental/Intersection/LineIntersection.cpp @@ -65,6 +65,8 @@ bool lineIntersect(const _Line& a, const _Line& b, _Point* result) { return no_intersection(result); } /* Are the line coincident? See if they overlap */ + // FIXME: allow returning range of coincidence, instead of or in + // addition to midpoint paramsA.lineEndPoints(a); double b0dist = paramsA.pointDistance(b[0]); bool b0on = approximately_zero_squared(b0dist); diff --git a/experimental/Intersection/LineIntersection_Test.cpp b/experimental/Intersection/LineIntersection_Test.cpp index f7d00b5..2af74d2 100644 --- a/experimental/Intersection/LineIntersection_Test.cpp +++ b/experimental/Intersection/LineIntersection_Test.cpp @@ -1,6 +1,7 @@ #include "CubicIntersection_Tests.h" #include "LineIntersection.h" +// FIXME: add tests for intersecting, non-intersecting, degenerate, coincident const _Line tests[][2] = { {{{166.86950047022856, 112.69654129527828}, {166.86948801592692, 112.69655741235339}}, {{166.86960700313026, 112.6965477747386}, {166.86925794355412, 112.69656471103423}}}, @@ -16,6 +17,9 @@ void LineIntersection_Test() { const _Line& line2 = tests[index][1]; _Point result; lineIntersect(line1, line2, &result); - printf("%s (%g,%g)\n", __FUNCTION__, result.x, result.y); + // FIXME: validate results + // see if result is between start and end of both lines + // see if result is on both lines + // printf("%s (%g,%g)\n", __FUNCTION__, result.x, result.y); } } diff --git a/experimental/Intersection/LineQuadraticIntersection.cpp b/experimental/Intersection/LineQuadraticIntersection.cpp new file mode 100644 index 0000000..02810ac --- /dev/null +++ b/experimental/Intersection/LineQuadraticIntersection.cpp @@ -0,0 +1,163 @@ +#include "CubicIntersection.h" +#include "Intersections.h" +#include "LineUtilities.h" +#include "QuadraticUtilities.h" + +/* +Find the interection of a line and quadratic by solving for valid t values. + +From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-function-defining-a-bezier-curve + +"A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three +control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where +A, B and C are points and t goes from zero to one. + +This will give you two equations: + + x = a(1 - t)^2 + b(1 - t)t + ct^2 + y = d(1 - t)^2 + e(1 - t)t + ft^2 + +If you add for instance the line equation (y = kx + m) to that, you'll end up +with three equations and three unknowns (x, y and t)." + +Similar to above, the quadratic is represented as + x = a(1-t)^2 + 2b(1-t)t + ct^2 + y = d(1-t)^2 + 2e(1-t)t + ft^2 +and the line as + y = g*x + h + +Using Mathematica, solve for the values of t where the quadratic intersects the +line: + + (in) t1 = Resultant[a*(1 - t)^2 + 2*b*(1 - t)*t + c*t^2 - x, + d*(1 - t)^2 + 2*e*(1 - t)*t + f*t^2 - g*x - h, x] + (out) -d + h + 2 d t - 2 e t - d t^2 + 2 e t^2 - f t^2 + + g (a - 2 a t + 2 b t + a t^2 - 2 b t^2 + c t^2) + (in) Solve[t1 == 0, t] + (out) { + {t -> (-2 d + 2 e + 2 a g - 2 b g - + Sqrt[(2 d - 2 e - 2 a g + 2 b g)^2 - + 4 (-d + 2 e - f + a g - 2 b g + c g) (-d + a g + h)]) / + (2 (-d + 2 e - f + a g - 2 b g + c g)) + }, + {t -> (-2 d + 2 e + 2 a g - 2 b g + + Sqrt[(2 d - 2 e - 2 a g + 2 b g)^2 - + 4 (-d + 2 e - f + a g - 2 b g + c g) (-d + a g + h)]) / + (2 (-d + 2 e - f + a g - 2 b g + c g)) + } + } + +Numeric Solutions (5.6) suggests to solve the quadratic by computing + + Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C)) + +and using the roots + + t1 = Q / A + t2 = C / Q + +Using the results above (when the line tends towards horizontal) + A = (-(d - 2*e + f) + g*(a - 2*b + c) ) + B = 2*( (d - e ) - g*(a - b ) ) + C = (-(d ) + g*(a ) + h ) + +If g goes to infinity, we can rewrite the line in terms of x. + x = g'*y + h' + +And solve accordingly in Mathematica: + + (in) t2 = Resultant[a*(1 - t)^2 + 2*b*(1 - t)*t + c*t^2 - g'*y - h', + d*(1 - t)^2 + 2*e*(1 - t)*t + f*t^2 - y, y] + (out) a - h' - 2 a t + 2 b t + a t^2 - 2 b t^2 + c t^2 - + g' (d - 2 d t + 2 e t + d t^2 - 2 e t^2 + f t^2) + (in) Solve[t2 == 0, t] + (out) { + {t -> (2 a - 2 b - 2 d g' + 2 e g' - + Sqrt[(-2 a + 2 b + 2 d g' - 2 e g')^2 - + 4 (a - 2 b + c - d g' + 2 e g' - f g') (a - d g' - h')]) / + (2 (a - 2 b + c - d g' + 2 e g' - f g')) + }, + {t -> (2 a - 2 b - 2 d g' + 2 e g' + + Sqrt[(-2 a + 2 b + 2 d g' - 2 e g')^2 - + 4 (a - 2 b + c - d g' + 2 e g' - f g') (a - d g' - h')])/ + (2 (a - 2 b + c - d g' + 2 e g' - f g')) + } + } + +Thus, if the slope of the line tends towards vertical, we use: + A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) + B = 2*(-(a - b ) + g'*(d - e ) ) + C = ( (a ) - g'*(d ) - h' ) + */ + + +class LineQuadraticIntersections : public Intersections { +public: + +LineQuadraticIntersections(const Quadratic& q, const _Line& l, Intersections& i) + : quad(q) + , line(l) + , intersections(i) { +} + +bool intersect() { + double slope; + double axisIntercept; + moreHorizontal = implicitLine(line, slope, axisIntercept); + double A = quad[2].x; // c + double B = quad[1].x; // b + double C = quad[0].x; // a + A += C - 2 * B; // A = a - 2*b + c + B -= C; // B = -(a - b) + double D = quad[2].y; // f + double E = quad[1].y; // e + double F = quad[0].y; // d + D += F - 2 * E; // D = d - 2*e + f + E -= F; // E = -(d - e) + if (moreHorizontal) { + A = A * slope - D; + B = B * slope - E; + C = C * slope - F + axisIntercept; + } else { + A = A - D * slope; + B = B - E * slope; + C = C - F * slope - axisIntercept; + } + double t[2]; + int roots = quadraticRoots(A, B, C, t); + for (int x = 0; x < roots; ++x) { + intersections.add(t[x], findLineT(t[x])); + } + return roots > 0; +} + +protected: + +double findLineT(double t) { + const double* qPtr; + const double* lPtr; + if (moreHorizontal) { + qPtr = &quad[0].x; + lPtr = &line[0].x; + } else { + qPtr = &quad[0].y; + lPtr = &line[0].y; + } + double s = 1 - t; + double quadVal = qPtr[0] * s * s + 2 * qPtr[2] * s * t + qPtr[4] * t * t; + return (quadVal - lPtr[0]) / (lPtr[2] - lPtr[0]); +} + +private: + +const Quadratic& quad; +const _Line& line; +Intersections& intersections; +bool moreHorizontal; + +}; + +bool intersectStart(const Quadratic& quad, const _Line& line, Intersections& i) { + LineQuadraticIntersections q(quad, line, i); + return q.intersect(); +} diff --git a/experimental/Intersection/LineQuadraticIntersection_Test.cpp b/experimental/Intersection/LineQuadraticIntersection_Test.cpp new file mode 100644 index 0000000..aa1094f --- /dev/null +++ b/experimental/Intersection/LineQuadraticIntersection_Test.cpp @@ -0,0 +1,55 @@ +#include "CubicIntersection.h" +#include "Intersection_Tests.h" +#include "Intersections.h" +#include "LineUtilities.h" +#include "TestUtilities.h" + +struct lineQuad { + Quadratic quad; + _Line line; +} lineQuadTests[] = { + {{{0, 0}, {0, 1}, {1, 1}}, {{0, 1}, {1, 0}}} +}; + +size_t lineQuadTests_count = sizeof(lineQuadTests) / sizeof(lineQuadTests[0]); + +const int firstLineQuadIntersectionTest = 0; + +void LineQuadraticIntersection_Test() { + for (size_t index = firstLineQuadIntersectionTest; index < lineQuadTests_count; ++index) { + const Quadratic& quad = lineQuadTests[index].quad; + const _Line& line = lineQuadTests[index].line; + Quadratic reduce1; + _Line reduce2; + int order1 = reduceOrder(quad, reduce1); + int order2 = reduceOrder(line, reduce2); + if (order1 < 3) { + printf("[%d] quad order=%d\n", (int) index, order1); + } + if (order2 < 2) { + printf("[%d] line order=%d\n", (int) index, order2); + } + if (order1 == 3 && order2 == 2) { + Intersections intersections; + intersectStart(reduce1, reduce2, intersections); + if (intersections.intersected()) { + for (int pt = 0; pt < intersections.used(); ++pt) { + double tt1 = intersections.fT[0][pt]; + double tx1, ty1; + xy_at_t(quad, tt1, tx1, ty1); + double tt2 = intersections.fT[1][pt]; + double tx2, ty2; + xy_at_t(line, tt2, tx2, ty2); + if (!approximately_equal(tx1, tx2)) { + printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + if (!approximately_equal(ty1, ty2)) { + printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + } + } + } + } +} diff --git a/experimental/Intersection/LineUtilities.cpp b/experimental/Intersection/LineUtilities.cpp new file mode 100644 index 0000000..9f782b1 --- /dev/null +++ b/experimental/Intersection/LineUtilities.cpp @@ -0,0 +1,22 @@ +#include "LineUtilities.h" + +bool implicitLine(const _Line& line, double& slope, double& axisIntercept) { + double lineDx = line[1].x - line[0].x; + double lineDy = line[1].y - line[0].y; + bool moreHorizontal = fabs(lineDx) > fabs(lineDy); + if (moreHorizontal) { + slope = lineDy / lineDx; + axisIntercept = line[0].y - slope * line[0].x; + } else { + slope = lineDx / lineDy; + axisIntercept = line[0].x - slope * line[0].y; + } + return moreHorizontal; +} + +int reduceOrder(const _Line& line, _Line& reduced) { + reduced[0] = line[0]; + int different = line[0] != line[1]; + reduced[1] = line[different]; + return 1 + different; +} diff --git a/experimental/Intersection/LineUtilities.h b/experimental/Intersection/LineUtilities.h new file mode 100644 index 0000000..4dafc9f --- /dev/null +++ b/experimental/Intersection/LineUtilities.h @@ -0,0 +1,4 @@ +#include "DataTypes.h" + +bool implicitLine(const _Line& line, double& slope, double& axisIntercept); +int reduceOrder(const _Line& line, _Line& reduced); diff --git a/experimental/Intersection/QuadraticBezierClip.cpp b/experimental/Intersection/QuadraticBezierClip.cpp index 1114d74..fc3acfe 100644 --- a/experimental/Intersection/QuadraticBezierClip.cpp +++ b/experimental/Intersection/QuadraticBezierClip.cpp @@ -48,10 +48,14 @@ bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double& maxT = 1; } // Find the intersection of distance convex hull and fat line. - x_at(distance2y[0], distance2y[1], top, bottom, flags, minT, maxT); - x_at(distance2y[1], distance2y[2], top, bottom, flags, minT, maxT); - x_at(distance2y[2], distance2y[0], top, bottom, flags, minT, maxT); - + int idx = 0; + do { + int next = idx + 1; + if (next == 3) { + next = 0; + } + x_at(distance2y[idx], distance2y[next], top, bottom, flags, minT, maxT); + idx = next; + } while (idx); return minT < maxT; // returns false if distance shows no intersection } - diff --git a/experimental/Intersection/QuadraticBezierClip_Test.cpp b/experimental/Intersection/QuadraticBezierClip_Test.cpp index 4fe35ba..894d899 100644 --- a/experimental/Intersection/QuadraticBezierClip_Test.cpp +++ b/experimental/Intersection/QuadraticBezierClip_Test.cpp @@ -1,10 +1,24 @@ -/* - * QuadraticBezierClip_Test.cpp - * edge - * - * Created by Cary Clark on 1/10/12. - * Copyright 2012 __MyCompanyName__. All rights reserved. - * - */ - +#include "CubicIntersection.h" +#include "Intersection_Tests.h" +#include "QuadraticIntersection_TestData.h" +void QuadraticBezierClip_Test() { + for (size_t index = 0; index < quadraticTests_count; ++index) { + const Quadratic& quad1 = quadraticTests[index][0]; + const Quadratic& quad2 = quadraticTests[index][1]; + Quadratic reduce1, reduce2; + int order1 = reduceOrder(quad1, reduce1); + int order2 = reduceOrder(quad2, reduce2); + if (order1 < 3) { + printf("%s [%d] quad1 order=%d\n", __FUNCTION__, (int)index, order1); + } + if (order2 < 3) { + printf("%s [%d] quad2 order=%d\n", __FUNCTION__, (int)index, order2); + } + if (order1 == 3 && order2 == 3) { + double minT = 0; + double maxT = 1; + bezier_clip(reduce1, reduce2, minT, maxT); + } + } +} diff --git a/experimental/Intersection/QuadraticIntersection.cpp b/experimental/Intersection/QuadraticIntersection.cpp index 9a92c69..ab552e0 100644 --- a/experimental/Intersection/QuadraticIntersection.cpp +++ b/experimental/Intersection/QuadraticIntersection.cpp @@ -185,4 +185,3 @@ principal value is always non-negative. The other square root is simply –1 times the principal square root; in other words, the two square roots of a number sum to 0. */ - \ No newline at end of file diff --git a/experimental/Intersection/QuadraticIntersection_Test.cpp b/experimental/Intersection/QuadraticIntersection_Test.cpp new file mode 100644 index 0000000..7e171f0 --- /dev/null +++ b/experimental/Intersection/QuadraticIntersection_Test.cpp @@ -0,0 +1,46 @@ +#include "CubicIntersection.h" +#include "Intersection_Tests.h" +#include "Intersections.h" +#include "QuadraticIntersection_TestData.h" +#include "TestUtilities.h" + +const int firstQuadIntersectionTest = 9; + +void QuadraticIntersection_Test() { + for (size_t index = firstQuadIntersectionTest; index < quadraticTests_count; ++index) { + const Quadratic& quad1 = quadraticTests[index][0]; + const Quadratic& quad2 = quadraticTests[index][1]; + Quadratic reduce1, reduce2; + int order1 = reduceOrder(quad1, reduce1); + int order2 = reduceOrder(quad2, reduce2); + if (order1 < 3) { + printf("[%d] quad1 order=%d\n", (int) index, order1); + } + if (order2 < 3) { + printf("[%d] quad2 order=%d\n", (int) index, order2); + } + if (order1 == 3 && order2 == 3) { + Intersections intersections; + intersectStart(reduce1, reduce2, intersections); + if (intersections.intersected()) { + for (int pt = 0; pt < intersections.used(); ++pt) { + double tt1 = intersections.fT[0][pt]; + double tx1, ty1; + xy_at_t(quad1, tt1, tx1, ty1); + double tt2 = intersections.fT[1][pt]; + double tx2, ty2; + xy_at_t(quad2, tt2, tx2, ty2); + if (!approximately_equal(tx1, tx2)) { + printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + if (!approximately_equal(ty1, ty2)) { + printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n", + __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2); + } + } + } + } + } +} + diff --git a/experimental/Intersection/QuadraticIntersection_TestData.cpp b/experimental/Intersection/QuadraticIntersection_TestData.cpp index 0d876bf..2fa8a98 100644 --- a/experimental/Intersection/QuadraticIntersection_TestData.cpp +++ b/experimental/Intersection/QuadraticIntersection_TestData.cpp @@ -9,3 +9,92 @@ #include "QuadraticIntersection_TestData.h" +const Quadratic quadraticLines[] = { + {{0, 0}, {0, 0}, {1, 0}}, + {{0, 0}, {1, 0}, {0, 0}}, + {{1, 0}, {0, 0}, {0, 0}}, + {{1, 0}, {2, 0}, {3, 0}}, + {{0, 0}, {0, 0}, {0, 1}}, + {{0, 0}, {0, 1}, {0, 0}}, + {{0, 1}, {0, 0}, {0, 0}}, + {{0, 1}, {0, 2}, {0, 3}}, + {{0, 0}, {0, 0}, {1, 1}}, + {{0, 0}, {1, 1}, {0, 0}}, + {{1, 1}, {0, 0}, {0, 0}}, + {{1, 1}, {2, 2}, {3, 3}}, + {{1, 1}, {3, 3}, {3, 3}}, + {{1, 1}, {1, 1}, {2, 2}}, + {{1, 1}, {2, 2}, {1, 1}}, + {{1, 1}, {1, 1}, {3, 3}}, + {{1, 1}, {2, 2}, {4, 4}}, // no coincident + {{1, 1}, {3, 3}, {4, 4}}, + {{1, 1}, {3, 3}, {2, 2}}, + {{1, 1}, {4, 4}, {2, 2}}, + {{1, 1}, {4, 4}, {3, 3}}, + {{2, 2}, {1, 1}, {3, 3}}, + {{2, 2}, {1, 1}, {4, 4}}, + {{2, 2}, {3, 3}, {1, 1}}, + {{2, 2}, {3, 3}, {4, 4}}, + {{2, 2}, {4, 4}, {1, 1}}, + {{2, 2}, {4, 4}, {3, 3}}, +}; + +const size_t quadraticLines_count = sizeof(quadraticLines) / sizeof(quadraticLines[0]); + +static const double F = PointEpsilon * 3; +static const double H = PointEpsilon * 4; +static const double J = PointEpsilon * 5; +static const double K = PointEpsilon * 8; // INVESTIGATE: why are larger multiples necessary? + +const Quadratic quadraticModEpsilonLines[] = { + {{0, F}, {0, 0}, {1, 0}}, + {{0, 0}, {1, 0}, {0, F}}, + {{1, 0}, {0, F}, {0, 0}}, + {{1, H}, {2, 0}, {3, 0}}, + {{F, 0}, {0, 0}, {0, 1}}, + {{0, 0}, {0, 1}, {F, 0}}, + {{0, 1}, {F, 0}, {0, 0}}, + {{H, 1}, {0, 2}, {0, 3}}, + {{0, F}, {0, 0}, {1, 1}}, + {{0, 0}, {1, 1}, {F, 0}}, + {{1, 1}, {F, 0}, {0, 0}}, + {{1, 1+J}, {2, 2}, {3, 3}}, + {{1, 1}, {3, 3}, {3+F, 3}}, + {{1, 1}, {1+F, 1}, {2, 2}}, + {{1, 1}, {2, 2}, {1, 1+F}}, + {{1, 1}, {1, 1+F}, {3, 3}}, + {{1+H, 1}, {2, 2}, {4, 4}}, // no coincident + {{1, 1+K}, {3, 3}, {4, 4}}, + {{1, 1}, {3+F, 3}, {2, 2}}, + {{1, 1}, {4, 4+F}, {2, 2}}, + {{1, 1}, {4, 4}, {3+F, 3}}, + {{2, 2}, {1, 1}, {3, 3+F}}, + {{2+F, 2}, {1, 1}, {4, 4}}, + {{2, 2+F}, {3, 3}, {1, 1}}, + {{2, 2}, {3+F, 3}, {4, 4}}, + {{2, 2}, {4, 4+F}, {1, 1}}, + {{2, 2}, {4, 4}, {3+F, 3}}, +}; + +const size_t quadraticModEpsilonLines_count = sizeof(quadraticModEpsilonLines) / sizeof(quadraticModEpsilonLines[0]); + +const Quadratic quadraticTests[][2] = { + { // one intersection + {{0, 0}, + {0, 1}, + {1, 1}}, + {{0, 1}, + {0, 0}, + {1, 0}} + }, + { // four intersections + {{1, 0}, + {2, 6}, + {3, 0}}, + {{0, 1}, + {6, 2}, + {0, 3}} + } +}; + +const size_t quadraticTests_count = sizeof(quadraticTests) / sizeof(quadraticTests[0]); diff --git a/experimental/Intersection/QuadraticIntersection_TestData.h b/experimental/Intersection/QuadraticIntersection_TestData.h index 003c376..54f084c 100644 --- a/experimental/Intersection/QuadraticIntersection_TestData.h +++ b/experimental/Intersection/QuadraticIntersection_TestData.h @@ -1,9 +1,9 @@ -/* - * QuadraticIntersection_TestData.h - * edge - * - * Created by Cary Clark on 1/10/12. - * Copyright 2012 __MyCompanyName__. All rights reserved. - * - */ +#include "DataTypes.h" +extern const Quadratic quadraticLines[]; +extern const Quadratic quadraticModEpsilonLines[]; +extern const Quadratic quadraticTests[][2]; + +extern const size_t quadraticLines_count; +extern const size_t quadraticModEpsilonLines_count; +extern const size_t quadraticTests_count; diff --git a/experimental/Intersection/QuadraticParameterization.cpp b/experimental/Intersection/QuadraticParameterization.cpp index a78aa9f..1c08fcb 100644 --- a/experimental/Intersection/QuadraticParameterization.cpp +++ b/experimental/Intersection/QuadraticParameterization.cpp @@ -130,3 +130,5 @@ void tangent(const Quadratic& quadratic, double t, _Point& result) { result.y = tangent(&quadratic[0].y, t); } +// unit test to return and validate parametric coefficients +#include "QuadraticParameterization_TestUtility.cpp" diff --git a/experimental/Intersection/QuadraticParameterization_Test.cpp b/experimental/Intersection/QuadraticParameterization_Test.cpp index c796685..ddf73b4 100644 --- a/experimental/Intersection/QuadraticParameterization_Test.cpp +++ b/experimental/Intersection/QuadraticParameterization_Test.cpp @@ -1,5 +1,5 @@ #include "CubicIntersection.h" -#include "CubicIntersection_Tests.h" +#include "Intersection_Tests.h" const Quadratic quadratics[] = { {{0, 0}, {1, 0}, {1, 1}}, @@ -18,20 +18,23 @@ void QuadraticCoincidence_Test() { chop_at(test, split, 0.5); Quadratic midThird; sub_divide(test, 1.0/3, 2.0/3, midThird); - if (!implicit_matches(test, split.first())) { - printf("%s-1 %d", __FUNCTION__, (int)index); - } - if (!implicit_matches(test, split.second())) { - printf("%s-2 %d", __FUNCTION__, (int)index); - } - if (!implicit_matches(midThird, split.first())) { - printf("%s-3 %d", __FUNCTION__, (int)index); - } - if (!implicit_matches(midThird, split.second())) { - printf("%s-4 %d", __FUNCTION__, (int)index); - } - if (!implicit_matches(split.first(), split.second())) { - printf("%s-5 %d", __FUNCTION__, (int)index); + const Quadratic* quads[] = { + &test, &midThird, &split.first(), &split.second() + }; + size_t quadsCount = sizeof(quads) / sizeof(quads[0]); + for (size_t one = 0; one < quadsCount; ++one) { + for (size_t two = 0; two < quadsCount; ++two) { + for (size_t inner = 0; inner < 3; inner += 2) { + if (!point_on_parameterized_curve(*quads[one], (*quads[two])[inner])) { + printf("%s %zu [%zu,%zu] %zu parameterization failed\n", + __FUNCTION__, index, one, two, inner); + } + } + if (!implicit_matches(*quads[one], *quads[two])) { + printf("%s %zu [%zu,%zu] coincidence failed\n", __FUNCTION__, + index, one, two); + } + } } } } diff --git a/experimental/Intersection/QuadraticParameterization_TestUtility.cpp b/experimental/Intersection/QuadraticParameterization_TestUtility.cpp new file mode 100644 index 0000000..326b28e --- /dev/null +++ b/experimental/Intersection/QuadraticParameterization_TestUtility.cpp @@ -0,0 +1,15 @@ +// included by QuadraticParameterization.cpp +// accesses internal functions to validate parameterized coefficients + +bool point_on_parameterized_curve(const Quadratic& quad, const _Point& point) { + double coeffs[coeff_count]; + implicit_coefficients(quad, coeffs); + double xx = coeffs[ xx_coeff] * point.x * point.x; + double xy = coeffs[ xy_coeff] * point.x * point.y; + double yy = coeffs[ yy_coeff] * point.y * point.y; + double x = coeffs[ x_coeff] * point.x; + double y = coeffs[ y_coeff] * point.y; + double c = coeffs[ c_coeff]; + double sum = xx + xy + yy + x + y + c; + return approximately_zero(sum); +} diff --git a/experimental/Intersection/QuadraticReduceOrder_Test.cpp b/experimental/Intersection/QuadraticReduceOrder_Test.cpp new file mode 100644 index 0000000..6e92329 --- /dev/null +++ b/experimental/Intersection/QuadraticReduceOrder_Test.cpp @@ -0,0 +1,38 @@ +#include "CubicIntersection.h" +#include "Intersection_Tests.h" +#include "QuadraticIntersection_TestData.h" +#include "TestUtilities.h" + +void QuadraticReduceOrder_Test() { + size_t index; + Quadratic reduce; + int order; + enum { + RunAll, + RunQuadraticLines, + RunQuadraticModLines, + RunNone + } run = RunAll; + int firstTestIndex = 0; +#if 0 + run = RunQuadraticLines; + firstTestIndex = 1; +#endif + int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX; + int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX; + + for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) { + const Quadratic& quad = quadraticLines[index]; + order = reduceOrder(quad, reduce); + if (order != 2) { + printf("[%d] line quad order=%d\n", (int) index, order); + } + } + for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) { + const Quadratic& quad = quadraticModEpsilonLines[index]; + order = reduceOrder(quad, reduce); + if (order != 3) { + printf("[%d] line mod quad order=%d\n", (int) index, order); + } + } +} diff --git a/experimental/Intersection/QuadraticUtilities.cpp b/experimental/Intersection/QuadraticUtilities.cpp new file mode 100644 index 0000000..aa784cb --- /dev/null +++ b/experimental/Intersection/QuadraticUtilities.cpp @@ -0,0 +1,21 @@ +#include "QuadraticUtilities.h" + +int quadraticRoots(double A, double B, double C, double t[2]) { + B *= 2; + double square = B * B - 4 * A * C; + if (square < 0) { + return 0; + } + double squareRt = sqrt(square); + double Q = (B + (B < 0 ? -squareRt : squareRt)) / -2; + int foundRoots = 0; + if ((Q <= A) ^ (Q < 0)) { + t[foundRoots++] = Q / A; + } + if ((C <= Q) ^ (C < 0)) { + t[foundRoots++] = C / Q; + } + return foundRoots; +} + + diff --git a/experimental/Intersection/QuadraticUtilities.h b/experimental/Intersection/QuadraticUtilities.h index 46f6745..2b7e34a 100644 --- a/experimental/Intersection/QuadraticUtilities.h +++ b/experimental/Intersection/QuadraticUtilities.h @@ -4,7 +4,7 @@ * b = 2*B - 2*C * c = C */ -static void set_abc(const double* quad, double& a, double& b, double& c) { +inline void set_abc(const double* quad, double& a, double& b, double& c) { a = quad[0]; // a = A b = 2 * quad[2]; // b = 2*B c = quad[4]; // c = C @@ -12,3 +12,5 @@ static void set_abc(const double* quad, double& a, double& b, double& c) { a -= b; // a = A - 2*B + C b -= c; // b = 2*B - 2*C } + +int quadraticRoots(double A, double B, double C, double t[2]); diff --git a/experimental/Intersection/ReduceOrder_Test.cpp b/experimental/Intersection/ReduceOrder_Test.cpp index 04aea1a..e213015 100644 --- a/experimental/Intersection/ReduceOrder_Test.cpp +++ b/experimental/Intersection/ReduceOrder_Test.cpp @@ -1,6 +1,7 @@ #include "CubicIntersection.h" #include "CubicIntersection_TestData.h" #include "CubicIntersection_Tests.h" +#include "QuadraticIntersection_TestData.h" #include "TestUtilities.h" void ReduceOrder_Test() { diff --git a/experimental/Intersection/TestUtilities.cpp b/experimental/Intersection/TestUtilities.cpp index 5e3c18e..e09e107 100644 --- a/experimental/Intersection/TestUtilities.cpp +++ b/experimental/Intersection/TestUtilities.cpp @@ -67,3 +67,19 @@ void xy_at_t(const Cubic& cubic, double t, double& x, double& y) { x = a * cubic[0].x + b * cubic[1].x + c * cubic[2].x + d * cubic[3].x; y = a * cubic[0].y + b * cubic[1].y + c * cubic[2].y + d * cubic[3].y; } + +void xy_at_t(const _Line& line, double t, double& x, double& y) { + double one_t = 1 - t; + x = one_t * line[0].x + t * line[1].x; + y = one_t * line[0].y + t * line[1].y; +} + +void xy_at_t(const Quadratic& quad, double t, double& x, double& y) { + double one_t = 1 - t; + double a = one_t * one_t; + double b = 2 * one_t * t; + double c = t * t; + x = a * quad[0].x + b * quad[1].x + c * quad[2].x; + y = a * quad[0].y + b * quad[1].y + c * quad[2].y; +} + diff --git a/experimental/Intersection/TestUtilities.h b/experimental/Intersection/TestUtilities.h index c67d702..b5bdae5 100644 --- a/experimental/Intersection/TestUtilities.h +++ b/experimental/Intersection/TestUtilities.h @@ -4,3 +4,5 @@ bool controls_inside(const Cubic& ); void find_tight_bounds(const Cubic& , _Rect& ); void quad_to_cubic(const Quadratic& , Cubic& ); void xy_at_t(const Cubic& , double t, double& x, double& y); +void xy_at_t(const _Line& , double t, double& x, double& y); +void xy_at_t(const Quadratic& , double t, double& x, double& y); diff --git a/experimental/Intersection/edge.xcodeproj/project.pbxproj b/experimental/Intersection/edge.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6f2460c --- /dev/null +++ b/experimental/Intersection/edge.xcodeproj/project.pbxproj @@ -0,0 +1,1081 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + FE3201C8144DCC68006DDA67 /* skia_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = FE3201C6144DCC68006DDA67 /* skia_mac.mm */; }; + FE3201C9144DCC68006DDA67 /* SkOSWindow_Mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = FE3201C7144DCC68006DDA67 /* SkOSWindow_Mac.mm */; }; + FE7130A114CE0EEB0008E392 /* LineQuadraticIntersection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7130A014CE0EEB0008E392 /* LineQuadraticIntersection.cpp */; }; + FE7131C414CF5A960008E392 /* LineQuadraticIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7131C314CF5A960008E392 /* LineQuadraticIntersection_Test.cpp */; }; + FE7131EE14D03AED0008E392 /* LineCubicIntersection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7131ED14D03AED0008E392 /* LineCubicIntersection.cpp */; }; + FE71324214D047670008E392 /* QuadraticUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE71324114D047670008E392 /* QuadraticUtilities.cpp */; }; + FE71324F14D04D460008E392 /* CubicRoots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA54114BC838600B35E2C /* CubicRoots.cpp */; }; + FE71325014D04D480008E392 /* CubeRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA53014BB934700B35E2C /* CubeRoot.cpp */; }; + FE71325F14D050D80008E392 /* LineUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE71325E14D050D80008E392 /* LineUtilities.cpp */; }; + FE71334214D06B0F0008E392 /* LineCubicIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE71334114D06B0F0008E392 /* LineCubicIntersection_Test.cpp */; }; + FEA5F4E21498000C005052F9 /* libports.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA5F4E11497FFF6005052F9 /* libports.a */; }; + FEA671D013C4A21600FE6FC1 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA671CF13C4A21600FE6FC1 /* AGL.framework */; }; + FEA671D813C4A21600FE6FC1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA671D713C4A21600FE6FC1 /* Foundation.framework */; }; + FEA671DA13C4A21600FE6FC1 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA671D913C4A21600FE6FC1 /* OpenGL.framework */; }; + FEA6778313C4B3A300FE6FC1 /* EdgeApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEA6778213C4B3A300FE6FC1 /* EdgeApp.cpp */; }; + FEC117CC14843B0A0086BF1F /* CubicBezierClip_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC117CB14843B0A0086BF1F /* CubicBezierClip_Test.cpp */; }; + FEC118B8148666670086BF1F /* ConvexHull.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC118B7148666670086BF1F /* ConvexHull.cpp */; }; + FEC118C2148668F30086BF1F /* DataTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC118C1148668F30086BF1F /* DataTypes.cpp */; }; + FEC11911148682200086BF1F /* CubicReduceOrder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC11910148682200086BF1F /* CubicReduceOrder.cpp */; }; + FEC1191B148683330086BF1F /* Extrema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC1191A148683330086BF1F /* Extrema.cpp */; }; + FEC1195514869DCA0086BF1F /* LineIntersection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC1195414869DC90086BF1F /* LineIntersection.cpp */; }; + FEC11E3E148D65780086BF1F /* CubicSubDivide.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC11E3D148D65780086BF1F /* CubicSubDivide.cpp */; }; + FEC11F84148E7C9C0086BF1F /* junk.htm in Resources */ = {isa = PBXBuildFile; fileRef = FEC11F83148E7C9C0086BF1F /* junk.htm */; }; + FEC12116148EB4EC0086BF1F /* CubicIntersectionT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC12115148EB4EC0086BF1F /* CubicIntersectionT.cpp */; }; + FEC1211B148EB5200086BF1F /* CubicBezierClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC1211A148EB5200086BF1F /* CubicBezierClip.cpp */; }; + FEC1238F149000100086BF1F /* LineParameteters_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC1238E149000100086BF1F /* LineParameteters_Test.cpp */; }; + FEC123A6149001A00086BF1F /* SkAntiEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEA670F013C49E2200FE6FC1 /* SkAntiEdge.cpp */; }; + FEC12CE014913E650086BF1F /* LineIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC12CDF14913E650086BF1F /* LineIntersection_Test.cpp */; }; + FECA984014AA044100B35E2C /* CubicParameterization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA983F14AA044100B35E2C /* CubicParameterization.cpp */; }; + FECA985114AA046600B35E2C /* QuadraticParameterization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA985014AA046600B35E2C /* QuadraticParameterization.cpp */; }; + FECA986214AA2E5900B35E2C /* QuadraticParameterization_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA986114AA2E5900B35E2C /* QuadraticParameterization_Test.cpp */; }; + FECA987814AA319300B35E2C /* QuadraticSubDivide.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA987714AA319300B35E2C /* QuadraticSubDivide.cpp */; }; + FECA997C14AB966900B35E2C /* CubicParameterizationCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA997B14AB966900B35E2C /* CubicParameterizationCode.cpp */; }; + FECA9A5A14B3B09100B35E2C /* CubicParameterization_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECA9A5914B3B09100B35E2C /* CubicParameterization_Test.cpp */; }; + FECAA52214BB527000B35E2C /* QuadraticIntersection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA52114BB527000B35E2C /* QuadraticIntersection.cpp */; }; + FECAA56D14BCA23200B35E2C /* QuadraticReduceOrder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA56C14BCA23200B35E2C /* QuadraticReduceOrder.cpp */; }; + FECAA58414BCBD4E00B35E2C /* QuadraticBezierClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA58314BCBD4E00B35E2C /* QuadraticBezierClip.cpp */; }; + FECAA67914BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA67814BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp */; }; + FECAA68514BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA68414BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp */; }; + FECAA6C714BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA6C614BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp */; }; + FECAA6E114BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA6E014BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp */; }; + FED53C391483CB9400F6359E /* Inline_Tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED53C381483CB9400F6359E /* Inline_Tests.cpp */; }; + FEED7245144DD2250059E97B /* SkEventNotifier.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEED723E144DD2250059E97B /* SkEventNotifier.mm */; }; + FEED7291144DD45E0059E97B /* libanimator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7268144DD3EA0059E97B /* libanimator.a */; }; + FEED7292144DD4610059E97B /* libexperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED726E144DD4050059E97B /* libexperimental.a */; }; + FEED7293144DD4620059E97B /* libskgr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7276144DD4140059E97B /* libskgr.a */; }; + FEED7294144DD4630059E97B /* libgr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7278144DD4140059E97B /* libgr.a */; }; + FEED7295144DD4650059E97B /* libimages.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED727E144DD4200059E97B /* libimages.a */; }; + FEED7296144DD4660059E97B /* libtess.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7284144DD4300059E97B /* libtess.a */; }; + FEED7297144DD46A0059E97B /* libpdf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED728A144DD4440059E97B /* libpdf.a */; }; + FEED7298144DD46B0059E97B /* libsvg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7290144DD44D0059E97B /* libsvg.a */; }; + FEED7299144DD46F0059E97B /* libviews.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7262144DD38D0059E97B /* libviews.a */; }; + FEED72A2144DD4AA0059E97B /* libxml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED72A1144DD4A80059E97B /* libxml.a */; }; + FEED72AB144DD50A0059E97B /* SampleAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEED723D144DD2250059E97B /* SampleAppDelegate.mm */; }; + FEED72B0144DD5710059E97B /* SampleApp.xib in Resources */ = {isa = PBXBuildFile; fileRef = FEED723C144DD2250059E97B /* SampleApp.xib */; }; + FEED7378144DD5F70059E97B /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA671D113C4A21600FE6FC1 /* ApplicationServices.framework */; }; + FEED7584144DD6360059E97B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7583144DD6360059E97B /* Cocoa.framework */; }; + FEED75DD144DD6590059E97B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED75DC144DD6590059E97B /* QuartzCore.framework */; }; + FEED75DF144DD6840059E97B /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED75DE144DD6840059E97B /* libz.dylib */; }; + FEED7626144F22E20059E97B /* CubicReduceOrder_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED7625144F22E20059E97B /* CubicReduceOrder_Test.cpp */; }; + FEED762C144F236C0059E97B /* CubicIntersection_TestData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED762B144F236C0059E97B /* CubicIntersection_TestData.cpp */; }; + FEED764C144F29BD0059E97B /* TestUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED764B144F29BD0059E97B /* TestUtilities.cpp */; }; + FEED768A144F2E7D0059E97B /* CubicIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED7689144F2E7D0059E97B /* CubicIntersection_Test.cpp */; }; + FEED76C1144F3E7F0059E97B /* ConvexHull_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED76C0144F3E7F0059E97B /* ConvexHull_Test.cpp */; }; + FEED76EE144F66E90059E97B /* Intersection_Tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEED76ED144F66E90059E97B /* Intersection_Tests.cpp */; }; + FEF87C3C13E0413500335C58 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF87C1A13E040E000335C58 /* libcore.a */; }; + FEF87C3D13E0413A00335C58 /* libeffects.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF87C2313E040F100335C58 /* libeffects.a */; }; + FEF87C3E13E0413F00335C58 /* libopts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF87C2C13E0410900335C58 /* libopts.a */; }; + FEF87C3F13E0414400335C58 /* libutils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF87C3B13E0412600335C58 /* libutils.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + FEA5F4E01497FFF6005052F9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEA5F4D91497FFF6005052F9 /* ports.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CDE03B47AA5CD6CE32E53995; + remoteInfo = ports; + }; + FEED7261144DD38D0059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED725D144DD38D0059E97B /* views.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 86302AD97E7E3B2ECED008C3; + remoteInfo = views; + }; + FEED7267144DD3EA0059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED7263144DD3EA0059E97B /* animator.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D2E8ABFA0A0734A3D0C9119; + remoteInfo = animator; + }; + FEED726D144DD4050059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED7269144DD4050059E97B /* experimental.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E18165BCFCD262D9D8DC9100; + remoteInfo = experimental; + }; + FEED7275144DD4140059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED726F144DD4140059E97B /* gpu.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9756429FF98563EB31F7DB61; + remoteInfo = skgr; + }; + FEED7277144DD4140059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED726F144DD4140059E97B /* gpu.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 4005E78FA1587FEF4005B75F; + remoteInfo = gr; + }; + FEED727D144DD4200059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED7279144DD4200059E97B /* images.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CDE66C29FD25244B1B30A964; + remoteInfo = images; + }; + FEED7283144DD4300059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED727F144DD4300059E97B /* libtess.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 985181AD94E99169C732B721; + remoteInfo = libtess; + }; + FEED7289144DD4440059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED7285144DD4440059E97B /* pdf.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 46FE697B5062CDA12F1A8C6E; + remoteInfo = pdf; + }; + FEED728F144DD44D0059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED728B144DD44D0059E97B /* svg.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E11E06188E29426A061DFAA2; + remoteInfo = svg; + }; + FEED72A0144DD4A80059E97B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEED729C144DD4A80059E97B /* xml.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = B9B83862B1FE3A5230CB0ED6; + remoteInfo = xml; + }; + FEF87C1913E040E000335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C1213E040E000335C58 /* core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8B1FC9FF853D5C32F4771091; + remoteInfo = core; + }; + FEF87C2213E040F100335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C1B13E040F100335C58 /* effects.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BB64F2E443C9412F1328140F; + remoteInfo = effects; + }; + FEF87C2B13E0410900335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C2413E0410900335C58 /* opts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 6FDD5BFF3B676557344FAA2B; + remoteInfo = opts; + }; + FEF87C3A13E0412600335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C3313E0412600335C58 /* utils.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C196E82C2F3304B37526F8F3; + remoteInfo = utils; + }; + FEF87C4013E0414D00335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C1213E040E000335C58 /* core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 5A9991BB6607533745115226; + remoteInfo = core; + }; + FEF87C4213E0415100335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C1B13E040F100335C58 /* effects.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = F0EB02F40D8DAD92937C53E1; + remoteInfo = effects; + }; + FEF87C4413E0415500335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C2413E0410900335C58 /* opts.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 801760729BE30DF59BEA25B9; + remoteInfo = opts; + }; + FEF87C4613E0415900335C58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FEF87C3313E0412600335C58 /* utils.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 7364408688F1A6434987562A; + remoteInfo = utils; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; + 256AC3F00F4B6AF500CF3369 /* edge_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edge_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* edge-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "edge-Info.plist"; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* edge.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = edge.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FE3201C6144DCC68006DDA67 /* skia_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = skia_mac.mm; path = ../../skia/trunk/src/utils/mac/skia_mac.mm; sourceTree = SOURCE_ROOT; }; + FE3201C7144DCC68006DDA67 /* SkOSWindow_Mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkOSWindow_Mac.mm; path = ../../skia/trunk/src/utils/mac/SkOSWindow_Mac.mm; sourceTree = SOURCE_ROOT; }; + FE3EBE41149A337700D76FDE /* x.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = x.svg; path = ../../../../tera/x.svg; sourceTree = SOURCE_ROOT; }; + FE3EBE6E149A7F4D00D76FDE /* valgrind.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = valgrind.txt; path = ../../../../tera/valgrind.txt; sourceTree = SOURCE_ROOT; }; + FE4FE7411492417500A12A34 /* IntersectionUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntersectionUtilities.cpp; sourceTree = ""; }; + FE7130A014CE0EEB0008E392 /* LineQuadraticIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineQuadraticIntersection.cpp; sourceTree = ""; }; + FE7131C314CF5A960008E392 /* LineQuadraticIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineQuadraticIntersection_Test.cpp; sourceTree = ""; }; + FE7131ED14D03AED0008E392 /* LineCubicIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineCubicIntersection.cpp; sourceTree = ""; }; + FE71324114D047670008E392 /* QuadraticUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticUtilities.cpp; sourceTree = ""; }; + FE71325114D04D7A0008E392 /* CubicUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicUtilities.h; sourceTree = ""; }; + FE71325D14D050D80008E392 /* LineUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineUtilities.h; sourceTree = ""; }; + FE71325E14D050D80008E392 /* LineUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineUtilities.cpp; sourceTree = ""; }; + FE71334114D06B0F0008E392 /* LineCubicIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineCubicIntersection_Test.cpp; sourceTree = ""; }; + FEA5F4D91497FFF6005052F9 /* ports.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ports.xcodeproj; path = ../../skia/trunk/out/gyp/ports.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEA670F013C49E2200FE6FC1 /* SkAntiEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkAntiEdge.cpp; sourceTree = ""; }; + FEA670F113C49E2200FE6FC1 /* SkAntiEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkAntiEdge.h; sourceTree = ""; }; + FEA6710713C4A13900FE6FC1 /* gyp */ = {isa = PBXFileReference; lastKnownFileType = folder; name = gyp; path = ../../skia/trunk/out/gyp; sourceTree = SOURCE_ROOT; }; + FEA671CF13C4A21600FE6FC1 /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = System/Library/Frameworks/AGL.framework; sourceTree = SDKROOT; }; + FEA671D113C4A21600FE6FC1 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; + FEA671D713C4A21600FE6FC1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + FEA671D913C4A21600FE6FC1 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + FEA6778213C4B3A300FE6FC1 /* EdgeApp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeApp.cpp; sourceTree = ""; }; + FEC117CB14843B0A0086BF1F /* CubicBezierClip_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicBezierClip_Test.cpp; sourceTree = ""; }; + FEC118B7148666670086BF1F /* ConvexHull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvexHull.cpp; sourceTree = ""; }; + FEC118C1148668F30086BF1F /* DataTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataTypes.cpp; sourceTree = ""; }; + FEC11910148682200086BF1F /* CubicReduceOrder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicReduceOrder.cpp; sourceTree = ""; }; + FEC1191A148683330086BF1F /* Extrema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Extrema.cpp; sourceTree = ""; }; + FEC1191E148683850086BF1F /* Extrema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extrema.h; sourceTree = ""; }; + FEC1195314869DC90086BF1F /* LineIntersection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineIntersection.h; sourceTree = ""; }; + FEC1195414869DC90086BF1F /* LineIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineIntersection.cpp; sourceTree = ""; }; + FEC11A821487D23E0086BF1F /* Intersections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Intersections.h; sourceTree = ""; }; + FEC11A851487D2650086BF1F /* LineParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineParameters.h; sourceTree = ""; }; + FEC11A881487D2F50086BF1F /* IntersectionUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntersectionUtilities.h; sourceTree = ""; }; + FEC11E3D148D65780086BF1F /* CubicSubDivide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicSubDivide.cpp; sourceTree = ""; }; + FEC11F83148E7C9C0086BF1F /* junk.htm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = junk.htm; path = ../../../../tera/htm_backups/junk.htm; sourceTree = SOURCE_ROOT; }; + FEC12115148EB4EC0086BF1F /* CubicIntersectionT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersectionT.cpp; sourceTree = ""; }; + FEC1211A148EB5200086BF1F /* CubicBezierClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicBezierClip.cpp; sourceTree = ""; }; + FEC1238E149000100086BF1F /* LineParameteters_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineParameteters_Test.cpp; sourceTree = ""; }; + FEC12CDF14913E650086BF1F /* LineIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineIntersection_Test.cpp; sourceTree = ""; }; + FECA983F14AA044100B35E2C /* CubicParameterization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization.cpp; sourceTree = ""; }; + FECA985014AA046600B35E2C /* QuadraticParameterization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization.cpp; sourceTree = ""; }; + FECA986114AA2E5900B35E2C /* QuadraticParameterization_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization_Test.cpp; sourceTree = ""; }; + FECA987714AA319300B35E2C /* QuadraticSubDivide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticSubDivide.cpp; sourceTree = ""; }; + FECA997B14AB966900B35E2C /* CubicParameterizationCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterizationCode.cpp; sourceTree = ""; }; + FECA9A5914B3B09100B35E2C /* CubicParameterization_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization_Test.cpp; sourceTree = ""; }; + FECAA52114BB527000B35E2C /* QuadraticIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection.cpp; sourceTree = ""; }; + FECAA52B14BB6B0900B35E2C /* QuadraticUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuadraticUtilities.h; sourceTree = ""; }; + FECAA53014BB934700B35E2C /* CubeRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubeRoot.cpp; sourceTree = ""; }; + FECAA54114BC838600B35E2C /* CubicRoots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicRoots.cpp; sourceTree = ""; }; + FECAA56C14BCA23200B35E2C /* QuadraticReduceOrder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticReduceOrder.cpp; sourceTree = ""; }; + FECAA58314BCBD4E00B35E2C /* QuadraticBezierClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticBezierClip.cpp; sourceTree = ""; }; + FECAA67814BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticBezierClip_Test.cpp; sourceTree = ""; }; + FECAA68314BCDE2600B35E2C /* QuadraticIntersection_TestData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuadraticIntersection_TestData.h; sourceTree = ""; }; + FECAA68414BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection_TestData.cpp; sourceTree = ""; }; + FECAA6C614BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection_Test.cpp; sourceTree = ""; }; + FECAA6E014BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticReduceOrder_Test.cpp; sourceTree = ""; }; + FECAAB7F14BDFAFD00B35E2C /* CubicParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization_TestUtility.cpp; sourceTree = ""; }; + FECAACA614BE1C6100B35E2C /* QuadraticParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization_TestUtility.cpp; sourceTree = ""; }; + FED53C381483CB9400F6359E /* Inline_Tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inline_Tests.cpp; sourceTree = ""; }; + FEE103331416542A006952D6 /* CubicIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection.cpp; sourceTree = ""; }; + FEED723C144DD2250059E97B /* SampleApp.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = SampleApp.xib; path = ../../skia/trunk/src/utils/mac/SampleApp.xib; sourceTree = SOURCE_ROOT; }; + FEED723D144DD2250059E97B /* SampleAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SampleAppDelegate.mm; path = ../../skia/trunk/src/utils/mac/SampleAppDelegate.mm; sourceTree = SOURCE_ROOT; }; + FEED723E144DD2250059E97B /* SkEventNotifier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkEventNotifier.mm; path = ../../skia/trunk/src/utils/mac/SkEventNotifier.mm; sourceTree = SOURCE_ROOT; }; + FEED723F144DD2250059E97B /* SkNSView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkNSView.mm; path = ../../skia/trunk/src/utils/mac/SkNSView.mm; sourceTree = SOURCE_ROOT; }; + FEED7240144DD2250059E97B /* SkOptionsTableView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkOptionsTableView.mm; path = ../../skia/trunk/src/utils/mac/SkOptionsTableView.mm; sourceTree = SOURCE_ROOT; }; + FEED7241144DD2250059E97B /* SkSampleNSView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkSampleNSView.mm; path = ../../skia/trunk/src/utils/mac/SkSampleNSView.mm; sourceTree = SOURCE_ROOT; }; + FEED7242144DD2250059E97B /* SkTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SkTextFieldCell.m; path = ../../skia/trunk/src/utils/mac/SkTextFieldCell.m; sourceTree = SOURCE_ROOT; }; + FEED725D144DD38D0059E97B /* views.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = views.xcodeproj; path = ../../skia/trunk/out/gyp/views.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED7263144DD3EA0059E97B /* animator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = animator.xcodeproj; path = ../../skia/trunk/out/gyp/animator.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED7269144DD4050059E97B /* experimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = experimental.xcodeproj; path = ../../skia/trunk/out/gyp/experimental.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED726F144DD4140059E97B /* gpu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gpu.xcodeproj; path = ../../skia/trunk/out/gyp/gpu.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED7279144DD4200059E97B /* images.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = images.xcodeproj; path = ../../skia/trunk/out/gyp/images.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED727F144DD4300059E97B /* libtess.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libtess.xcodeproj; path = ../../skia/trunk/out/gyp/libtess.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED7285144DD4440059E97B /* pdf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = pdf.xcodeproj; path = ../../skia/trunk/out/gyp/pdf.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED728B144DD44D0059E97B /* svg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = svg.xcodeproj; path = ../../skia/trunk/out/gyp/svg.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED729C144DD4A80059E97B /* xml.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = xml.xcodeproj; path = ../../skia/trunk/out/gyp/xml.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEED7583144DD6360059E97B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + FEED75DC144DD6590059E97B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = ""; }; + FEED75DE144DD6840059E97B /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = ""; }; + FEED7625144F22E20059E97B /* CubicReduceOrder_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicReduceOrder_Test.cpp; sourceTree = ""; }; + FEED762B144F236C0059E97B /* CubicIntersection_TestData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection_TestData.cpp; sourceTree = ""; }; + FEED762F144F23CA0059E97B /* CubicIntersection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicIntersection.h; sourceTree = ""; }; + FEED7632144F25150059E97B /* CubicIntersection_TestData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicIntersection_TestData.h; sourceTree = ""; }; + FEED764B144F29BD0059E97B /* TestUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestUtilities.cpp; sourceTree = ""; }; + FEED764F144F2A160059E97B /* DataTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTypes.h; sourceTree = ""; }; + FEED7673144F2D770059E97B /* TestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestUtilities.h; sourceTree = ""; }; + FEED7680144F2E480059E97B /* Intersection_Tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Intersection_Tests.h; sourceTree = ""; }; + FEED7689144F2E7D0059E97B /* CubicIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection_Test.cpp; sourceTree = ""; }; + FEED76C0144F3E7F0059E97B /* ConvexHull_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvexHull_Test.cpp; sourceTree = ""; }; + FEED76ED144F66E90059E97B /* Intersection_Tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Intersection_Tests.cpp; sourceTree = ""; }; + FEF87C1213E040E000335C58 /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = core.xcodeproj; path = ../../skia/trunk/out/gyp/core.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEF87C1B13E040F100335C58 /* effects.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = effects.xcodeproj; path = ../../skia/trunk/out/gyp/effects.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEF87C2413E0410900335C58 /* opts.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = opts.xcodeproj; path = ../../skia/trunk/out/gyp/opts.xcodeproj; sourceTree = SOURCE_ROOT; }; + FEF87C3313E0412600335C58 /* utils.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = utils.xcodeproj; path = ../../skia/trunk/out/gyp/utils.xcodeproj; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FEF87C3C13E0413500335C58 /* libcore.a in Frameworks */, + FEF87C3D13E0413A00335C58 /* libeffects.a in Frameworks */, + FEF87C3E13E0413F00335C58 /* libopts.a in Frameworks */, + FEF87C3F13E0414400335C58 /* libutils.a in Frameworks */, + FEA671D813C4A21600FE6FC1 /* Foundation.framework in Frameworks */, + FEA671D013C4A21600FE6FC1 /* AGL.framework in Frameworks */, + FEA671DA13C4A21600FE6FC1 /* OpenGL.framework in Frameworks */, + FEED7291144DD45E0059E97B /* libanimator.a in Frameworks */, + FEED7292144DD4610059E97B /* libexperimental.a in Frameworks */, + FEED7293144DD4620059E97B /* libskgr.a in Frameworks */, + FEED7294144DD4630059E97B /* libgr.a in Frameworks */, + FEED7295144DD4650059E97B /* libimages.a in Frameworks */, + FEED7296144DD4660059E97B /* libtess.a in Frameworks */, + FEED7297144DD46A0059E97B /* libpdf.a in Frameworks */, + FEED7298144DD46B0059E97B /* libsvg.a in Frameworks */, + FEED7299144DD46F0059E97B /* libviews.a in Frameworks */, + FEED72A2144DD4AA0059E97B /* libxml.a in Frameworks */, + FEED7378144DD5F70059E97B /* ApplicationServices.framework in Frameworks */, + FEED7584144DD6360059E97B /* Cocoa.framework in Frameworks */, + FEED75DD144DD6590059E97B /* QuartzCore.framework in Frameworks */, + FEED75DF144DD6840059E97B /* libz.dylib in Frameworks */, + FEA5F4E21498000C005052F9 /* libports.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* edge.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* edge */ = { + isa = PBXGroup; + children = ( + FE3EBE6E149A7F4D00D76FDE /* valgrind.txt */, + FE3EBE41149A337700D76FDE /* x.svg */, + FEC11F83148E7C9C0086BF1F /* junk.htm */, + FEA670EF13C49D7600FE6FC1 /* views */, + FEC123A7149001B20086BF1F /* AntiEdge */, + 29B97315FDCFA39411CA2CEA /* CubicIntersection */, + FEC123A5149001540086BF1F /* Tests */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + FEED7263144DD3EA0059E97B /* animator.xcodeproj */, + FEF87C1213E040E000335C58 /* core.xcodeproj */, + FEF87C1B13E040F100335C58 /* effects.xcodeproj */, + FEED7269144DD4050059E97B /* experimental.xcodeproj */, + FEED726F144DD4140059E97B /* gpu.xcodeproj */, + FEED7279144DD4200059E97B /* images.xcodeproj */, + FEED727F144DD4300059E97B /* libtess.xcodeproj */, + FEF87C2413E0410900335C58 /* opts.xcodeproj */, + FEA5F4D91497FFF6005052F9 /* ports.xcodeproj */, + FEED7285144DD4440059E97B /* pdf.xcodeproj */, + FEED728B144DD44D0059E97B /* svg.xcodeproj */, + FEF87C3313E0412600335C58 /* utils.xcodeproj */, + FEED725D144DD38D0059E97B /* views.xcodeproj */, + FEED729C144DD4A80059E97B /* xml.xcodeproj */, + FEA6710713C4A13900FE6FC1 /* gyp */, + ); + name = edge; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* CubicIntersection */ = { + isa = PBXGroup; + children = ( + FEC118B7148666670086BF1F /* ConvexHull.cpp */, + FECAA53014BB934700B35E2C /* CubeRoot.cpp */, + FEC1211A148EB5200086BF1F /* CubicBezierClip.cpp */, + FEED762F144F23CA0059E97B /* CubicIntersection.h */, + FEE103331416542A006952D6 /* CubicIntersection.cpp */, + FEC12115148EB4EC0086BF1F /* CubicIntersectionT.cpp */, + FECA983F14AA044100B35E2C /* CubicParameterization.cpp */, + FECA997B14AB966900B35E2C /* CubicParameterizationCode.cpp */, + FEC11910148682200086BF1F /* CubicReduceOrder.cpp */, + FECAA54114BC838600B35E2C /* CubicRoots.cpp */, + FEC11E3D148D65780086BF1F /* CubicSubDivide.cpp */, + FE71325114D04D7A0008E392 /* CubicUtilities.h */, + FEED764F144F2A160059E97B /* DataTypes.h */, + FEC118C1148668F30086BF1F /* DataTypes.cpp */, + FEC1191E148683850086BF1F /* Extrema.h */, + FEC1191A148683330086BF1F /* Extrema.cpp */, + FEC11A821487D23E0086BF1F /* Intersections.h */, + FEC11A881487D2F50086BF1F /* IntersectionUtilities.h */, + FE4FE7411492417500A12A34 /* IntersectionUtilities.cpp */, + FEC1195314869DC90086BF1F /* LineIntersection.h */, + FEC1195414869DC90086BF1F /* LineIntersection.cpp */, + FEC11A851487D2650086BF1F /* LineParameters.h */, + FE7131ED14D03AED0008E392 /* LineCubicIntersection.cpp */, + FE7130A014CE0EEB0008E392 /* LineQuadraticIntersection.cpp */, + FECAA58314BCBD4E00B35E2C /* QuadraticBezierClip.cpp */, + FECAA52114BB527000B35E2C /* QuadraticIntersection.cpp */, + FECA985014AA046600B35E2C /* QuadraticParameterization.cpp */, + FECAA56C14BCA23200B35E2C /* QuadraticReduceOrder.cpp */, + FECA987714AA319300B35E2C /* QuadraticSubDivide.cpp */, + FECAA52B14BB6B0900B35E2C /* QuadraticUtilities.h */, + FE71324114D047670008E392 /* QuadraticUtilities.cpp */, + FE71325D14D050D80008E392 /* LineUtilities.h */, + FE71325E14D050D80008E392 /* LineUtilities.cpp */, + ); + name = CubicIntersection; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* edge-Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + FEA671CF13C4A21600FE6FC1 /* AGL.framework */, + FEA671D113C4A21600FE6FC1 /* ApplicationServices.framework */, + FEED7583144DD6360059E97B /* Cocoa.framework */, + FEA671D713C4A21600FE6FC1 /* Foundation.framework */, + FEA671D913C4A21600FE6FC1 /* OpenGL.framework */, + FEED75DC144DD6590059E97B /* QuartzCore.framework */, + FEED75DE144DD6840059E97B /* libz.dylib */, + ); + name = Frameworks; + sourceTree = ""; + }; + FEA5F4DA1497FFF6005052F9 /* Products */ = { + isa = PBXGroup; + children = ( + FEA5F4E11497FFF6005052F9 /* libports.a */, + ); + name = Products; + sourceTree = ""; + }; + FEA670EF13C49D7600FE6FC1 /* views */ = { + isa = PBXGroup; + children = ( + FEED723C144DD2250059E97B /* SampleApp.xib */, + FEED723D144DD2250059E97B /* SampleAppDelegate.mm */, + FEED723E144DD2250059E97B /* SkEventNotifier.mm */, + FEED723F144DD2250059E97B /* SkNSView.mm */, + FEED7240144DD2250059E97B /* SkOptionsTableView.mm */, + FEED7241144DD2250059E97B /* SkSampleNSView.mm */, + FEED7242144DD2250059E97B /* SkTextFieldCell.m */, + FE3201C7144DCC68006DDA67 /* SkOSWindow_Mac.mm */, + FE3201C6144DCC68006DDA67 /* skia_mac.mm */, + ); + name = views; + sourceTree = ""; + }; + FEC123A5149001540086BF1F /* Tests */ = { + isa = PBXGroup; + children = ( + FEED76C0144F3E7F0059E97B /* ConvexHull_Test.cpp */, + FEC117CB14843B0A0086BF1F /* CubicBezierClip_Test.cpp */, + FEED7689144F2E7D0059E97B /* CubicIntersection_Test.cpp */, + FEED7632144F25150059E97B /* CubicIntersection_TestData.h */, + FEED762B144F236C0059E97B /* CubicIntersection_TestData.cpp */, + FECA9A5914B3B09100B35E2C /* CubicParameterization_Test.cpp */, + FECAAB7F14BDFAFD00B35E2C /* CubicParameterization_TestUtility.cpp */, + FEED7625144F22E20059E97B /* CubicReduceOrder_Test.cpp */, + FED53C381483CB9400F6359E /* Inline_Tests.cpp */, + FEED7680144F2E480059E97B /* Intersection_Tests.h */, + FEED76ED144F66E90059E97B /* Intersection_Tests.cpp */, + FE71334114D06B0F0008E392 /* LineCubicIntersection_Test.cpp */, + FEC12CDF14913E650086BF1F /* LineIntersection_Test.cpp */, + FEC1238E149000100086BF1F /* LineParameteters_Test.cpp */, + FE7131C314CF5A960008E392 /* LineQuadraticIntersection_Test.cpp */, + FECAA67814BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp */, + FECAA6C614BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp */, + FECAA68314BCDE2600B35E2C /* QuadraticIntersection_TestData.h */, + FECAA68414BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp */, + FECA986114AA2E5900B35E2C /* QuadraticParameterization_Test.cpp */, + FECAACA614BE1C6100B35E2C /* QuadraticParameterization_TestUtility.cpp */, + FECAA6E014BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp */, + FEED7673144F2D770059E97B /* TestUtilities.h */, + FEED764B144F29BD0059E97B /* TestUtilities.cpp */, + ); + name = Tests; + sourceTree = ""; + }; + FEC123A7149001B20086BF1F /* AntiEdge */ = { + isa = PBXGroup; + children = ( + FEA670F113C49E2200FE6FC1 /* SkAntiEdge.h */, + FEA670F013C49E2200FE6FC1 /* SkAntiEdge.cpp */, + 256AC3F00F4B6AF500CF3369 /* edge_Prefix.pch */, + FEA6778213C4B3A300FE6FC1 /* EdgeApp.cpp */, + ); + name = AntiEdge; + sourceTree = ""; + }; + FEED725E144DD38D0059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED7262144DD38D0059E97B /* libviews.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED7264144DD3EA0059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED7268144DD3EA0059E97B /* libanimator.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED726A144DD4050059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED726E144DD4050059E97B /* libexperimental.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED7270144DD4140059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED7276144DD4140059E97B /* libskgr.a */, + FEED7278144DD4140059E97B /* libgr.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED727A144DD4200059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED727E144DD4200059E97B /* libimages.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED7280144DD4300059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED7284144DD4300059E97B /* libtess.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED7286144DD4440059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED728A144DD4440059E97B /* libpdf.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED728C144DD44D0059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED7290144DD44D0059E97B /* libsvg.a */, + ); + name = Products; + sourceTree = ""; + }; + FEED729D144DD4A80059E97B /* Products */ = { + isa = PBXGroup; + children = ( + FEED72A1144DD4A80059E97B /* libxml.a */, + ); + name = Products; + sourceTree = ""; + }; + FEF87C1313E040E000335C58 /* Products */ = { + isa = PBXGroup; + children = ( + FEF87C1A13E040E000335C58 /* libcore.a */, + ); + name = Products; + sourceTree = ""; + }; + FEF87C1C13E040F100335C58 /* Products */ = { + isa = PBXGroup; + children = ( + FEF87C2313E040F100335C58 /* libeffects.a */, + ); + name = Products; + sourceTree = ""; + }; + FEF87C2513E0410900335C58 /* Products */ = { + isa = PBXGroup; + children = ( + FEF87C2C13E0410900335C58 /* libopts.a */, + ); + name = Products; + sourceTree = ""; + }; + FEF87C3413E0412600335C58 /* Products */ = { + isa = PBXGroup; + children = ( + FEF87C3B13E0412600335C58 /* libutils.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* edge */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "edge" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + FEF87C4113E0414D00335C58 /* PBXTargetDependency */, + FEF87C4313E0415100335C58 /* PBXTargetDependency */, + FEF87C4513E0415500335C58 /* PBXTargetDependency */, + FEF87C4713E0415900335C58 /* PBXTargetDependency */, + ); + name = edge; + productInstallPath = "$(HOME)/Applications"; + productName = edge; + productReference = 8D1107320486CEB800E47090 /* edge.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "edge" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* edge */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = FEED7264144DD3EA0059E97B /* Products */; + ProjectRef = FEED7263144DD3EA0059E97B /* animator.xcodeproj */; + }, + { + ProductGroup = FEF87C1313E040E000335C58 /* Products */; + ProjectRef = FEF87C1213E040E000335C58 /* core.xcodeproj */; + }, + { + ProductGroup = FEF87C1C13E040F100335C58 /* Products */; + ProjectRef = FEF87C1B13E040F100335C58 /* effects.xcodeproj */; + }, + { + ProductGroup = FEED726A144DD4050059E97B /* Products */; + ProjectRef = FEED7269144DD4050059E97B /* experimental.xcodeproj */; + }, + { + ProductGroup = FEED7270144DD4140059E97B /* Products */; + ProjectRef = FEED726F144DD4140059E97B /* gpu.xcodeproj */; + }, + { + ProductGroup = FEED727A144DD4200059E97B /* Products */; + ProjectRef = FEED7279144DD4200059E97B /* images.xcodeproj */; + }, + { + ProductGroup = FEED7280144DD4300059E97B /* Products */; + ProjectRef = FEED727F144DD4300059E97B /* libtess.xcodeproj */; + }, + { + ProductGroup = FEF87C2513E0410900335C58 /* Products */; + ProjectRef = FEF87C2413E0410900335C58 /* opts.xcodeproj */; + }, + { + ProductGroup = FEED7286144DD4440059E97B /* Products */; + ProjectRef = FEED7285144DD4440059E97B /* pdf.xcodeproj */; + }, + { + ProductGroup = FEA5F4DA1497FFF6005052F9 /* Products */; + ProjectRef = FEA5F4D91497FFF6005052F9 /* ports.xcodeproj */; + }, + { + ProductGroup = FEED728C144DD44D0059E97B /* Products */; + ProjectRef = FEED728B144DD44D0059E97B /* svg.xcodeproj */; + }, + { + ProductGroup = FEF87C3413E0412600335C58 /* Products */; + ProjectRef = FEF87C3313E0412600335C58 /* utils.xcodeproj */; + }, + { + ProductGroup = FEED725E144DD38D0059E97B /* Products */; + ProjectRef = FEED725D144DD38D0059E97B /* views.xcodeproj */; + }, + { + ProductGroup = FEED729D144DD4A80059E97B /* Products */; + ProjectRef = FEED729C144DD4A80059E97B /* xml.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 8D1107260486CEB800E47090 /* edge */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + FEA5F4E11497FFF6005052F9 /* libports.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libports.a; + remoteRef = FEA5F4E01497FFF6005052F9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7262144DD38D0059E97B /* libviews.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libviews.a; + remoteRef = FEED7261144DD38D0059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7268144DD3EA0059E97B /* libanimator.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libanimator.a; + remoteRef = FEED7267144DD3EA0059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED726E144DD4050059E97B /* libexperimental.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libexperimental.a; + remoteRef = FEED726D144DD4050059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7276144DD4140059E97B /* libskgr.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libskgr.a; + remoteRef = FEED7275144DD4140059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7278144DD4140059E97B /* libgr.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libgr.a; + remoteRef = FEED7277144DD4140059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED727E144DD4200059E97B /* libimages.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libimages.a; + remoteRef = FEED727D144DD4200059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7284144DD4300059E97B /* libtess.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libtess.a; + remoteRef = FEED7283144DD4300059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED728A144DD4440059E97B /* libpdf.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libpdf.a; + remoteRef = FEED7289144DD4440059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED7290144DD44D0059E97B /* libsvg.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libsvg.a; + remoteRef = FEED728F144DD44D0059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEED72A1144DD4A80059E97B /* libxml.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libxml.a; + remoteRef = FEED72A0144DD4A80059E97B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEF87C1A13E040E000335C58 /* libcore.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libcore.a; + remoteRef = FEF87C1913E040E000335C58 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEF87C2313E040F100335C58 /* libeffects.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libeffects.a; + remoteRef = FEF87C2213E040F100335C58 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEF87C2C13E0410900335C58 /* libopts.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libopts.a; + remoteRef = FEF87C2B13E0410900335C58 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + FEF87C3B13E0412600335C58 /* libutils.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libutils.a; + remoteRef = FEF87C3A13E0412600335C58 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */, + FEED72B0144DD5710059E97B /* SampleApp.xib in Resources */, + FEC11F84148E7C9C0086BF1F /* junk.htm in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FEA6778313C4B3A300FE6FC1 /* EdgeApp.cpp in Sources */, + FE3201C8144DCC68006DDA67 /* skia_mac.mm in Sources */, + FE3201C9144DCC68006DDA67 /* SkOSWindow_Mac.mm in Sources */, + FEED7245144DD2250059E97B /* SkEventNotifier.mm in Sources */, + FEED72AB144DD50A0059E97B /* SampleAppDelegate.mm in Sources */, + FEED7626144F22E20059E97B /* CubicReduceOrder_Test.cpp in Sources */, + FEED762C144F236C0059E97B /* CubicIntersection_TestData.cpp in Sources */, + FEED764C144F29BD0059E97B /* TestUtilities.cpp in Sources */, + FEED768A144F2E7D0059E97B /* CubicIntersection_Test.cpp in Sources */, + FEED76C1144F3E7F0059E97B /* ConvexHull_Test.cpp in Sources */, + FEED76EE144F66E90059E97B /* Intersection_Tests.cpp in Sources */, + FED53C391483CB9400F6359E /* Inline_Tests.cpp in Sources */, + FEC117CC14843B0A0086BF1F /* CubicBezierClip_Test.cpp in Sources */, + FEC118B8148666670086BF1F /* ConvexHull.cpp in Sources */, + FEC118C2148668F30086BF1F /* DataTypes.cpp in Sources */, + FEC11911148682200086BF1F /* CubicReduceOrder.cpp in Sources */, + FEC1191B148683330086BF1F /* Extrema.cpp in Sources */, + FEC1195514869DCA0086BF1F /* LineIntersection.cpp in Sources */, + FEC11E3E148D65780086BF1F /* CubicSubDivide.cpp in Sources */, + FEC12116148EB4EC0086BF1F /* CubicIntersectionT.cpp in Sources */, + FEC1211B148EB5200086BF1F /* CubicBezierClip.cpp in Sources */, + FEC1238F149000100086BF1F /* LineParameteters_Test.cpp in Sources */, + FEC123A6149001A00086BF1F /* SkAntiEdge.cpp in Sources */, + FEC12CE014913E650086BF1F /* LineIntersection_Test.cpp in Sources */, + FECA984014AA044100B35E2C /* CubicParameterization.cpp in Sources */, + FECA985114AA046600B35E2C /* QuadraticParameterization.cpp in Sources */, + FECA986214AA2E5900B35E2C /* QuadraticParameterization_Test.cpp in Sources */, + FECA987814AA319300B35E2C /* QuadraticSubDivide.cpp in Sources */, + FECA997C14AB966900B35E2C /* CubicParameterizationCode.cpp in Sources */, + FECA9A5A14B3B09100B35E2C /* CubicParameterization_Test.cpp in Sources */, + FECAA52214BB527000B35E2C /* QuadraticIntersection.cpp in Sources */, + FECAA56D14BCA23200B35E2C /* QuadraticReduceOrder.cpp in Sources */, + FECAA58414BCBD4E00B35E2C /* QuadraticBezierClip.cpp in Sources */, + FECAA67914BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp in Sources */, + FECAA68514BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp in Sources */, + FECAA6C714BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp in Sources */, + FECAA6E114BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp in Sources */, + FE7130A114CE0EEB0008E392 /* LineQuadraticIntersection.cpp in Sources */, + FE7131C414CF5A960008E392 /* LineQuadraticIntersection_Test.cpp in Sources */, + FE7131EE14D03AED0008E392 /* LineCubicIntersection.cpp in Sources */, + FE71324214D047670008E392 /* QuadraticUtilities.cpp in Sources */, + FE71324F14D04D460008E392 /* CubicRoots.cpp in Sources */, + FE71325014D04D480008E392 /* CubeRoot.cpp in Sources */, + FE71325F14D050D80008E392 /* LineUtilities.cpp in Sources */, + FE71334214D06B0F0008E392 /* LineCubicIntersection_Test.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + FEF87C4113E0414D00335C58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = core; + targetProxy = FEF87C4013E0414D00335C58 /* PBXContainerItemProxy */; + }; + FEF87C4313E0415100335C58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = effects; + targetProxy = FEF87C4213E0415100335C58 /* PBXContainerItemProxy */; + }; + FEF87C4513E0415500335C58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = opts; + targetProxy = FEF87C4413E0415500335C58 /* PBXContainerItemProxy */; + }; + FEF87C4713E0415900335C58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = utils; + targetProxy = FEF87C4613E0415900335C58 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 1DDD58150DA1D0A300B32029 /* English */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = edge_Prefix.pch; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = "edge-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../../skia/xcode/core/build/Debug\"", + "\"$(SRCROOT)/../../skia/xcode/maccore/build/Debug\"", + ); + PREBINDING = NO; + PRODUCT_NAME = edge; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = edge_Prefix.pch; + INFOPLIST_FILE = "edge-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../../skia/xcode/core/build/Debug\"", + "\"$(SRCROOT)/../../skia/xcode/maccore/build/Debug\"", + ); + PRODUCT_NAME = edge; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_ENABLE_CPP_EXCEPTIONS = YES; + GCC_ENABLE_CPP_RTTI = YES; + GCC_ENABLE_SYMBOL_SEPARATION = YES; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ( + SK_BUILD_FOR_MAC, + SK_DEBUG, + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THREADSAFE_STATICS = YES; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = NO; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_PROTOTYPE_CONVERSION = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_PREPROCESS = YES; + LD_RUNPATH_SEARCH_PATHS = ""; + LIBRARY_SEARCH_PATHS = ""; + OTHER_LDFLAGS = ""; + PREBINDING = YES; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + SDKROOT = ""; + USER_HEADER_SEARCH_PATHS = "../../skia/trunk/gpu/include ../../skia/trunk/src/core ../../skia/trunk/include/** ../../skia/trunk/gm"; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "edge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "edge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +}