aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/Intersection/QuadraticImplicit.cpp
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-09 14:11:58 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-09 14:11:58 +0000
commit6aea33f92c611d6fdc88bc2352c5c966168af83b (patch)
tree0afc954993f542c618413c659d21f1680065221a /experimental/Intersection/QuadraticImplicit.cpp
parent9598f4256d729434a9e7273a7de1e4876eaacee9 (diff)
checkpoint for shape ops
at minimum, the unit tests in SimplyNew_Test pass git-svn-id: http://skia.googlecode.com/svn/trunk@5860 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental/Intersection/QuadraticImplicit.cpp')
-rw-r--r--experimental/Intersection/QuadraticImplicit.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/experimental/Intersection/QuadraticImplicit.cpp b/experimental/Intersection/QuadraticImplicit.cpp
index 835b3bf71f..268d7d3f62 100644
--- a/experimental/Intersection/QuadraticImplicit.cpp
+++ b/experimental/Intersection/QuadraticImplicit.cpp
@@ -64,7 +64,55 @@ static void addValidRoots(const double roots[4], const int count, const int side
}
}
+static bool onlyEndPtsInCommon(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
+// the idea here is to see at minimum do a quick reject by rotating all points
+// to either side of the line formed by connecting the endpoints
+// if the opposite curves points are on the line or on the other side, the
+// curves at most intersect at the endpoints
+ for (int oddMan = 0; oddMan < 3; ++oddMan) {
+ const _Point* endPt[2];
+ for (int opp = 1; opp < 3; ++opp) {
+ int end = oddMan ^ opp;
+ if (end == 3) {
+ end = opp;
+ }
+ endPt[opp - 1] = &q1[end];
+ }
+ double origX = endPt[0]->x;
+ double origY = endPt[0]->y;
+ double adj = endPt[1]->x - origX;
+ double opp = endPt[1]->y - origY;
+ double sign = (q1[oddMan].y - origY) * adj - (q1[oddMan].x - origX) * opp;
+ assert(!approximately_zero(sign));
+ for (int n = 0; n < 3; ++n) {
+ double test = (q2[n].y - origY) * adj - (q2[n].x - origX) * opp;
+ if (test * sign > 0) {
+ goto tryNextHalfPlane;
+ }
+ }
+ for (int i1 = 0; i1 < 3; i1 += 2) {
+ for (int i2 = 0; i2 < 3; i2 += 2) {
+ if (q1[i1] == q2[i2]) {
+ i.insertOne(i1 >> 1, 0);
+ i.insertOne(i2 >> 1, 1);
+ }
+ }
+ }
+ assert(i.fUsed < 3);
+ return true;
+tryNextHalfPlane:
+ ;
+ }
+ return false;
+}
+
bool intersect2(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
+ // if the quads share an end point, check to see if they overlap
+
+ if (onlyEndPtsInCommon(q1, q2, i)) {
+ assert(i.insertBalanced());
+ return i.intersected();
+ }
QuadImplicitForm i1(q1);
QuadImplicitForm i2(q2);
if (i1.implicit_match(i2)) {
@@ -100,7 +148,9 @@ bool intersect2(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
addValidRoots(roots2, rootCount, 1, i);
_Point pts[4];
bool matches[4];
+ int flipCheck[4];
int index, ndex2;
+ int flipIndex = 0;
for (ndex2 = 0; ndex2 < i.fUsed2; ++ndex2) {
xy_at_t(q2, i.fT[1][ndex2], pts[ndex2].x, pts[ndex2].y);
matches[ndex2] = false;
@@ -110,6 +160,8 @@ bool intersect2(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
xy_at_t(q1, i.fT[0][index], xy.x, xy.y);
for (ndex2 = 0; ndex2 < i.fUsed2; ++ndex2) {
if (approximately_equal(pts[ndex2].x, xy.x) && approximately_equal(pts[ndex2].y, xy.y)) {
+ assert(flipIndex < 4);
+ flipCheck[flipIndex++] = ndex2;
matches[ndex2] = true;
goto next;
}
@@ -131,6 +183,7 @@ bool intersect2(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
}
++ndex2;
}
+ i.fFlip = i.fUsed >= 2 && flipCheck[0] > flipCheck[1];
assert(i.insertBalanced());
return i.intersected();
}