shape ops work in progress
this fixes quad/line intersection
git-svn-id: http://skia.googlecode.com/svn/trunk@5277 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index 5a026c8..103c534 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -25,9 +25,17 @@
int gDebugMaxWindValue = SK_MaxS32;
#endif
+#define HIGH_DEF_ANGLES 1
+
+#if HIGH_DEF_ANGLES
+typedef double AngleValue;
+#else
+typedef SkScalar AngleValue;
+#endif
+
#define DEBUG_UNUSED 0 // set to expose unused functions
-#if 0 // set to 1 for multiple thread -- no debugging
+#if 1 // set to 1 for multiple thread -- no debugging
const bool gRunTestsInOneThread = false;
@@ -51,11 +59,11 @@
#define DEBUG_ACTIVE_SPANS 1
#define DEBUG_ADD_INTERSECTING_TS 0
#define DEBUG_ADD_T_PAIR 0
-#define DEBUG_ANGLE 0
-#define DEBUG_CONCIDENT 0
+#define DEBUG_ANGLE 1
+#define DEBUG_CONCIDENT 1
#define DEBUG_CROSS 0
#define DEBUG_DUMP 1
-#define DEBUG_MARK_DONE 0
+#define DEBUG_MARK_DONE 1
#define DEBUG_PATH_CONSTRUCTION 1
#define DEBUG_SORT 1
#define DEBUG_WIND_BUMP 0
@@ -90,8 +98,7 @@
Intersections& intersections) {
const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
const _Line bLine = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}};
- intersect(aQuad, bLine, intersections);
- return intersections.fUsed;
+ return intersect(aQuad, bLine, intersections);
}
static int CubicLineIntersect(const SkPoint a[2], const SkPoint b[3],
@@ -331,6 +338,46 @@
CubicSubDivide
};
+static void LineSubDivideHD(const SkPoint a[2], double startT, double endT,
+ _Point sub[]) {
+ const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
+ _Line dst;
+ sub_divide(aLine, startT, endT, dst);
+ sub[0] = dst[0];
+ sub[1] = dst[1];
+}
+
+static void QuadSubDivideHD(const SkPoint a[3], double startT, double endT,
+ _Point sub[]) {
+ const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
+ {a[2].fX, a[2].fY}};
+ Quadratic dst;
+ sub_divide(aQuad, startT, endT, dst);
+ sub[0] = dst[0];
+ sub[1] = dst[1];
+ sub[2] = dst[2];
+}
+
+static void CubicSubDivideHD(const SkPoint a[4], double startT, double endT,
+ _Point sub[]) {
+ const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
+ {a[2].fX, a[2].fY}, {a[3].fX, a[3].fY}};
+ Cubic dst;
+ sub_divide(aCubic, startT, endT, dst);
+ sub[0] = dst[0];
+ sub[1] = dst[1];
+ sub[2] = dst[2];
+ sub[3] = dst[3];
+}
+
+static void (* const SegmentSubDivideHD[])(const SkPoint [], double , double ,
+ _Point [] ) = {
+ NULL,
+ LineSubDivideHD,
+ QuadSubDivideHD,
+ CubicSubDivideHD
+};
+
#if DEBUG_UNUSED
static void QuadSubBounds(const SkPoint a[3], double startT, double endT,
SkRect& bounds) {
@@ -456,17 +503,17 @@
if (fDy == 0 && rh.fDy == 0 && fDx * rh.fDx < 0) {
return fDx < rh.fDx;
}
- SkScalar cmp = fDx * rh.fDy - rh.fDx * fDy;
+ AngleValue cmp = fDx * rh.fDy - rh.fDx * fDy;
if (!approximately_zero(cmp)) {
return cmp < 0;
}
- SkScalar dy = approximately_pin(fDy + fDDy);
- SkScalar rdy = approximately_pin(rh.fDy + rh.fDDy);
+ AngleValue dy = approximately_pin(fDy + fDDy);
+ AngleValue rdy = approximately_pin(rh.fDy + rh.fDDy);
if (dy * rdy < 0) {
return dy < 0;
}
- SkScalar dx = approximately_pin(fDx + fDDx);
- SkScalar rdx = approximately_pin(rh.fDx + rh.fDDx);
+ AngleValue dx = approximately_pin(fDx + fDDx);
+ AngleValue rdx = approximately_pin(rh.fDx + rh.fDDx);
if (dy == 0 && rdy == 0 && dx * rdx < 0) {
return dx < rdx;
}
@@ -502,7 +549,33 @@
bool isHorizontal() const {
return fDy == 0 && fDDy == 0 && fDDDy == 0;
}
+
+ // high precision version
+#if HIGH_DEF_ANGLES
+ void set(const SkPoint* orig, SkPath::Verb verb, const Segment* segment,
+ int start, int end, double startT, double endT) {
+ Cubic pts;
+ (*SegmentSubDivideHD[verb])(orig, startT, endT, pts);
+ fSegment = segment;
+ fStart = start;
+ fEnd = end;
+ fDx = approximately_pin(pts[1].x - pts[0].x); // b - a
+ fDy = approximately_pin(pts[1].y - pts[0].y);
+ if (verb == SkPath::kLine_Verb) {
+ fDDx = fDDy = fDDDx = fDDDy = 0;
+ return;
+ }
+ fDDx = approximately_pin(pts[2].x - pts[1].x - fDx); // a - 2b + c
+ fDDy = approximately_pin(pts[2].y - pts[1].y - fDy);
+ if (verb == SkPath::kQuad_Verb) {
+ fDDDx = fDDDy = 0;
+ return;
+ }
+ fDDDx = approximately_pin(pts[3].x + 3 * (pts[1].x - pts[2].x) - pts[0].x);
+ fDDDy = approximately_pin(pts[3].y + 3 * (pts[1].y - pts[2].y) - pts[0].y);
+ }
+#else
// since all angles share a point, this needs to know which point
// is the common origin, i.e., whether the center is at pts[0] or pts[verb]
// practically, this should only be called by addAngle
@@ -575,6 +648,7 @@
}
SkASSERT(0); // FIXME: add cubic case
}
+#endif
Segment* segment() const {
return const_cast<Segment*>(fSegment);
@@ -590,36 +664,42 @@
#if DEBUG_ANGLE
void debugShow(const SkPoint& a) const {
- SkDebugf(" d=(%1.9g,%1.9g) dd=(%1.9g,%1.9g) ddd=(%1.9g,%1.9g)",
+ SkDebugf(" d=(%1.9g,%1.9g) dd=(%1.9g,%1.9g) ddd=(%1.9g,%1.9g)\n",
fDx, fDy, fDDx, fDDy, fDDDx, fDDDy);
- SkPoint b, c, d;
- b.fX = a.fX + fDx; // add b - a
- b.fY = a.fY + fDy;
- c.fX = a.fX + 2 * fDx + fDDx; // add a + 2(b - a) to a - 2b + c
- c.fY = a.fY + 2 * fDy + fDDy;
+ AngleValue ax = (AngleValue) a.fX;
+ AngleValue ay = (AngleValue) a.fY;
+ AngleValue bx, by, cx, cy, dx, dy;
+ bx = ax + fDx; // add b - a
+ by = ay + fDy;
+ cx = ax + 2 * fDx + fDDx; // add a + 2(b - a) to a - 2b + c
+ cy = ay + 2 * fDy + fDDy;
if (fDDDx == 0 && fDDDy == 0) {
if (fDDx == 0 && fDDy == 0) {
- SkDebugf(" line=(%1.9g,%1.9g %1.9g,%1.9g)\n", a.fX, a.fY, b.fX, b.fY);
+ SkDebugf(
+" {SkPath::kLine_Verb, {{%1.9g, %1.9g}, {%1.9g, %1.9g} }},\n",
+ ax, ay, bx, by);
} else {
- SkDebugf(" quad=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)\n",
- a.fX, a.fY, b.fX, b.fY, c.fX, c.fY);
+ SkDebugf(
+" {SkPath::kQuad_Verb, {{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}}},\n",
+ ax, ay, bx, by, cx, cy);
}
} else {
- d.fX = fDDDx - a.fX - 3 * (c.fX - b.fX);
- d.fY = fDDDy - a.fY - 3 * (c.fY - b.fY);
- SkDebugf(" cubic=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)\n",
- a.fX, a.fY, b.fX, b.fY, c.fX, c.fY, d.fX, d.fY);
+ dx = fDDDx - ax - 3 * (cx - bx);
+ dy = fDDDy - ay - 3 * (cy - by);
+ SkDebugf(
+" {SkPath::kCubic_Verb, {{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}}},\n",
+ ax, ay, bx, by, cx, cy, dx, dy);
}
}
#endif
private:
- SkScalar fDx;
- SkScalar fDy;
- SkScalar fDDx;
- SkScalar fDDy;
- SkScalar fDDDx;
- SkScalar fDDDy;
+ AngleValue fDx;
+ AngleValue fDy;
+ AngleValue fDDx;
+ AngleValue fDDy;
+ AngleValue fDDDx;
+ AngleValue fDDDy;
const Segment* fSegment;
int fStart;
int fEnd;
@@ -726,7 +806,7 @@
}
double referenceT = fTs[index].fT;
int lesser = index;
- while (--lesser >= 0 && referenceT - fTs[lesser].fT < FLT_EPSILON) {
+ while (--lesser >= 0 && approximately_negative(referenceT - fTs[lesser].fT)) {
if (activeAngleOther(lesser, done, angles)) {
return true;
}
@@ -735,7 +815,7 @@
if (activeAngleOther(index, done, angles)) {
return true;
}
- } while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
+ } while (++index < fTs.count() && approximately_negative(fTs[index].fT - referenceT));
return false;
}
@@ -796,10 +876,14 @@
void addAngle(SkTDArray<Angle>& angles, int start, int end) const {
SkASSERT(start != end);
+ Angle* angle = angles.append();
+#if HIGH_DEF_ANGLES==0 // old way
SkPoint edge[4];
(*SegmentSubDivide[fVerb])(fPts, fTs[start].fT, fTs[end].fT, edge);
- Angle* angle = angles.append();
angle->set(edge, fVerb, this, start, end);
+#else // new way : compute temp edge in higher precision
+ angle->set(fPts, fVerb, this, start, end, fTs[start].fT, fTs[end].fT);
+#endif
}
void addCancelOutsides(double tStart, double oStart, Segment& other,
@@ -810,20 +894,20 @@
int oCount = other.fTs.count();
do {
++tIndex;
- } while (tStart - fTs[tIndex].fT >= FLT_EPSILON && tIndex < tCount);
+ } while (!approximately_negative(tStart - fTs[tIndex].fT) && tIndex < tCount);
int tIndexStart = tIndex;
do {
++oIndex;
- } while (oStart - other.fTs[oIndex].fT >= FLT_EPSILON && oIndex < oCount);
+ } while (!approximately_negative(oStart - other.fTs[oIndex].fT) && oIndex < oCount);
int oIndexStart = oIndex;
double nextT;
do {
nextT = fTs[++tIndex].fT;
- } while (nextT < 1 && nextT - tStart < FLT_EPSILON);
+ } while (nextT < 1 && approximately_negative(nextT - tStart));
double oNextT;
do {
oNextT = other.fTs[++oIndex].fT;
- } while (oNextT < 1 && oNextT - oStart < FLT_EPSILON);
+ } while (oNextT < 1 && approximately_negative(oNextT - oStart));
// at this point, spans before and after are at:
// fTs[tIndexStart - 1], fTs[tIndexStart], fTs[tIndex]
// if tIndexStart == 0, no prior span
@@ -885,10 +969,10 @@
double oStart = outsideTs[1];
do {
++tIndex;
- } while (tStart - fTs[tIndex].fT >= FLT_EPSILON);
+ } while (!approximately_negative(tStart - fTs[tIndex].fT));
do {
++oIndex;
- } while (oStart - other.fTs[oIndex].fT >= FLT_EPSILON);
+ } while (!approximately_negative(oStart - other.fTs[oIndex].fT));
if (tIndex > 0 || oIndex > 0) {
addTPair(tStart, other, oStart, false);
}
@@ -898,17 +982,17 @@
double nextT;
do {
nextT = fTs[++tIndex].fT;
- } while (nextT - tStart < FLT_EPSILON);
+ } while (approximately_negative(nextT - tStart));
tStart = nextT;
do {
nextT = other.fTs[++oIndex].fT;
- } while (nextT - oStart < FLT_EPSILON);
+ } while (approximately_negative(nextT - oStart));
oStart = nextT;
if (tStart == 1 && oStart == 1) {
break;
}
addTPair(tStart, other, oStart, false);
- } while (tStart < 1 && oStart < 1 && oEnd - oStart >= FLT_EPSILON);
+ } while (tStart < 1 && oStart < 1 && !approximately_negative(oEnd - oStart));
}
void addCubic(const SkPoint pts[4]) {
@@ -990,10 +1074,10 @@
int insertedAt = -1;
size_t tCount = fTs.count();
// FIXME: only do this pinning here (e.g. this is done also in quad/line intersect)
- if (newT < FLT_EPSILON) {
+ if (approximately_less_than_zero(newT)) {
newT = 0;
}
- if (newT > 1 - FLT_EPSILON) {
+ if (approximately_greater_than_one(newT)) {
newT = 1;
}
for (size_t index = 0; index < tCount; ++index) {
@@ -1037,14 +1121,14 @@
// pointer since both coincident segments must contain the same spans.
void addTCancel(double startT, double endT, Segment& other,
double oStartT, double oEndT) {
- SkASSERT(endT - startT >= FLT_EPSILON);
- SkASSERT(oEndT - oStartT >= FLT_EPSILON);
+ SkASSERT(!approximately_negative(endT - startT));
+ SkASSERT(!approximately_negative(oEndT - oStartT));
int index = 0;
- while (startT - fTs[index].fT >= FLT_EPSILON) {
+ while (!approximately_negative(startT - fTs[index].fT)) {
++index;
}
int oIndex = other.fTs.count();
- while (other.fTs[--oIndex].fT - oEndT > -FLT_EPSILON)
+ while (approximately_positive(other.fTs[--oIndex].fT - oEndT))
;
double tRatio = (oEndT - oStartT) / (endT - startT);
Span* test = &fTs[index];
@@ -1064,13 +1148,13 @@
TrackOutside(outsideTs, span->fT, oTestT);
}
span = &fTs[++index];
- } while (span->fT - testT < FLT_EPSILON);
+ } while (approximately_negative(span->fT - testT));
Span* oSpan = oTest;
double otherTMatchStart = oEndT - (span->fT - startT) * tRatio;
double otherTMatchEnd = oEndT - (test->fT - startT) * tRatio;
SkDEBUGCODE(int originalWindValue = oSpan->fWindValue);
- while (oSpan->fT > otherTMatchStart - FLT_EPSILON
- && otherTMatchEnd - FLT_EPSILON > oSpan->fT) {
+ while (approximately_negative(otherTMatchStart - oSpan->fT)
+ && !approximately_negative(otherTMatchEnd - oSpan->fT)) {
#ifdef SK_DEBUG
SkASSERT(originalWindValue == oSpan->fWindValue);
#endif
@@ -1086,8 +1170,8 @@
}
test = span;
oTest = oSpan;
- } while (test->fT < endT - FLT_EPSILON);
- SkASSERT(!oIndex || oTest->fT < oStartT + FLT_EPSILON);
+ } while (!approximately_negative(endT - test->fT));
+ SkASSERT(!oIndex || approximately_negative(oTest->fT - oStartT));
// FIXME: determine if canceled edges need outside ts added
if (!done() && outsideTs.count()) {
double tStart = outsideTs[0];
@@ -1111,14 +1195,14 @@
// the lesser
void addTCoincident(const int xorMask, double startT, double endT, Segment& other,
double oStartT, double oEndT) {
- SkASSERT(endT - startT >= FLT_EPSILON);
- SkASSERT(oEndT - oStartT >= FLT_EPSILON);
+ SkASSERT(!approximately_negative(endT - startT));
+ SkASSERT(!approximately_negative(oEndT - oStartT));
int index = 0;
- while (startT - fTs[index].fT >= FLT_EPSILON) {
+ while (!approximately_negative(startT - fTs[index].fT)) {
++index;
}
int oIndex = 0;
- while (oStartT - other.fTs[oIndex].fT >= FLT_EPSILON) {
+ while (!approximately_negative(oStartT - other.fTs[oIndex].fT)) {
++oIndex;
}
double tRatio = (oEndT - oStartT) / (endT - startT);
@@ -1155,14 +1239,14 @@
}
}
end = &fTs[++index];
- } while (end->fT - test->fT < FLT_EPSILON);
+ } while (approximately_negative(end->fT - test->fT));
// because of the order in which coincidences are resolved, this and other
// may not have the same intermediate points. Compute the corresponding
// intermediate T values (using this as the master, other as the follower)
// and walk other conditionally -- hoping that it catches up in the end
double otherTMatch = (test->fT - startT) * tRatio + oStartT;
Span* oEnd = oTest;
- while (oEnd->fT < oEndT - FLT_EPSILON && oEnd->fT - otherTMatch < FLT_EPSILON) {
+ while (!approximately_negative(oEndT - oEnd->fT) && approximately_negative(oEnd->fT - otherTMatch)) {
if (transfer) {
if (decrementThis) {
#ifdef SK_DEBUG
@@ -1182,9 +1266,9 @@
}
test = end;
oTest = oEnd;
- } while (test->fT < endT - FLT_EPSILON);
- SkASSERT(oTest->fT < oEndT + FLT_EPSILON);
- SkASSERT(oTest->fT > oEndT - FLT_EPSILON);
+ } while (!approximately_negative(endT - test->fT));
+ SkASSERT(approximately_negative(oTest->fT - oEndT));
+ SkASSERT(approximately_negative(oEndT - oTest->fT));
if (!done()) {
if (outsideTs.count()) {
addCoinOutsides(outsideTs, other, oEndT);
@@ -1204,10 +1288,10 @@
int tCount = fTs.count();
for (int tIndex = 0; tIndex < tCount; ++tIndex) {
const Span& span = fTs[tIndex];
- if (span.fT - t >= FLT_EPSILON) {
+ if (!approximately_negative(span.fT - t)) {
break;
}
- if (span.fT - t < FLT_EPSILON && span.fOther == &other && span.fOtherT == otherT) {
+ if (approximately_negative(span.fT - t) && span.fOther == &other && span.fOtherT == otherT) {
#if DEBUG_ADD_T_PAIR
SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n",
__FUNCTION__, fID, t, other.fID, otherT);
@@ -1247,12 +1331,12 @@
void buildAngles(int index, SkTDArray<Angle>& angles) const {
double referenceT = fTs[index].fT;
int lesser = index;
- while (--lesser >= 0 && referenceT - fTs[lesser].fT < FLT_EPSILON) {
+ while (--lesser >= 0 && approximately_negative(referenceT - fTs[lesser].fT)) {
buildAnglesInner(lesser, angles);
}
do {
buildAnglesInner(index, angles);
- } while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
+ } while (++index < fTs.count() && approximately_negative(fTs[index].fT - referenceT));
}
void buildAnglesInner(int index, SkTDArray<Angle>& angles) const {
@@ -1510,7 +1594,7 @@
nextEnd = nextStart;
do {
nextEnd += step;
- } while (fabs(startT - other->fTs[nextEnd].fT) < FLT_EPSILON);
+ } while (approximately_zero(startT - other->fTs[nextEnd].fT));
SkASSERT(step < 0 ? nextEnd >= 0 : nextEnd < other->fTs.count());
return other;
}
@@ -1673,8 +1757,8 @@
nextStart = endSpan->fOtherIndex;
double startT = other->fTs[nextStart].fT;
SkDEBUGCODE(bool firstLoop = true;)
- if ((startT < FLT_EPSILON && step < 0)
- || (startT > 1 - FLT_EPSILON && step > 0)) {
+ if ((approximately_less_than_zero(startT) && step < 0)
+ || (approximately_greater_than_one(startT) && step > 0)) {
step = -step;
SkDEBUGCODE(firstLoop = false;)
}
@@ -1682,7 +1766,7 @@
nextEnd = nextStart;
do {
nextEnd += step;
- } while (fabs(startT - other->fTs[nextEnd].fT) < FLT_EPSILON);
+ } while (approximately_zero(startT - other->fTs[nextEnd].fT));
if (other->fTs[SkMin32(nextStart, nextEnd)].fWindValue) {
break;
}
@@ -1825,7 +1909,7 @@
continue;
}
// FIXME: if moStartT, moEndT are initialized to NaN, can skip this test
- if (moStartT == moEndT) {
+ if (approximately_equal(moStartT, moEndT)) {
continue;
}
int toStart = -1;
@@ -1857,7 +1941,7 @@
if (toStart <= 0 || toEnd <= 0) {
continue;
}
- if (toStartT == toEndT) {
+ if (approximately_equal(toStartT, toEndT)) {
continue;
}
// test to see if the segment between there and here is linear
@@ -1866,14 +1950,10 @@
continue;
}
bool flipped = (moStart - moEnd) * (toStart - toEnd) < 1;
- double tStart = tOther->fTs[toStart].fT;
- double tEnd = tOther->fTs[toEnd].fT;
- double mStart = mOther->fTs[moStart].fT;
- double mEnd = mOther->fTs[moEnd].fT;
if (flipped) {
- mOther->addTCancel(mStart, mEnd, *tOther, tEnd, tStart);
+ mOther->addTCancel(moStartT, moEndT, *tOther, toEndT, toStartT);
} else {
- mOther->addTCoincident(xorMask, mStart, mEnd, *tOther, tStart, tEnd);
+ mOther->addTCoincident(xorMask, moStartT, moEndT, *tOther, toStartT, toEndT);
}
}
}
@@ -2032,7 +2112,7 @@
bool isMissing(double startT) const {
size_t tCount = fTs.count();
for (size_t index = 0; index < tCount; ++index) {
- if (fabs(startT - fTs[index].fT) < FLT_EPSILON) {
+ if (approximately_zero(startT - fTs[index].fT)) {
return false;
}
}
@@ -2045,11 +2125,11 @@
return true;
}
double t = fTs[end].fT;
- if (t < FLT_EPSILON) {
- return fTs[1].fT >= FLT_EPSILON;
+ if (approximately_less_than_zero(t)) {
+ return !approximately_less_than_zero(fTs[1].fT);
}
- if (t > 1 - FLT_EPSILON) {
- return fTs[count - 2].fT <= 1 - FLT_EPSILON;
+ if (approximately_greater_than_one(t)) {
+ return !approximately_greater_than_one(fTs[count - 2].fT);
}
return false;
}
@@ -2098,12 +2178,12 @@
SkASSERT(winding);
double referenceT = fTs[index].fT;
int lesser = index;
- while (--lesser >= 0 && referenceT - fTs[lesser].fT < FLT_EPSILON) {
+ while (--lesser >= 0 && approximately_negative(referenceT - fTs[lesser].fT)) {
markOneDone(__FUNCTION__, lesser, winding);
}
do {
markOneDone(__FUNCTION__, index, winding);
- } while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
+ } while (++index < fTs.count() && approximately_negative(fTs[index].fT - referenceT));
}
void markOneDone(const char* funName, int tIndex, int winding) {
@@ -2136,25 +2216,25 @@
SkASSERT(winding);
double referenceT = fTs[index].fT;
int lesser = index;
- while (--lesser >= 0 && referenceT - fTs[lesser].fT < FLT_EPSILON) {
+ while (--lesser >= 0 && approximately_negative(referenceT - fTs[lesser].fT)) {
markOneWinding(__FUNCTION__, lesser, winding);
}
do {
markOneWinding(__FUNCTION__, index, winding);
- } while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
+ } while (++index < fTs.count() && approximately_negative(fTs[index].fT - referenceT));
}
void matchWindingValue(int tIndex, double t, bool borrowWind) {
int nextDoorWind = SK_MaxS32;
if (tIndex > 0) {
const Span& below = fTs[tIndex - 1];
- if (t - below.fT < FLT_EPSILON) {
+ if (approximately_negative(t - below.fT)) {
nextDoorWind = below.fWindValue;
}
}
if (nextDoorWind == SK_MaxS32 && tIndex + 1 < fTs.count()) {
const Span& above = fTs[tIndex + 1];
- if (above.fT - t < FLT_EPSILON) {
+ if (approximately_negative(above.fT - t)) {
nextDoorWind = above.fWindValue;
}
}
@@ -2194,7 +2274,7 @@
int to = from;
while (step > 0 ? ++to < count : --to >= 0) {
const Span& span = fTs[to];
- if ((step > 0 ? span.fT - fromSpan.fT : fromSpan.fT - span.fT) < FLT_EPSILON) {
+ if (approximately_zero(span.fT - fromSpan.fT)) {
continue;
}
return to;
@@ -2239,7 +2319,7 @@
static void TrackOutside(SkTDArray<double>& outsideTs, double end,
double start) {
int outCount = outsideTs.count();
- if (outCount == 0 || end - outsideTs[outCount - 2] >= FLT_EPSILON) {
+ if (outCount == 0 || !approximately_negative(end - outsideTs[outCount - 2])) {
*outsideTs.append() = end;
*outsideTs.append() = start;
}
@@ -2256,7 +2336,7 @@
SkASSERT(index < tCount - 1);
start = index;
double startT = fTs[index].fT;
- while (fTs[++index].fT - startT < FLT_EPSILON)
+ while (approximately_negative(fTs[++index].fT - startT))
SkASSERT(index < tCount);
SkASSERT(index < tCount);
end = index;
@@ -2680,13 +2760,13 @@
if (startT > endT) {
SkTSwap<double>(startT, endT);
}
- SkASSERT(endT - startT >= FLT_EPSILON);
+ SkASSERT(!approximately_negative(endT - startT));
double oStartT = coincidence.fTs[1][0];
double oEndT = coincidence.fTs[1][1];
if (oStartT > oEndT) {
SkTSwap<double>(oStartT, oEndT);
}
- SkASSERT(oEndT - oStartT >= FLT_EPSILON);
+ SkASSERT(!approximately_negative(oEndT - oStartT));
if (thisOne.cancels(other)) {
// make sure startT and endT have t entries
if (startT > 0 || oEndT < 1
@@ -3415,7 +3495,7 @@
// angles to find the span closest to the ray -- even if there are just
// two spokes on the wheel.
const Angle* angle = NULL;
- if (fabs(tHit - test->t(tIndex)) < FLT_EPSILON) {
+ if (approximately_zero(tHit - test->t(tIndex))) {
SkTDArray<Angle> angles;
int end = test->nextSpan(tIndex, 1);
if (end < 0) {