OLD | NEW |
1 // Another approach is to start with the implicit form of one curve and solve | 1 // Another approach is to start with the implicit form of one curve and solve |
2 // (seek implicit coefficients in QuadraticParameter.cpp | 2 // (seek implicit coefficients in QuadraticParameter.cpp |
3 // by substituting in the parametric form of the other. | 3 // by substituting in the parametric form of the other. |
4 // The downside of this approach is that early rejects are difficult to come by. | 4 // The downside of this approach is that early rejects are difficult to come by. |
5 // http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormu
la.html#step | 5 // http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormu
la.html#step |
6 | 6 |
7 | |
8 #include "SkDQuadImplicit.h" | 7 #include "SkDQuadImplicit.h" |
9 #include "SkIntersections.h" | 8 #include "SkIntersections.h" |
10 #include "SkPathOpsLine.h" | 9 #include "SkPathOpsLine.h" |
11 #include "SkQuarticRoot.h" | 10 #include "SkQuarticRoot.h" |
12 #include "SkTArray.h" | 11 #include "SkTArray.h" |
13 #include "SkTSort.h" | 12 #include "SkTSort.h" |
14 | 13 |
15 /* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F | 14 /* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F |
16 * and given x = at^2 + bt + c (the parameterized form) | 15 * and given x = at^2 + bt + c (the parameterized form) |
17 * y = dt^2 + et + f | 16 * y = dt^2 + et + f |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 SkDLine line = {{hull[2], hull[0]}}; | 151 SkDLine line = {{hull[2], hull[0]}}; |
153 const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDL
ine*) &hull[1] }; | 152 const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDL
ine*) &hull[1] }; |
154 const size_t kTestCount = SK_ARRAY_COUNT(testLines); | 153 const size_t kTestCount = SK_ARRAY_COUNT(testLines); |
155 SkSTArray<kTestCount * 2, double, true> tsFound; | 154 SkSTArray<kTestCount * 2, double, true> tsFound; |
156 for (size_t index = 0; index < kTestCount; ++index) { | 155 for (size_t index = 0; index < kTestCount; ++index) { |
157 SkIntersections rootTs; | 156 SkIntersections rootTs; |
158 rootTs.allowNear(false); | 157 rootTs.allowNear(false); |
159 int roots = rootTs.intersect(q2, *testLines[index]); | 158 int roots = rootTs.intersect(q2, *testLines[index]); |
160 for (int idx2 = 0; idx2 < roots; ++idx2) { | 159 for (int idx2 = 0; idx2 < roots; ++idx2) { |
161 double t = rootTs[0][idx2]; | 160 double t = rootTs[0][idx2]; |
162 #ifdef SK_DEBUG | 161 #if 0 // def SK_DEBUG // FIXME : accurate for error = 16, error of 17.5 seen |
| 162 // {{{136.08723965397621, 1648.2814535211637}, {593.49031197259478, 1190.8784277
439891}, {593.49031197259478, 544.0128173828125}}} |
| 163 // {{{-968.181396484375, 544.0128173828125}, {592.2825927734375, 870.55249023437
5}, {593.435302734375, 557.8828125}}} |
| 164 |
163 SkDPoint qPt = q2.ptAtT(t); | 165 SkDPoint qPt = q2.ptAtT(t); |
164 SkDPoint lPt = testLines[index]->ptAtT(rootTs[1][idx2]); | 166 SkDPoint lPt = testLines[index]->ptAtT(rootTs[1][idx2]); |
165 SkASSERT(qPt.approximatelyPEqual(lPt)); | 167 SkASSERT(qPt.approximatelyDEqual(lPt)); |
166 #endif | 168 #endif |
167 if (approximately_negative(t - t2s) || approximately_positive(t - t2
e)) { | 169 if (approximately_negative(t - t2s) || approximately_positive(t - t2
e)) { |
168 continue; | 170 continue; |
169 } | 171 } |
170 tsFound.push_back(rootTs[0][idx2]); | 172 tsFound.push_back(rootTs[0][idx2]); |
171 } | 173 } |
172 } | 174 } |
173 int tCount = tsFound.count(); | 175 int tCount = tsFound.count(); |
174 if (tCount <= 0) { | 176 if (tCount <= 0) { |
175 return true; | 177 return true; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 if (calcMask & (1 << 1)) t1[1] = quad1.ptAtT(*t1Seed); | 300 if (calcMask & (1 << 1)) t1[1] = quad1.ptAtT(*t1Seed); |
299 if (calcMask & (1 << 4)) t2[1] = quad2.ptAtT(*t2Seed); | 301 if (calcMask & (1 << 4)) t2[1] = quad2.ptAtT(*t2Seed); |
300 if (t1[1].approximatelyEqual(t2[1])) { | 302 if (t1[1].approximatelyEqual(t2[1])) { |
301 *pt = t1[1]; | 303 *pt = t1[1]; |
302 #if ONE_OFF_DEBUG | 304 #if ONE_OFF_DEBUG |
303 SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) == (%1.9g,%1.9g)\n", __
FUNCTION__, | 305 SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) == (%1.9g,%1.9g)\n", __
FUNCTION__, |
304 t1Seed, t2Seed, t1[1].fX, t1[1].fY, t2[1].fX, t2[1].fY); | 306 t1Seed, t2Seed, t1[1].fX, t1[1].fY, t2[1].fX, t2[1].fY); |
305 #endif | 307 #endif |
306 return true; | 308 return true; |
307 } | 309 } |
308 if (calcMask & (1 << 0)) t1[0] = quad1.ptAtT(*t1Seed - tStep); | 310 if (calcMask & (1 << 0)) t1[0] = quad1.ptAtT(SkTMax(0., *t1Seed - tStep)
); |
309 if (calcMask & (1 << 2)) t1[2] = quad1.ptAtT(*t1Seed + tStep); | 311 if (calcMask & (1 << 2)) t1[2] = quad1.ptAtT(SkTMin(1., *t1Seed + tStep)
); |
310 if (calcMask & (1 << 3)) t2[0] = quad2.ptAtT(*t2Seed - tStep); | 312 if (calcMask & (1 << 3)) t2[0] = quad2.ptAtT(SkTMax(0., *t2Seed - tStep)
); |
311 if (calcMask & (1 << 5)) t2[2] = quad2.ptAtT(*t2Seed + tStep); | 313 if (calcMask & (1 << 5)) t2[2] = quad2.ptAtT(SkTMin(1., *t2Seed + tStep)
); |
312 double dist[3][3]; | 314 double dist[3][3]; |
313 // OPTIMIZE: using calcMask value permits skipping some distance calcuat
ions | 315 // OPTIMIZE: using calcMask value permits skipping some distance calcuat
ions |
314 // if prior loop's results are moved to correct slot for reuse | 316 // if prior loop's results are moved to correct slot for reuse |
315 dist[1][1] = t1[1].distanceSquared(t2[1]); | 317 dist[1][1] = t1[1].distanceSquared(t2[1]); |
316 int best_i = 1, best_j = 1; | 318 int best_i = 1, best_j = 1; |
317 for (int i = 0; i < 3; ++i) { | 319 for (int i = 0; i < 3; ++i) { |
318 for (int j = 0; j < 3; ++j) { | 320 for (int j = 0; j < 3; ++j) { |
319 if (i == 1 && j == 1) { | 321 if (i == 1 && j == 1) { |
320 continue; | 322 continue; |
321 } | 323 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 } | 378 } |
377 SkDLine tmpLine; | 379 SkDLine tmpLine; |
378 int testTIndex = testT << 1; | 380 int testTIndex = testT << 1; |
379 tmpLine[0] = tmpLine[1] = q2[testTIndex]; | 381 tmpLine[0] = tmpLine[1] = q2[testTIndex]; |
380 tmpLine[1].fX += q2[1].fY - q2[testTIndex].fY; | 382 tmpLine[1].fX += q2[1].fY - q2[testTIndex].fY; |
381 tmpLine[1].fY -= q2[1].fX - q2[testTIndex].fX; | 383 tmpLine[1].fY -= q2[1].fX - q2[testTIndex].fX; |
382 SkIntersections impTs; | 384 SkIntersections impTs; |
383 impTs.intersectRay(q1, tmpLine); | 385 impTs.intersectRay(q1, tmpLine); |
384 for (int index = 0; index < impTs.used(); ++index) { | 386 for (int index = 0; index < impTs.used(); ++index) { |
385 SkDPoint realPt = impTs.pt(index); | 387 SkDPoint realPt = impTs.pt(index); |
386 if (!tmpLine[0].approximatelyEqual(realPt)) { | 388 if (!tmpLine[0].approximatelyPEqual(realPt)) { |
387 continue; | 389 continue; |
388 } | 390 } |
389 if (swap) { | 391 if (swap) { |
390 i->insert(testT, impTs[0][index], tmpLine[0]); | 392 i->insert(testT, impTs[0][index], tmpLine[0]); |
391 } else { | 393 } else { |
392 i->insert(impTs[0][index], testT, tmpLine[0]); | 394 i->insert(impTs[0][index], testT, tmpLine[0]); |
393 } | 395 } |
394 } | 396 } |
395 } | 397 } |
396 | 398 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 } | 546 } |
545 if (lowestIndex < 0) { | 547 if (lowestIndex < 0) { |
546 break; | 548 break; |
547 } | 549 } |
548 insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]], | 550 insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]], |
549 pts1[lowestIndex]); | 551 pts1[lowestIndex]); |
550 closest[lowestIndex] = -1; | 552 closest[lowestIndex] = -1; |
551 } while (++used < r1Count); | 553 } while (++used < r1Count); |
552 return fUsed; | 554 return fUsed; |
553 } | 555 } |
OLD | NEW |