| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2012 Google Inc. | 2  * Copyright 2012 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 #include "SkIntersections.h" | 7 #include "SkIntersections.h" | 
| 8 #include "SkLineParameters.h" | 8 #include "SkLineParameters.h" | 
| 9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" | 
| 10 #include "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 66             2         0           -2        -1       0 | 66             2         0           -2        -1       0 | 
| 67 */ | 67 */ | 
| 68 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { | 68 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { | 
| 69     for (int opp = 1; opp < kPointCount; ++opp) { | 69     for (int opp = 1; opp < kPointCount; ++opp) { | 
| 70         int end = (oddMan ^ opp) - oddMan;  // choose a value not equal to oddMa
     n | 70         int end = (oddMan ^ opp) - oddMan;  // choose a value not equal to oddMa
     n | 
| 71         end &= ~(end >> 2);  // if the value went negative, set it to zero | 71         end &= ~(end >> 2);  // if the value went negative, set it to zero | 
| 72         endPt[opp - 1] = &fPts[end]; | 72         endPt[opp - 1] = &fPts[end]; | 
| 73     } | 73     } | 
| 74 } | 74 } | 
| 75 | 75 | 
| 76 // from http://blog.gludion.com/2009/08/distance-to-quadratic-bezier-curve.html |  | 
| 77 // (currently only used by testing) |  | 
| 78 double SkDQuad::nearestT(const SkDPoint& pt) const { |  | 
| 79     SkDVector pos = fPts[0] - pt; |  | 
| 80     // search points P of bezier curve with PM.(dP / dt) = 0 |  | 
| 81     // a calculus leads to a 3d degree equation : |  | 
| 82     SkDVector A = fPts[1] - fPts[0]; |  | 
| 83     SkDVector B = fPts[2] - fPts[1]; |  | 
| 84     B -= A; |  | 
| 85     double a = B.dot(B); |  | 
| 86     double b = 3 * A.dot(B); |  | 
| 87     double c = 2 * A.dot(A) + pos.dot(B); |  | 
| 88     double d = pos.dot(A); |  | 
| 89     double ts[3]; |  | 
| 90     int roots = SkDCubic::RootsValidT(a, b, c, d, ts); |  | 
| 91     double d0 = pt.distanceSquared(fPts[0]); |  | 
| 92     double d2 = pt.distanceSquared(fPts[2]); |  | 
| 93     double distMin = SkTMin(d0, d2); |  | 
| 94     int bestIndex = -1; |  | 
| 95     for (int index = 0; index < roots; ++index) { |  | 
| 96         SkDPoint onQuad = ptAtT(ts[index]); |  | 
| 97         double dist = pt.distanceSquared(onQuad); |  | 
| 98         if (distMin > dist) { |  | 
| 99             distMin = dist; |  | 
| 100             bestIndex = index; |  | 
| 101         } |  | 
| 102     } |  | 
| 103     if (bestIndex >= 0) { |  | 
| 104         return ts[bestIndex]; |  | 
| 105     } |  | 
| 106     return d0 < d2 ? 0 : 1; |  | 
| 107 } |  | 
| 108 |  | 
| 109 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { | 76 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { | 
| 110     int foundRoots = 0; | 77     int foundRoots = 0; | 
| 111     for (int index = 0; index < realRoots; ++index) { | 78     for (int index = 0; index < realRoots; ++index) { | 
| 112         double tValue = s[index]; | 79         double tValue = s[index]; | 
| 113         if (approximately_zero_or_more(tValue) && approximately_one_or_less(tVal
     ue)) { | 80         if (approximately_zero_or_more(tValue) && approximately_one_or_less(tVal
     ue)) { | 
| 114             if (approximately_less_than_zero(tValue)) { | 81             if (approximately_less_than_zero(tValue)) { | 
| 115                 tValue = 0; | 82                 tValue = 0; | 
| 116             } else if (approximately_greater_than_one(tValue)) { | 83             } else if (approximately_greater_than_one(tValue)) { | 
| 117                 tValue = 1; | 84                 tValue = 1; | 
| 118             } | 85             } | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 181     lineParameters.normalize(); | 148     lineParameters.normalize(); | 
| 182     double distance = lineParameters.controlPtDistance(*this); | 149     double distance = lineParameters.controlPtDistance(*this); | 
| 183     double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), | 150     double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), | 
| 184             fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 151             fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 
| 185     double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), | 152     double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), | 
| 186             fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 153             fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 
| 187     largest = SkTMax(largest, -tiniest); | 154     largest = SkTMax(largest, -tiniest); | 
| 188     return approximately_zero_when_compared_to(distance, largest); | 155     return approximately_zero_when_compared_to(distance, largest); | 
| 189 } | 156 } | 
| 190 | 157 | 
| 191 SkDConic SkDQuad::toConic() const { |  | 
| 192     SkDConic conic; |  | 
| 193     memcpy(conic.fPts.fPts, fPts, sizeof(fPts)); |  | 
| 194     conic.fWeight = 1; |  | 
| 195     return conic; |  | 
| 196 } |  | 
| 197 |  | 
| 198 SkDCubic SkDQuad::toCubic() const { |  | 
| 199     SkDCubic cubic; |  | 
| 200     cubic[0] = fPts[0]; |  | 
| 201     cubic[2] = fPts[1]; |  | 
| 202     cubic[3] = fPts[2]; |  | 
| 203     cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; |  | 
| 204     cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; |  | 
| 205     cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; |  | 
| 206     cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; |  | 
| 207     return cubic; |  | 
| 208 } |  | 
| 209 |  | 
| 210 SkDVector SkDQuad::dxdyAtT(double t) const { | 158 SkDVector SkDQuad::dxdyAtT(double t) const { | 
| 211     double a = t - 1; | 159     double a = t - 1; | 
| 212     double b = 1 - 2 * t; | 160     double b = 1 - 2 * t; | 
| 213     double c = t; | 161     double c = t; | 
| 214     SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 162     SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 
| 215             a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 163             a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 
| 216     return result; | 164     return result; | 
| 217 } | 165 } | 
| 218 | 166 | 
| 219 // OPTIMIZE: assert if caller passes in t == 0 / t == 1 ? | 167 // OPTIMIZE: assert if caller passes in t == 0 / t == 1 ? | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 339 } | 287 } | 
| 340 | 288 | 
| 341 SkDQuadPair SkDQuad::chopAt(double t) const | 289 SkDQuadPair SkDQuad::chopAt(double t) const | 
| 342 { | 290 { | 
| 343     SkDQuadPair dst; | 291     SkDQuadPair dst; | 
| 344     interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t); | 292     interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t); | 
| 345     interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t); | 293     interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t); | 
| 346     return dst; | 294     return dst; | 
| 347 } | 295 } | 
| 348 | 296 | 
| 349 bool SkDQuad::Clockwise(const SkOpCurve& edge, bool* swap) { |  | 
| 350     SkDQuad temp; |  | 
| 351     double sum = (edge[0].fX - edge[kPointLast].fX) * (edge[0].fY + edge[kPointL
     ast].fY); |  | 
| 352     for (int idx = 0; idx < kPointLast; ++idx){ |  | 
| 353         sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx]
     .fY); |  | 
