#include "CubicIntersection.h"
-#include "CubicIntersection_Tests.h"
+#include "Intersection_Tests.h"
#include "IntersectionUtilities.h"
const Cubic convex[] = {
//
#include <math.h>
-#include "CubicIntersection.h"
+#include "CubicUtilities.h"
#define TEST_ALTERNATIVES 0
#if TEST_ALTERNATIVES
#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];
+++ /dev/null
-/*
- 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
-
-
-
- */
-
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& );
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;
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;
}
#include "CubicIntersection.h"
#include "CubicIntersection_TestData.h"
-#include "CubicIntersection_Tests.h"
+#include "Intersection_Tests.h"
#include "Intersections.h"
#include "TestUtilities.h"
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);
}
}
}
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
};
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]);
-
-
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;
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;
+++ /dev/null
-#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();
-}
+++ /dev/null
-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();
/* 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 ==
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
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);
result.y = tangent(&cubic[0].y, t);
}
+// unit test to return and validate parametric coefficients
+#include "CubicParameterization_TestUtility.cpp"
+
+
* 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 - "
" 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 {
typedef std::vector<coeff> coeffs;
typedef std::vector<coeffs> 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
#include "CubicIntersection.h"
-#include "CubicIntersection_Tests.h"
+#include "Intersection_Tests.h"
#include "TestUtilities.h"
const Quadratic quadratics[] = {
}
}
}
+
+// 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);
+ }
+ }
+ }
+}
--- /dev/null
+// 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);
+}
--- /dev/null
+#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);
+ }
+
+ }
+ }
+}
-#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
if (is_unit_interval(r))
*roots++ = r;
}
- return (int)(roots - tValues);
+ return (int)(roots - t);
}
--- /dev/null
+double cube_root(double x);
+int cubicRoots(double A, double B, double C, double D, double t[3]);
#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* );
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();
}
#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) {
--- /dev/null
+#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();
+}
--- /dev/null
+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();
--- /dev/null
+#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();
+}
--- /dev/null
+#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);
+ }
+ }
+ }
+ }
+ }
+}
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);
#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}}},
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);
}
}
--- /dev/null
+#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();
+}
--- /dev/null
+#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);
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#include "DataTypes.h"
+
+bool implicitLine(const _Line& line, double& slope, double& axisIntercept);
+int reduceOrder(const _Line& line, _Line& reduced);
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
}
-
-/*
- * 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);
+ }
+ }
+}
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
--- /dev/null
+#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);
+ }
+ }
+ }
+ }
+ }
+}
+
#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]);
-/*
- * 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;
result.y = tangent(&quadratic[0].y, t);
}
+// unit test to return and validate parametric coefficients
+#include "QuadraticParameterization_TestUtility.cpp"
#include "CubicIntersection.h"
-#include "CubicIntersection_Tests.h"
+#include "Intersection_Tests.h"
const Quadratic quadratics[] = {
{{0, 0}, {1, 0}, {1, 1}},
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);
+ }
+ }
}
}
}
--- /dev/null
+// 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);
+}
--- /dev/null
+#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);
+ }
+ }
+}
--- /dev/null
+#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;
+}
+
+
* 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
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]);
#include "CubicIntersection.h"
#include "CubicIntersection_TestData.h"
#include "CubicIntersection_Tests.h"
+#include "QuadraticIntersection_TestData.h"
#include "TestUtilities.h"
void ReduceOrder_Test() {
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;
+}
+
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);
--- /dev/null
+// !$*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 = "<group>"; };
+ 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ 256AC3F00F4B6AF500CF3369 /* edge_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edge_Prefix.pch; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* edge-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "edge-Info.plist"; sourceTree = "<group>"; };
+ 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 = "<group>"; };
+ FE7130A014CE0EEB0008E392 /* LineQuadraticIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineQuadraticIntersection.cpp; sourceTree = "<group>"; };
+ FE7131C314CF5A960008E392 /* LineQuadraticIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineQuadraticIntersection_Test.cpp; sourceTree = "<group>"; };
+ FE7131ED14D03AED0008E392 /* LineCubicIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineCubicIntersection.cpp; sourceTree = "<group>"; };
+ FE71324114D047670008E392 /* QuadraticUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticUtilities.cpp; sourceTree = "<group>"; };
+ FE71325114D04D7A0008E392 /* CubicUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicUtilities.h; sourceTree = "<group>"; };
+ FE71325D14D050D80008E392 /* LineUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineUtilities.h; sourceTree = "<group>"; };
+ FE71325E14D050D80008E392 /* LineUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineUtilities.cpp; sourceTree = "<group>"; };
+ FE71334114D06B0F0008E392 /* LineCubicIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineCubicIntersection_Test.cpp; sourceTree = "<group>"; };
+ 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 = "<group>"; };
+ FEA670F113C49E2200FE6FC1 /* SkAntiEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkAntiEdge.h; sourceTree = "<group>"; };
+ 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 = "<group>"; };
+ FEC117CB14843B0A0086BF1F /* CubicBezierClip_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicBezierClip_Test.cpp; sourceTree = "<group>"; };
+ FEC118B7148666670086BF1F /* ConvexHull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvexHull.cpp; sourceTree = "<group>"; };
+ FEC118C1148668F30086BF1F /* DataTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataTypes.cpp; sourceTree = "<group>"; };
+ FEC11910148682200086BF1F /* CubicReduceOrder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicReduceOrder.cpp; sourceTree = "<group>"; };
+ FEC1191A148683330086BF1F /* Extrema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Extrema.cpp; sourceTree = "<group>"; };
+ FEC1191E148683850086BF1F /* Extrema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extrema.h; sourceTree = "<group>"; };
+ FEC1195314869DC90086BF1F /* LineIntersection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineIntersection.h; sourceTree = "<group>"; };
+ FEC1195414869DC90086BF1F /* LineIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineIntersection.cpp; sourceTree = "<group>"; };
+ FEC11A821487D23E0086BF1F /* Intersections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Intersections.h; sourceTree = "<group>"; };
+ FEC11A851487D2650086BF1F /* LineParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineParameters.h; sourceTree = "<group>"; };
+ FEC11A881487D2F50086BF1F /* IntersectionUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntersectionUtilities.h; sourceTree = "<group>"; };
+ FEC11E3D148D65780086BF1F /* CubicSubDivide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicSubDivide.cpp; sourceTree = "<group>"; };
+ 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 = "<group>"; };
+ FEC1211A148EB5200086BF1F /* CubicBezierClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicBezierClip.cpp; sourceTree = "<group>"; };
+ FEC1238E149000100086BF1F /* LineParameteters_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineParameteters_Test.cpp; sourceTree = "<group>"; };
+ FEC12CDF14913E650086BF1F /* LineIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineIntersection_Test.cpp; sourceTree = "<group>"; };
+ FECA983F14AA044100B35E2C /* CubicParameterization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization.cpp; sourceTree = "<group>"; };
+ FECA985014AA046600B35E2C /* QuadraticParameterization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization.cpp; sourceTree = "<group>"; };
+ FECA986114AA2E5900B35E2C /* QuadraticParameterization_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization_Test.cpp; sourceTree = "<group>"; };
+ FECA987714AA319300B35E2C /* QuadraticSubDivide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticSubDivide.cpp; sourceTree = "<group>"; };
+ FECA997B14AB966900B35E2C /* CubicParameterizationCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterizationCode.cpp; sourceTree = "<group>"; };
+ FECA9A5914B3B09100B35E2C /* CubicParameterization_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization_Test.cpp; sourceTree = "<group>"; };
+ FECAA52114BB527000B35E2C /* QuadraticIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection.cpp; sourceTree = "<group>"; };
+ FECAA52B14BB6B0900B35E2C /* QuadraticUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuadraticUtilities.h; sourceTree = "<group>"; };
+ FECAA53014BB934700B35E2C /* CubeRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubeRoot.cpp; sourceTree = "<group>"; };
+ FECAA54114BC838600B35E2C /* CubicRoots.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicRoots.cpp; sourceTree = "<group>"; };
+ FECAA56C14BCA23200B35E2C /* QuadraticReduceOrder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticReduceOrder.cpp; sourceTree = "<group>"; };
+ FECAA58314BCBD4E00B35E2C /* QuadraticBezierClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticBezierClip.cpp; sourceTree = "<group>"; };
+ FECAA67814BCDBD600B35E2C /* QuadraticBezierClip_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticBezierClip_Test.cpp; sourceTree = "<group>"; };
+ FECAA68314BCDE2600B35E2C /* QuadraticIntersection_TestData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuadraticIntersection_TestData.h; sourceTree = "<group>"; };
+ FECAA68414BCDE2600B35E2C /* QuadraticIntersection_TestData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection_TestData.cpp; sourceTree = "<group>"; };
+ FECAA6C614BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticIntersection_Test.cpp; sourceTree = "<group>"; };
+ FECAA6E014BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticReduceOrder_Test.cpp; sourceTree = "<group>"; };
+ FECAAB7F14BDFAFD00B35E2C /* CubicParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization_TestUtility.cpp; sourceTree = "<group>"; };
+ FECAACA614BE1C6100B35E2C /* QuadraticParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization_TestUtility.cpp; sourceTree = "<group>"; };
+ FED53C381483CB9400F6359E /* Inline_Tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inline_Tests.cpp; sourceTree = "<group>"; };
+ FEE103331416542A006952D6 /* CubicIntersection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection.cpp; sourceTree = "<group>"; };
+ 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 = "<absolute>"; };
+ FEED75DC144DD6590059E97B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
+ FEED75DE144DD6840059E97B /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+ FEED7625144F22E20059E97B /* CubicReduceOrder_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicReduceOrder_Test.cpp; sourceTree = "<group>"; };
+ FEED762B144F236C0059E97B /* CubicIntersection_TestData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection_TestData.cpp; sourceTree = "<group>"; };
+ FEED762F144F23CA0059E97B /* CubicIntersection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicIntersection.h; sourceTree = "<group>"; };
+ FEED7632144F25150059E97B /* CubicIntersection_TestData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubicIntersection_TestData.h; sourceTree = "<group>"; };
+ FEED764B144F29BD0059E97B /* TestUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestUtilities.cpp; sourceTree = "<group>"; };
+ FEED764F144F2A160059E97B /* DataTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTypes.h; sourceTree = "<group>"; };
+ FEED7673144F2D770059E97B /* TestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestUtilities.h; sourceTree = "<group>"; };
+ FEED7680144F2E480059E97B /* Intersection_Tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Intersection_Tests.h; sourceTree = "<group>"; };
+ FEED7689144F2E7D0059E97B /* CubicIntersection_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicIntersection_Test.cpp; sourceTree = "<group>"; };
+ FEED76C0144F3E7F0059E97B /* ConvexHull_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvexHull_Test.cpp; sourceTree = "<group>"; };
+ FEED76ED144F66E90059E97B /* Intersection_Tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Intersection_Tests.cpp; sourceTree = "<group>"; };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107310486CEB800E47090 /* edge-Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ 1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ FEA5F4DA1497FFF6005052F9 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEA5F4E11497FFF6005052F9 /* libports.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ FEC123A7149001B20086BF1F /* AntiEdge */ = {
+ isa = PBXGroup;
+ children = (
+ FEA670F113C49E2200FE6FC1 /* SkAntiEdge.h */,
+ FEA670F013C49E2200FE6FC1 /* SkAntiEdge.cpp */,
+ 256AC3F00F4B6AF500CF3369 /* edge_Prefix.pch */,
+ FEA6778213C4B3A300FE6FC1 /* EdgeApp.cpp */,
+ );
+ name = AntiEdge;
+ sourceTree = "<group>";
+ };
+ FEED725E144DD38D0059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED7262144DD38D0059E97B /* libviews.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED7264144DD3EA0059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED7268144DD3EA0059E97B /* libanimator.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED726A144DD4050059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED726E144DD4050059E97B /* libexperimental.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED7270144DD4140059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED7276144DD4140059E97B /* libskgr.a */,
+ FEED7278144DD4140059E97B /* libgr.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED727A144DD4200059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED727E144DD4200059E97B /* libimages.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED7280144DD4300059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED7284144DD4300059E97B /* libtess.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED7286144DD4440059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED728A144DD4440059E97B /* libpdf.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED728C144DD44D0059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED7290144DD44D0059E97B /* libsvg.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEED729D144DD4A80059E97B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEED72A1144DD4A80059E97B /* libxml.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEF87C1313E040E000335C58 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEF87C1A13E040E000335C58 /* libcore.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEF87C1C13E040F100335C58 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEF87C2313E040F100335C58 /* libeffects.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEF87C2513E0410900335C58 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEF87C2C13E0410900335C58 /* libopts.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FEF87C3413E0412600335C58 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FEF87C3B13E0412600335C58 /* libutils.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* 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 = "<group>";
+ };
+ 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 1DDD58150DA1D0A300B32029 /* English */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "<group>";
+ };
+/* 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 */;
+}