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 "SkPathOpsQuad.h" | 10 #include "SkPathOpsQuad.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 } | 41 } |
42 if (!foundOutlier) { | 42 if (!foundOutlier) { |
43 return false; | 43 return false; |
44 } | 44 } |
45 } | 45 } |
46 *isLinear = linear; | 46 *isLinear = linear; |
47 return true; | 47 return true; |
48 } | 48 } |
49 | 49 |
| 50 bool SkDQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const { |
| 51 return conic.hullIntersects(*this, isLinear); |
| 52 } |
| 53 |
| 54 bool SkDQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { |
| 55 return cubic.hullIntersects(*this, isLinear); |
| 56 } |
| 57 |
50 /* bit twiddling for finding the off curve index (x&~m is the pair in [0,1,2] ex
cluding oddMan) | 58 /* bit twiddling for finding the off curve index (x&~m is the pair in [0,1,2] ex
cluding oddMan) |
51 oddMan opp x=oddMan^opp x=x-oddMan m=x>>2 x&~m | 59 oddMan opp x=oddMan^opp x=x-oddMan m=x>>2 x&~m |
52 0 1 1 1 0 1 | 60 0 1 1 1 0 1 |
53 2 2 2 0 2 | 61 2 2 2 0 2 |
54 1 1 0 -1 -1 0 | 62 1 1 0 -1 -1 0 |
55 2 3 2 0 2 | 63 2 3 2 0 2 |
56 2 1 3 1 0 1 | 64 2 1 3 1 0 1 |
57 2 0 -2 -1 0 | 65 2 0 -2 -1 0 |
58 */ | 66 */ |
59 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { | 67 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 lineParameters.normalize(); | 199 lineParameters.normalize(); |
192 double distance = lineParameters.controlPtDistance(*this); | 200 double distance = lineParameters.controlPtDistance(*this); |
193 double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), | 201 double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), |
194 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 202 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); |
195 double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), | 203 double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), |
196 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 204 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); |
197 largest = SkTMax(largest, -tiniest); | 205 largest = SkTMax(largest, -tiniest); |
198 return approximately_zero_when_compared_to(distance, largest); | 206 return approximately_zero_when_compared_to(distance, largest); |
199 } | 207 } |
200 | 208 |
| 209 SkDConic SkDQuad::toConic() const { |
| 210 SkDConic conic; |
| 211 memcpy(conic.fPts.fPts, fPts, sizeof(fPts)); |
| 212 conic.fWeight = 1; |
| 213 return conic; |
| 214 } |
| 215 |
201 SkDCubic SkDQuad::toCubic() const { | 216 SkDCubic SkDQuad::toCubic() const { |
202 SkDCubic cubic; | 217 SkDCubic cubic; |
203 cubic[0] = fPts[0]; | 218 cubic[0] = fPts[0]; |
204 cubic[2] = fPts[1]; | 219 cubic[2] = fPts[1]; |
205 cubic[3] = fPts[2]; | 220 cubic[3] = fPts[2]; |
206 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; | 221 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; |
207 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; | 222 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; |
208 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; | 223 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; |
209 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; | 224 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; |
210 return cubic; | 225 return cubic; |
(...skipping 18 matching lines...) Expand all Loading... |
229 } | 244 } |
230 double one_t = 1 - t; | 245 double one_t = 1 - t; |
231 double a = one_t * one_t; | 246 double a = one_t * one_t; |
232 double b = 2 * one_t * t; | 247 double b = 2 * one_t * t; |
233 double c = t * t; | 248 double c = t * t; |
234 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 249 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, |
235 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 250 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; |
236 return result; | 251 return result; |
237 } | 252 } |
238 | 253 |
| 254 static double interp_quad_coords(const double* src, double t) { |
| 255 double ab = SkDInterp(src[0], src[2], t); |
| 256 double bc = SkDInterp(src[2], src[4], t); |
| 257 double abc = SkDInterp(ab, bc, t); |
| 258 return abc; |
| 259 } |
| 260 |
| 261 bool SkDQuad::monotonicInY() const { |
| 262 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); |
| 263 } |
| 264 |
239 /* | 265 /* |
240 Given a quadratic q, t1, and t2, find a small quadratic segment. | 266 Given a quadratic q, t1, and t2, find a small quadratic segment. |
241 | 267 |
242 The new quadratic is defined by A, B, and C, where | 268 The new quadratic is defined by A, B, and C, where |
243 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 | 269 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 |
244 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 | 270 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 |
245 | 271 |
246 To find B, compute the point halfway between t1 and t2: | 272 To find B, compute the point halfway between t1 and t2: |
247 | 273 |
248 q(at (t1 + t2)/2) == D | 274 q(at (t1 + t2)/2) == D |
249 | 275 |
250 Next, compute where D must be if we know the value of B: | 276 Next, compute where D must be if we know the value of B: |
251 | 277 |
252 _12 = A/2 + B/2 | 278 _12 = A/2 + B/2 |
253 12_ = B/2 + C/2 | 279 12_ = B/2 + C/2 |
254 123 = A/4 + B/2 + C/4 | 280 123 = A/4 + B/2 + C/4 |
255 = D | 281 = D |
256 | 282 |
257 Group the known values on one side: | 283 Group the known values on one side: |
258 | 284 |
259 B = D*2 - A/2 - C/2 | 285 B = D*2 - A/2 - C/2 |
260 */ | 286 */ |
261 | 287 |
262 static double interp_quad_coords(const double* src, double t) { | 288 // OPTIMIZE : special case either or both of t1 = 0, t2 = 1 |
263 double ab = SkDInterp(src[0], src[2], t); | |
264 double bc = SkDInterp(src[2], src[4], t); | |
265 double abc = SkDInterp(ab, bc, t); | |
266 return abc; | |
267 } | |
268 | |
269 bool SkDQuad::monotonicInY() const { | |
270 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); | |
271 } | |
272 | |
273 SkDQuad SkDQuad::subDivide(double t1, double t2) const { | 289 SkDQuad SkDQuad::subDivide(double t1, double t2) const { |
274 SkDQuad dst; | 290 SkDQuad dst; |
275 double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1); | 291 double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1); |
276 double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1); | 292 double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1); |
277 double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2); | 293 double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2); |
278 double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2); | 294 double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2); |
279 double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2); | 295 double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2); |
280 double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2); | 296 double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2); |
281 /* bx = */ dst[1].fX = 2*dx - (ax + cx)/2; | 297 /* bx = */ dst[1].fX = 2 * dx - (ax + cx) / 2; |
282 /* by = */ dst[1].fY = 2*dy - (ay + cy)/2; | 298 /* by = */ dst[1].fY = 2 * dy - (ay + cy) / 2; |
283 return dst; | 299 return dst; |
284 } | 300 } |
285 | 301 |
286 void SkDQuad::align(int endIndex, SkDPoint* dstPt) const { | 302 void SkDQuad::align(int endIndex, SkDPoint* dstPt) const { |
287 if (fPts[endIndex].fX == fPts[1].fX) { | 303 if (fPts[endIndex].fX == fPts[1].fX) { |
288 dstPt->fX = fPts[endIndex].fX; | 304 dstPt->fX = fPts[endIndex].fX; |
289 } | 305 } |
290 if (fPts[endIndex].fY == fPts[1].fY) { | 306 if (fPts[endIndex].fY == fPts[1].fY) { |
291 dstPt->fY = fPts[endIndex].fY; | 307 dstPt->fY = fPts[endIndex].fY; |
292 } | 308 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 * c = C | 396 * c = C |
381 */ | 397 */ |
382 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 398 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { |
383 *a = quad[0]; // a = A | 399 *a = quad[0]; // a = A |
384 *b = 2 * quad[2]; // b = 2*B | 400 *b = 2 * quad[2]; // b = 2*B |
385 *c = quad[4]; // c = C | 401 *c = quad[4]; // c = C |
386 *b -= *c; // b = 2*B - C | 402 *b -= *c; // b = 2*B - C |
387 *a -= *b; // a = A - 2*B + C | 403 *a -= *b; // a = A - 2*B + C |
388 *b -= *c; // b = 2*B - 2*C | 404 *b -= *c; // b = 2*B - 2*C |
389 } | 405 } |
OLD | NEW |