| 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 |