| 354     } |  | 
| 355     temp.set(edge.fPts); |  | 
| 356     *swap = sum > 0 && !temp.monotonicInY(); |  | 
| 357     return sum <= 0; |  | 
| 358 } |  | 
| 359 |  | 
| 360 static int valid_unit_divide(double numer, double denom, double* ratio) | 297 static int valid_unit_divide(double numer, double denom, double* ratio) | 
| 361 { | 298 { | 
| 362     if (numer < 0) { | 299     if (numer < 0) { | 
| 363         numer = -numer; | 300         numer = -numer; | 
| 364         denom = -denom; | 301         denom = -denom; | 
| 365     } | 302     } | 
| 366     if (denom == 0 || numer == 0 || numer >= denom) { | 303     if (denom == 0 || numer == 0 || numer >= denom) { | 
| 367         return 0; | 304         return 0; | 
| 368     } | 305     } | 
| 369     double r = numer / denom; | 306     double r = numer / denom; | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 396  * c =             C | 333  * c =             C | 
| 397  */ | 334  */ | 
| 398 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 335 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 
| 399     *a = quad[0];      // a = A | 336     *a = quad[0];      // a = A | 
| 400     *b = 2 * quad[2];  // b =     2*B | 337     *b = 2 * quad[2];  // b =     2*B | 
| 401     *c = quad[4];      // c =             C | 338     *c = quad[4];      // c =             C | 
| 402     *b -= *c;          // b =     2*B -   C | 339     *b -= *c;          // b =     2*B -   C | 
| 403     *a -= *b;          // a = A - 2*B +   C | 340     *a -= *b;          // a = A - 2*B +   C | 
| 404     *b -= *c;          // b =     2*B - 2*C | 341     *b -= *c;          // b =     2*B - 2*C | 
| 405 } | 342 } | 
| OLD | NEW | 
|---|