aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/Intersection
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-27 21:22:25 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-27 21:22:25 +0000
commit7db7c6bba9e9a61ad574a1d60b65bce4563beee5 (patch)
tree11fd4f2acba36aa1c48ff1994890691bfaf0980e /experimental/Intersection
parent889b09edfeb5f461ca283dfd08ee6b23560a7859 (diff)
shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@4820 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental/Intersection')
-rw-r--r--experimental/Intersection/Simplify.cpp55
-rw-r--r--experimental/Intersection/SimplifyNew_Test.cpp2
2 files changed, 46 insertions, 11 deletions
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index c6236d513a..53abe8b07d 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -483,6 +483,10 @@ public:
return fDx;
}
+ double dy() const {
+ return fDy;
+ }
+
int end() const {
return fEnd;
}
@@ -1759,7 +1763,12 @@ public:
bool intersected() const {
return fTs.count() > 0;
}
-
+
+ bool isConnected(int startIndex, int endIndex) const {
+ return fTs[startIndex].fWindSum != SK_MinS32
+ || fTs[endIndex].fWindSum != SK_MinS32;
+ }
+
bool isLinear(int start, int end) const {
if (fVerb == SkPath::kLine_Verb) {
return true;
@@ -2289,9 +2298,6 @@ public:
}
bool crosses(const Contour* crosser) const {
- if (this == crosser) {
- return true;
- }
for (int index = 0; index < fCrosses.count(); ++index) {
if (fCrosses[index] == crosser) {
return true;
@@ -3035,12 +3041,14 @@ static void coincidenceCheck(SkTDArray<Contour*>& contourList, int winding) {
// two contours touch, so we need only look at contours not touching this one.
// OPTIMIZATION: sort contourList vertically to avoid linear walk
static int innerContourCheck(SkTDArray<Contour*>& contourList,
- Contour* baseContour, const SkPoint& basePt) {
+ Contour* baseContour, const Segment* current, int index, int endIndex) {
+ const SkPoint& basePt = current->xyAtT(endIndex);
int contourCount = contourList.count();
SkScalar bestY = SK_ScalarMin;
const Segment* test = NULL;
int tIndex;
double tHit;
+ bool checkCrosses = true;
for (int cTest = 0; cTest < contourCount; ++cTest) {
Contour* contour = contourList[cTest];
if (basePt.fY < contour->bounds().fTop) {
@@ -3049,8 +3057,19 @@ static int innerContourCheck(SkTDArray<Contour*>& contourList,
if (bestY > contour->bounds().fBottom) {
continue;
}
- if (baseContour->crosses(contour)) {
- continue;
+ // even though the contours crossed, if spans cancel through concidence,
+ // the contours may be not have any span links to chase, and the current
+ // segment may be isolated. Detect this by seeing if current has
+ // uninitialized wind sums. If so, project a ray instead of relying on
+ // previously found intersections.
+ if (baseContour == contour) {
+ continue;
+ }
+ if (checkCrosses && baseContour->crosses(contour)) {
+ if (current->isConnected(index, endIndex)) {
+ continue;
+ }
+ checkCrosses = false;
}
const Segment* next = contour->crossedSegment(basePt, bestY, tIndex, tHit);
if (next) {
@@ -3087,16 +3106,27 @@ static int innerContourCheck(SkTDArray<Contour*>& contourList,
// is 12 noon or an earlier hour (the next counterclockwise)
int count = sorted.count();
int left = -1;
+ int mid = -1;
int right = -1;
+ bool baseMatches = test->yAtT(tIndex) == basePt.fY;
for (int index = 0; index < count; ++index) {
- double indexDx = sorted[index]->dx();
+ const Angle* angle = sorted[index];
+ if (baseMatches && angle->isHorizontal()) {
+ continue;
+ }
+ double indexDx = angle->dx();
if (indexDx < 0) {
left = index;
} else if (indexDx > 0) {
right = index;
break;
+ } else {
+ mid = index;
}
}
+ if (left < 0 && right < 0) {
+ left = mid;
+ }
SkASSERT(left >= 0 || right >= 0);
if (left < 0) {
left = right;
@@ -3136,6 +3166,11 @@ static int innerContourCheck(SkTDArray<Contour*>& contourList,
SkDebugf("%s final winding=%d\n", __FUNCTION__, winding);
#endif
}
+ start here;
+ // we're broken because we find a vertical span
+ // also, does it make sense to compute a contour's winding? Won't it
+ // depend on coincidence and (e.g. a figure eight) self intersection?
+ // (hopefully no one uses this) so remove it
baseContour->setWinding(winding);
return winding;
}
@@ -3293,8 +3328,8 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) {
contourWinding = 0;
firstContour = false;
} else {
- const SkPoint& topPoint = current->xyAtT(endIndex);
- contourWinding = innerContourCheck(contourList, topContour, topPoint);
+ contourWinding = innerContourCheck(contourList, topContour, current,
+ index, endIndex);
#if DEBUG_WINDING
SkDebugf("%s contourWinding=%d\n", __FUNCTION__, contourWinding);
#endif
diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp
index aa475c7334..2b7d4e44da 100644
--- a/experimental/Intersection/SimplifyNew_Test.cpp
+++ b/experimental/Intersection/SimplifyNew_Test.cpp
@@ -641,7 +641,7 @@ static void testLine66() {
testSimplifyx(path);
}
-static void (*firstTest)() = testLine66;
+static void (*firstTest)() = 0;
static struct {
void (*fun)();