| Index: src/pathops/SkDLineIntersection.cpp
|
| diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
|
| index ed96b9c5d7997033d92f4e1c630c50e2814546e6..8fc673f2fb80e36558df1ae889a82863e6e05975 100644
|
| --- a/src/pathops/SkDLineIntersection.cpp
|
| +++ b/src/pathops/SkDLineIntersection.cpp
|
| @@ -7,6 +7,45 @@
|
| #include "SkIntersections.h"
|
| #include "SkPathOpsLine.h"
|
|
|
| +/* Determine the intersection point of two lines. This assumes the lines are not parallel,
|
| + and that that the lines are infinite.
|
| + From http://en.wikipedia.org/wiki/Line-line_intersection
|
| + */
|
| +SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) {
|
| + double axLen = a[1].fX - a[0].fX;
|
| + double ayLen = a[1].fY - a[0].fY;
|
| + double bxLen = b[1].fX - b[0].fX;
|
| + double byLen = b[1].fY - b[0].fY;
|
| + double denom = byLen * axLen - ayLen * bxLen;
|
| + SkASSERT(denom);
|
| + double term1 = a[1].fX * a[0].fY - a[1].fY * a[0].fX;
|
| + double term2 = b[1].fX * b[0].fY - b[1].fY * b[0].fX;
|
| + SkDPoint p;
|
| + p.fX = (term1 * bxLen - axLen * term2) / denom;
|
| + p.fY = (term1 * byLen - ayLen * term2) / denom;
|
| + return p;
|
| +}
|
| +
|
| +int SkIntersections::cleanUpCoincidence() {
|
| + do {
|
| + int last = fUsed - 1;
|
| + for (int index = 0; index < last; ++index) {
|
| + if (fT[0][index] == fT[0][index + 1]) {
|
| + removeOne(index + (int) (fT[1][index] == 0 || fT[1][index] == 1));
|
| + goto tryAgain;
|
| + }
|
| + }
|
| + for (int index = 0; index < last; ++index) {
|
| + if (fT[1][index] == fT[1][index + 1]) {
|
| + removeOne(index + (int) (fT[0][index] == 0 || fT[0][index] == 1));
|
| + goto tryAgain;
|
| + }
|
| + }
|
| + return fUsed;
|
| +tryAgain: ;
|
| + } while (true);
|
| +}
|
| +
|
| void SkIntersections::cleanUpParallelLines(bool parallel) {
|
| while (fUsed > 2) {
|
| removeOne(1);
|
| @@ -18,9 +57,6 @@
|
| SkASSERT(startMatch || endMatch);
|
| removeOne(endMatch);
|
| }
|
| - }
|
| - if (fUsed == 2) {
|
| - fIsCoincident[0] = fIsCoincident[1] = 0x03;
|
| }
|
| }
|
|
|
| @@ -45,6 +81,12 @@
|
| SkDVector ab0 = a[0] - b[0];
|
| double numerA = ab0.fY * bLen.fX - bLen.fY * ab0.fX;
|
| double numerB = ab0.fY * aLen.fX - aLen.fY * ab0.fX;
|
| +#if 0
|
| + if (!between(0, numerA, denom) || !between(0, numerB, denom)) {
|
| + fUsed = 0;
|
| + return 0;
|
| + }
|
| +#endif
|
| numerA /= denom;
|
| numerB /= denom;
|
| int used;
|
| @@ -148,6 +190,7 @@
|
| }
|
| SkASSERT(a[iA] != b[nearer]);
|
| SkASSERT(iA == (bNearA[nearer] > 0.5));
|
| + fNearlySame[iA] = true;
|
| insertNear(iA, nearer, a[iA], b[nearer]);
|
| aNearB[iA] = -1;
|
| bNearA[nearer] = -1;
|
| @@ -190,6 +233,18 @@
|
|
|
| static double horizontal_intercept(const SkDLine& line, double y) {
|
| return SkPinT((y - line[0].fY) / (line[1].fY - line[0].fY));
|
| +}
|
| +
|
| +int SkIntersections::horizontal(const SkDLine& line, double y) {
|
| + fMax = 2;
|
| + int horizontalType = horizontal_coincident(line, y);
|
| + if (horizontalType == 1) {
|
| + fT[0][0] = horizontal_intercept(line, y);
|
| + } else if (horizontalType == 2) {
|
| + fT[0][0] = 0;
|
| + fT[0][1] = 1;
|
| + }
|
| + return fUsed = horizontalType;
|
| }
|
|
|
| int SkIntersections::horizontal(const SkDLine& line, double left, double right,
|
| @@ -268,6 +323,18 @@
|
| return SkPinT((x - line[0].fX) / (line[1].fX - line[0].fX));
|
| }
|
|
|
| +int SkIntersections::vertical(const SkDLine& line, double x) {
|
| + fMax = 2;
|
| + int verticalType = vertical_coincident(line, x);
|
| + if (verticalType == 1) {
|
| + fT[0][0] = vertical_intercept(line, x);
|
| + } else if (verticalType == 2) {
|
| + fT[0][0] = 0;
|
| + fT[0][1] = 1;
|
| + }
|
| + return fUsed = verticalType;
|
| +}
|
| +
|
| int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
|
| double x, bool flipped) {
|
| fMax = 3; // cleanup parallel lines will bring this back line
|
| @@ -326,3 +393,14 @@
|
| return fUsed;
|
| }
|
|
|
| +// from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.py
|
| +// 4 subs, 2 muls, 1 cmp
|
| +static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) {
|
| + return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX);
|
| +}
|
| +
|
| +// 16 subs, 8 muls, 6 cmps
|
| +bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) {
|
| + return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1])
|
| + && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]);
|
| +}
|
|
|