| Index: src/pathops/SkPathOpsLine.cpp
|
| diff --git a/src/pathops/SkPathOpsLine.cpp b/src/pathops/SkPathOpsLine.cpp
|
| index 48c042a7facbb7ecfe525669662bdf7649e1b17a..1b548fcd30b20e4f59729808239585a37095fb2c 100644
|
| --- a/src/pathops/SkPathOpsLine.cpp
|
| +++ b/src/pathops/SkPathOpsLine.cpp
|
| @@ -78,9 +78,7 @@ double SkDLine::nearPoint(const SkDPoint& xy) const {
|
| }
|
| double t = numer / denom;
|
| SkDPoint realPt = ptAtT(t);
|
| - SkDVector distU = xy - realPt;
|
| - double distSq = distU.fX * distU.fX + distU.fY * distU.fY;
|
| - double dist = sqrt(distSq); // OPTIMIZATION: can we compare against distSq instead ?
|
| + double dist = realPt.distance(xy); // OPTIMIZATION: can we compare against distSq instead ?
|
| // find the ordinal in the original line with the largest unsigned exponent
|
| double tiniest = SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
|
| double largest = SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
|
| @@ -93,6 +91,35 @@ double SkDLine::nearPoint(const SkDPoint& xy) const {
|
| return t;
|
| }
|
|
|
| +bool SkDLine::nearRay(const SkDPoint& xy) const {
|
| + // project a perpendicular ray from the point to the line; find the T on the line
|
| + SkDVector len = fPts[1] - fPts[0]; // the x/y magnitudes of the line
|
| + double denom = len.fX * len.fX + len.fY * len.fY; // see DLine intersectRay
|
| + SkDVector ab0 = xy - fPts[0];
|
| + double numer = len.fX * ab0.fX + ab0.fY * len.fY;
|
| + double t = numer / denom;
|
| + SkDPoint realPt = ptAtT(t);
|
| + double dist = realPt.distance(xy); // OPTIMIZATION: can we compare against distSq instead ?
|
| + // find the ordinal in the original line with the largest unsigned exponent
|
| + double tiniest = SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
|
| + double largest = SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
|
| + largest = SkTMax(largest, -tiniest);
|
| + return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance?
|
| +}
|
| +
|
| +// Returns true if a ray from (0,0) to (x1,y1) is coincident with a ray (0,0) to (x2,y2)
|
| +// OPTIMIZE: a specialty routine could speed this up -- may not be called very often though
|
| +bool SkDLine::NearRay(double x1, double y1, double x2, double y2) {
|
| + double denom1 = x1 * x1 + y1 * y1;
|
| + double denom2 = x2 * x2 + y2 * y2;
|
| + SkDLine line = {{{0, 0}, {x1, y1}}};
|
| + SkDPoint pt = {x2, y2};
|
| + if (denom2 > denom1) {
|
| + SkTSwap(line[1], pt);
|
| + }
|
| + return line.nearRay(pt);
|
| +}
|
| +
|
| double SkDLine::ExactPointH(const SkDPoint& xy, double left, double right, double y) {
|
| if (xy.fY == y) {
|
| if (xy.fX == left) {
|
| @@ -106,7 +133,7 @@ double SkDLine::ExactPointH(const SkDPoint& xy, double left, double right, doubl
|
| }
|
|
|
| double SkDLine::NearPointH(const SkDPoint& xy, double left, double right, double y) {
|
| - if (!AlmostEqualUlps(xy.fY, y)) {
|
| + if (!AlmostBequalUlps(xy.fY, y)) {
|
| return -1;
|
| }
|
| if (!AlmostBetweenUlps(left, xy.fX, right)) {
|
| @@ -115,6 +142,18 @@ double SkDLine::NearPointH(const SkDPoint& xy, double left, double right, double
|
| double t = (xy.fX - left) / (right - left);
|
| t = SkPinT(t);
|
| SkASSERT(between(0, t, 1));
|
| + double realPtX = (1 - t) * left + t * right;
|
| + SkDVector distU = {xy.fY - y, xy.fX - realPtX};
|
| + double distSq = distU.fX * distU.fX + distU.fY * distU.fY;
|
| + double dist = sqrt(distSq); // OPTIMIZATION: can we compare against distSq instead ?
|
| + double tiniest = SkTMin(SkTMin(y, left), right);
|
| + double largest = SkTMax(SkTMax(y, left), right);
|
| + largest = SkTMax(largest, -tiniest);
|
| + if (!AlmostEqualUlps(largest, largest + dist)) { // is the dist within ULPS tolerance?
|
| + return -1;
|
| + }
|
| + t = SkPinT(t);
|
| + SkASSERT(between(0, t, 1));
|
| return t;
|
| }
|
|
|
| @@ -131,7 +170,7 @@ double SkDLine::ExactPointV(const SkDPoint& xy, double top, double bottom, doubl
|
| }
|
|
|
| double SkDLine::NearPointV(const SkDPoint& xy, double top, double bottom, double x) {
|
| - if (!AlmostEqualUlps(xy.fX, x)) {
|
| + if (!AlmostBequalUlps(xy.fX, x)) {
|
| return -1;
|
| }
|
| if (!AlmostBetweenUlps(top, xy.fY, bottom)) {
|
| @@ -140,5 +179,27 @@ double SkDLine::NearPointV(const SkDPoint& xy, double top, double bottom, double
|
| double t = (xy.fY - top) / (bottom - top);
|
| t = SkPinT(t);
|
| SkASSERT(between(0, t, 1));
|
| + double realPtY = (1 - t) * top + t * bottom;
|
| + SkDVector distU = {xy.fX - x, xy.fY - realPtY};
|
| + double distSq = distU.fX * distU.fX + distU.fY * distU.fY;
|
| + double dist = sqrt(distSq); // OPTIMIZATION: can we compare against distSq instead ?
|
| + double tiniest = SkTMin(SkTMin(x, top), bottom);
|
| + double largest = SkTMax(SkTMax(x, top), bottom);
|
| + largest = SkTMax(largest, -tiniest);
|
| + if (!AlmostEqualUlps(largest, largest + dist)) { // is the dist within ULPS tolerance?
|
| + return -1;
|
| + }
|
| + t = SkPinT(t);
|
| + SkASSERT(between(0, t, 1));
|
| return t;
|
| }
|
| +
|
| +#ifdef SK_DEBUG
|
| +void SkDLine::dump() {
|
| + SkDebugf("{{");
|
| + fPts[0].dump();
|
| + SkDebugf(", ");
|
| + fPts[1].dump();
|
| + SkDebugf("}}\n");
|
| +}
|
| +#endif
|
|
|