Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(569)

Unified Diff: src/pathops/SkDQuadLineIntersection.cpp

Issue 19183003: path ops near exact (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: remove unused static function Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkDQuadIntersection.cpp ('k') | src/pathops/SkIntersections.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkDQuadLineIntersection.cpp
diff --git a/src/pathops/SkDQuadLineIntersection.cpp b/src/pathops/SkDQuadLineIntersection.cpp
index 98e38621e07944afb71bedc31fdc8c4abd84574a..9df2dc248ab01e37b123f7b9da2dd4d408d89b12 100644
--- a/src/pathops/SkDQuadLineIntersection.cpp
+++ b/src/pathops/SkDQuadLineIntersection.cpp
@@ -92,7 +92,12 @@ public:
LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersections* i)
: quad(q)
, line(l)
- , intersections(i) {
+ , intersections(i)
+ , fAllowNear(true) {
+ }
+
+ void allowNear(bool allow) {
+ fAllowNear = allow;
}
int intersectRay(double roots[2]) {
@@ -126,7 +131,7 @@ public:
}
int intersect() {
- addEndPoints();
+ addExactEndPoints();
double rootVals[2];
int roots = intersectRay(rootVals);
for (int index = 0; index < roots; ++index) {
@@ -137,6 +142,9 @@ public:
intersections->insert(quadT, lineT, pt);
}
}
+ if (fAllowNear) {
+ addNearEndPoints();
+ }
return intersections->used();
}
@@ -151,7 +159,7 @@ public:
}
int horizontalIntersect(double axisIntercept, double left, double right, bool flipped) {
- addHorizontalEndPoints(left, right, axisIntercept);
+ addExactHorizontalEndPoints(left, right, axisIntercept);
double rootVals[2];
int roots = horizontalIntersect(axisIntercept, rootVals);
for (int index = 0; index < roots; ++index) {
@@ -162,6 +170,9 @@ public:
intersections->insert(quadT, lineT, pt);
}
}
+ if (fAllowNear) {
+ addNearHorizontalEndPoints(left, right, axisIntercept);
+ }
if (flipped) {
intersections->flip();
}
@@ -179,7 +190,7 @@ public:
}
int verticalIntersect(double axisIntercept, double top, double bottom, bool flipped) {
- addVerticalEndPoints(top, bottom, axisIntercept);
+ addExactVerticalEndPoints(top, bottom, axisIntercept);
double rootVals[2];
int roots = verticalIntersect(axisIntercept, rootVals);
for (int index = 0; index < roots; ++index) {
@@ -190,6 +201,9 @@ public:
intersections->insert(quadT, lineT, pt);
}
}
+ if (fAllowNear) {
+ addNearVerticalEndPoints(top, bottom, axisIntercept);
+ }
if (flipped) {
intersections->flip();
}
@@ -198,73 +212,88 @@ public:
protected:
// add endpoints first to get zero and one t values exactly
- void addEndPoints() {
+ void addExactEndPoints() {
for (int qIndex = 0; qIndex < 3; qIndex += 2) {
- bool foundEnd = false;
- for (int lIndex = 0; lIndex < 2; lIndex++) {
- if (quad[qIndex] == line[lIndex]) {
- intersections->insert(qIndex >> 1, lIndex, line[lIndex]);
- foundEnd = true;
- }
- }
- if (foundEnd) {
+ double lineT = line.exactPoint(quad[qIndex]);
+ if (lineT < 0) {
continue;
}
- // See if the quad end touches the line.
- double dist = line.isLeft(quad[qIndex]); // this distance isn't cartesian
- SkDVector lineLen = line[1] - line[0]; // the x/y magnitudes of the line
- // compute the ULPS of the larger of the x/y deltas
- double larger = SkTMax(SkTAbs(lineLen.fX), SkTAbs(lineLen.fY));
- if (!RoughlyEqualUlps(larger, larger + dist)) { // is the dist within ULPS tolerance?
+ double quadT = (double) (qIndex >> 1);
+ intersections->insert(quadT, lineT, quad[qIndex]);
+ }
+ }
+
+ void addNearEndPoints() {
+ for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+ double quadT = (double) (qIndex >> 1);
+ if (intersections->hasT(quadT)) {
continue;
}
- double lineT = findLineT(qIndex >> 1);
- if (!between(0, lineT, 1)) {
+ double lineT = line.nearPoint(quad[qIndex]);
+ if (lineT < 0) {
continue;
}
- SkDPoint linePt = line.xyAtT(lineT);
- if (linePt.approximatelyEqual(quad[qIndex])) {
- intersections->insert(qIndex >> 1, lineT, quad[qIndex]);
+ intersections->insert(quadT, lineT, quad[qIndex]);
+ }
+ // FIXME: see if line end is nearly on quad
+ }
+
+ void addExactHorizontalEndPoints(double left, double right, double y) {
+ for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+ double lineT = SkDLine::ExactPointH(quad[qIndex], left, right, y);
+ if (lineT < 0) {
+ continue;
}
+ double quadT = (double) (qIndex >> 1);
+ intersections->insert(quadT, lineT, quad[qIndex]);
}
}
- void addHorizontalEndPoints(double left, double right, double y) {
+ void addNearHorizontalEndPoints(double left, double right, double y) {
for (int qIndex = 0; qIndex < 3; qIndex += 2) {
- if (!AlmostEqualUlps(quad[qIndex].fY, y)) {
+ double quadT = (double) (qIndex >> 1);
+ if (intersections->hasT(quadT)) {
continue;
}
- double x = quad[qIndex].fX;
- if (between(left, x, right)) {
- double t = (x - left) / (right - left);
- intersections->insert(qIndex >> 1, t, quad[qIndex]);
+ double lineT = SkDLine::NearPointH(quad[qIndex], left, right, y);
+ if (lineT < 0) {
+ continue;
}
+ intersections->insert(quadT, lineT, quad[qIndex]);
}
+ // FIXME: see if line end is nearly on quad
}
- void addVerticalEndPoints(double top, double bottom, double x) {
+ void addExactVerticalEndPoints(double top, double bottom, double x) {
for (int qIndex = 0; qIndex < 3; qIndex += 2) {
- if (!AlmostEqualUlps(quad[qIndex].fX, x)) {
+ double lineT = SkDLine::ExactPointV(quad[qIndex], top, bottom, x);
+ if (lineT < 0) {
continue;
}
- double y = quad[qIndex].fY;
- if (between(top, y, bottom)) {
- double t = (y - top) / (bottom - top);
- intersections->insert(qIndex >> 1, t, quad[qIndex]);
+ double quadT = (double) (qIndex >> 1);
+ intersections->insert(quadT, lineT, quad[qIndex]);
+ }
+ }
+
+ void addNearVerticalEndPoints(double top, double bottom, double x) {
+ for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+ double quadT = (double) (qIndex >> 1);
+ if (intersections->hasT(quadT)) {
+ continue;
+ }
+ double lineT = SkDLine::NearPointV(quad[qIndex], top, bottom, x);
+ if (lineT < 0) {
+ continue;
}
+ intersections->insert(quadT, lineT, quad[qIndex]);
}
+ // FIXME: see if line end is nearly on quad
}
double findLineT(double t) {
SkDPoint xy = quad.xyAtT(t);
double dx = line[1].fX - line[0].fX;
double dy = line[1].fY - line[0].fY;
-#if 0
- if (fabs(dx) > fabs(dy)) {
- return (xy.fX - line[0].fX) / dx;
- }
- return (xy.fY - line[0].fY) / dy;
-#else
double dxT = (xy.fX - line[0].fX) / dx;
double dyT = (xy.fY - line[0].fY) / dy;
if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) {
@@ -274,7 +303,6 @@ protected:
return dxT;
}
return fabs(dx) > fabs(dy) ? dxT : dyT;
-#endif
}
static bool PinTs(double* quadT, double* lineT) {
@@ -284,16 +312,8 @@ protected:
if (!approximately_zero_or_more(*lineT)) {
return false;
}
- if (precisely_less_than_zero(*quadT)) {
- *quadT = 0;
- } else if (precisely_greater_than_one(*quadT)) {
- *quadT = 1;
- }
- if (precisely_less_than_zero(*lineT)) {
- *lineT = 0;
- } else if (precisely_greater_than_one(*lineT)) {
- *lineT = 1;
- }
+ *quadT = SkPinT(*quadT);
+ *lineT = SkPinT(*lineT);
return true;
}
@@ -301,6 +321,7 @@ private:
const SkDQuad& quad;
const SkDLine& line;
SkIntersections* intersections;
+ bool fAllowNear;
};
// utility for pairs of coincident quads
@@ -355,6 +376,7 @@ int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) {
LineQuadraticIntersections q(quad, line, this);
+ q.allowNear(fAllowNear);
return q.intersect();
}
« no previous file with comments | « src/pathops/SkDQuadIntersection.cpp ('k') | src/pathops/SkIntersections.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698