40 return lh.convexHullOverlaps(&rh);
44 return lh.endsIntersect(&rh);
67 i.intersect(arc, quad);
73 for (
int idx = 0; idx <
i.used(); ++idx) {
74 if (
i[0][idx] > 1 ||
i[0][idx] < 0) {
76 i.intersect(arc, quad);
78 if (
i[1][idx] > 1 ||
i[1][idx] < 0) {
80 i.intersect(arc, quad);
89 return i[1][smallest];
98 const QuadPts circle[8] = {{{{ r, 0}, { r, -
s}, {
m, -
m}}},
99 {{{
m, -
m}, {
s, -r}, { 0, -r}}},
100 {{{ 0, -r}, {-
s, -r}, {-
m, -
m}}},
101 {{{-
m, -
m}, {-r, -
s}, {-r, 0}}},
102 {{{-r, 0}, {-r,
s}, {-
m,
m}}},
103 {{{-
m,
m}, {-
s, r}, { 0, r}}},
104 {{{ 0, r}, {
s, r}, {
m,
m}}},
105 {{{
m,
m}, { r,
s}, { r, 0}}}};
106 for (
int octant = 0; octant < 8; ++octant) {
113 for (
int index = 0; index < tArray->
size(); ++index) {
114 double matchT = (*tArray)[index];
132 double delta = a1 - a2;
133 return (delta < 4 && delta > 0) ||
delta < -4;
137 sweep[0] = quad[1] - quad[0];
138 sweep[1] = quad[2] - quad[0];
142 SkDVector v[] = {quad[2] - quad[0], quad[1] - quad[0], quad[2] - quad[1]};
144 return longest / dist;
160 double s0dt0 = sweep[0].
dot(tweep[0]);
163 double m = s0xt0 / s0dt0;
164 double sDist = sweep[0].
length() *
m;
165 double tDist = tweep[0].
length() *
m;
166 bool useS = fabs(sDist) < fabs(tDist);
168 if (mFactor < 5000) {
189 bool tBetweenS = s0xs1 > 0 ? s0xt0 > 0 && s1xt0 < 0 : s0xt0 < 0 && s1xt0 > 0;
192 tBetweenS |= s0xs1 > 0 ? s0xt1 > 0 && s1xt1 < 0 : s0xt1 < 0 && s1xt1 > 0;
197 if ((s0xt0 == 0 && s1xt1 == 0) || (s1xt0 == 0 && s0xt1 == 0)) {
200 bool sBetweenT = t0xt1 > 0 ? s0xt0 < 0 && s0xt1 > 0 : s0xt0 > 0 && s0xt1 < 0;
201 sBetweenT |= t0xt1 > 0 ? s1xt0 < 0 && s1xt1 > 0 : s1xt0 > 0 && s1xt1 < 0;
206 if (s0xt0 >= 0 && s0xt1 >= 0 && s1xt0 >= 0 && s1xt1 >= 0) {
209 if (s0xt0 <= 0 && s0xt1 <= 0 && s1xt0 <= 0 && s1xt1 <= 0) {
218 if (s0xt0 > 0 && m0xm1 > 0) {
221 if (s0xt0 < 0 && m0xm1 < 0) {
242 return (startToTest <= 0 && testToEnd <= 0 && startToTest >= startToEnd) ||
243 (startToTest >= 0 && testToEnd >= 0 && startToTest <= startToEnd);
254 SkTQSort<double>(t1Array.
begin(), t1Array.
end());
255 SkTQSort<double>(t2Array.
begin(), t2Array.
end());
256 double t1 =
result->tMin1 = t1Array[0];
257 double t2 =
result->tMin2 = t2Array[0];
282 {
bounds.fLeft - quad[0].fX,
bounds.fTop - quad[0].fY },
283 {
bounds.fRight - quad[0].fX,
bounds.fTop - quad[0].fY },
284 {
bounds.fLeft - quad[0].fX,
bounds.fBottom - quad[0].fY },
285 {
bounds.fRight - quad[0].fX,
bounds.fBottom - quad[0].fY }
288 for (
unsigned index = 0; index <
std::size(corner); ++index) {
296 for (
int index = 0; index < 2; ++index) {
307 double r = maxRadius / 2;
308 double rStep = r / 2;
312 double bestR = maxRadius;
313 upperRange->
tMin = 0;
314 lowerRange->
tMin = 1;
331 SkDebugf(
"u bestCCW=%d ccw=%d bestMin=%1.9g:%1.9g r=%1.9g tMin=%1.9g\n",
332 bestCCW, tRange.
ccw, lowerRange->
tMin, upperRange->
tMin, r,
335 if (bestCCW >= 0 && bestCCW != (
int) tRange.
ccw) {
336 if (tRange.
tMin < upperRange->
tMin) {
337 upperRange->
tMin = 0;
342 if (upperRange->
tMin < tRange.
tMin) {
343 bestCCW = tRange.
ccw;
345 *upperRange = tRange;
347 if (lowerRange->
tMin > tRange.
tMin) {
348 *lowerRange = tRange;
351 r += stepUp ? rStep : -rStep;
353 }
while (rStep > FLT_EPSILON);
358 double lastHighR = bestR;
366 SkDebugf(
"l bestCCW=%d ccw=%d bestMin=%1.9g:%1.9g r=%1.9g tMin=%1.9g\n",
367 bestCCW, tRange.
ccw, lowerRange->
tMin, upperRange->
tMin, r,
370 if (bestCCW != (
int) tRange.
ccw || upperRange->
tMin < tRange.
tMin) {
371 bestCCW = tRange.
ccw;
372 *upperRange = tRange;
389 if (upperRange->
tMin < tRange.
tMin) {
390 *upperRange = tRange;
392 if (lowerRange->
tMin > tRange.
tMin) {
393 *lowerRange = tRange;
398 r += success ? -rStep : rStep;
400 }
while (rStep > FLT_EPSILON);
401 }
while (rStep > FLT_EPSILON);
404 SkDebugf(
"l a2-a1==%1.9g\n", lowerRange->
a2 - lowerRange->
a1);
414 TRange lowerRange, upperRange;
417 double angle = fabs(lowerRange.
a2 - lowerRange.
a1);
422 const SkDQuad& quad2,
bool ccw) {
423 TRange lowerRange, upperRange;
426 return ccw == upperRange.
ccw;
430 shortQuad[0] = quad[0].asSkPoint();
431 shortQuad[1] = quad[1].asSkPoint();
432 shortQuad[2] = quad[2].asSkPoint();
453 double a1s = atan2(origin.
fY - quad1[1].fY, quad1[1].fX - origin.
fX);
454 double a1e = atan2(origin.
fY - quad1[2].fY, quad1[2].fX - origin.
fX);
455 double a2s = atan2(origin.
fY - quad2[1].fY, quad2[1].fX - origin.
fX);
456 double a2e = atan2(origin.
fY - quad2[2].fY, quad2[2].fX - origin.
fX);
461 bool realMatchesOverlap = realOverlap == overlap ||
SK_ScalarPI - fabs(a2s - a1s) < 0.002;
462 if (realOverlap != overlap) {
465 if (!realMatchesOverlap) {
466 DumpQ(quad1, quad2, testNo);
469 if (oldSchoolOverlap != (overlap < 0)) {
477 double vDir[2] = { v1s.
cross(v1e), v2s.
cross(v2e) };
478 bool ray1In2 = v1s.
cross(v2s) * vDir[1] <= 0 && v1s.
cross(v2e) * vDir[1] >= 0;
479 bool ray2In1 = v2s.
cross(v1s) * vDir[0] <= 0 && v2s.
cross(v1e) * vDir[0] >= 0;
484 bool ctrl1In2 = v1e.
cross(v2s) * vDir[1] <= 0 && v1e.
cross(v2e) * vDir[1] >= 0;
486 bool ctrl2In1 = v2e.
cross(v1s) * vDir[0] <= 0 && v2e.
cross(v1e) * vDir[0] >= 0;
492 SkDLine rays[] = {{{origin, quad2[2]}}, {{origin, quad1[2]}}};
493 const SkDQuad* quads[] = {&quad1, &quad2};
496 double minX, minY, maxX, maxY;
500 bool useIntersect =
false;
501 double smallestTs[] = {1, 1};
502 for (
unsigned index = 0; index <
std::size(quads); ++index) {
503 const SkDQuad& q = *quads[index];
504 midSpokes[index] = q.
ptAtT(0.5) - origin;
510 intersect[index].intersectRay(q, rays[index]);
513 bool foundZero =
false;
515 for (
int idx2 = 0; idx2 <
i.used(); ++idx2) {
516 double t =
i[0][idx2];
531 if (ray.
fX *
end.fX < 0 || ray.
fY *
end.fY < 0) {
534 double rayDist = ray.
length();
535 double endDist =
end.length();
536 double delta = fabs(rayDist - endDist) / maxWidth;
538 useIntersect ^=
true;
540 smallestTs[index] = smallT;
544 int sIndex = (
int) (smallestTs[1] < 1);
546 double t = smallestTs[sIndex];
547 const SkDQuad& q = *quads[sIndex];
550 double rayDist = ray.
length();
551 double endDist =
end.length();
555 SkDebugf(
"rayDist>endDist:%d sIndex==0:%d vDir[sIndex]<0:%d midXray<0:%d\n",
556 rayDist > endDist, sIndex == 0, vDir[sIndex] < 0, midXray < 0);
560 firstInside = (rayDist > endDist) ^ (sIndex == 0) ^ (vDir[sIndex] < 0);
561 }
else if (overlap >= 0) {
570 SkASSERT(realEnds == (firstInside ? 1 : 0));
579{{{939.4808349609375, 914.355224609375}, {-357.7921142578125, 590.842529296875}, {736.8936767578125, -350.717529296875}}},
580{{{939.4808349609375, 914.355224609375}, {-182.85418701171875, 634.4552001953125}, {-509.62615966796875, 576.1182861328125}}}
582 for (
int index = 0; index < (
int)
std::size(quads); index += 2) {
596 for (
int index = 0; index < 100000; ++index) {
597 if (index % 1000 == 999)
SkDebugf(
".");
601 if (quad1.
fPts[0] == quad1.
fPts[2]) {
606 if (quad2.
fPts[0] == quad2.
fPts[2]) {
630 for (
int index = 0; index < 100000; ++index) {
634 if (quad1.
fPts[0] == quad1.
fPts[2]) {
639 if (quad2.
fPts[0] == quad2.
fPts[2]) {
651 TRange lowerRange, upperRange;
663 DumpQ(small[0], small[1], smallIndex);
670{{{-770.8492431640625, 948.2369384765625}, {-853.37066650390625, 972.0301513671875}, {-200.62042236328125, -26.7174072265625}}},
671{{{-770.8492431640625, 948.2369384765625}, {513.602783203125, 578.8681640625}, {960.641357421875, -813.69757080078125}}},
672{{{563.8267822265625, -107.4566650390625}, {-44.67724609375, -136.57452392578125}, {492.3856201171875, -268.79644775390625}}},
673{{{563.8267822265625, -107.4566650390625}, {708.049072265625, -100.77789306640625}, {-48.88226318359375, 967.9022216796875}}},
674{{{598.857421875, 846.345458984375}, {-644.095703125, -316.12921142578125}, {-97.64599609375, 20.6158447265625}}},
675{{{598.857421875, 846.345458984375}, {715.7142333984375, 955.3599853515625}, {-919.9478759765625, 691.611328125}}},
677 TRange lowerRange, upperRange;
679 for (
int index = 0; index < (
int)
std::size(qPts); ++index) {
704 {{{-708.0077926931004,-154.61669472244046},
705 {-707.9234268635319,-154.30459999551294},
706 {505.58447265625,-504.9130859375}}},
707 {{{-708.0077926931004,-154.61669472244046},
708 {-711.127526325141,-163.9446090624656},
709 {-32.39227294921875,-906.3277587890625}}},
711 {{{-708.0077926931004,-154.61669472244046},
712 {-708.2875337527566,-154.36676458635623},
713 {505.58447265625,-504.9130859375}}},
714 {{{-708.0077926931004,-154.61669472244046},
715 {-708.4111557216864,-154.5366642875255},
716 {-32.39227294921875,-906.3277587890625}}},
718 {{{-609.0230951752058,-267.5435593490574},
719 {-594.1120809906336,-136.08492475411555},
720 {505.58447265625,-504.9130859375}}},
721 {{{-609.0230951752058,-267.5435593490574},
722 {-693.7467719138988,-341.3259237831895},
723 {-32.39227294921875,-906.3277587890625}}}
725 {{{-708.0077926931004,-154.61669472244046},
726 {-707.9994640658723,-154.58588461064852},
727 {505.58447265625,-504.9130859375}}},
728 {{{-708.0077926931004,-154.61669472244046},
729 {-708.0239418990758,-154.6403553507124},
730 {-32.39227294921875,-906.3277587890625}}}
732 {{{-708.0077926931004,-154.61669472244046},
733 {-707.9993222215099,-154.55999389855003},
734 {68.88981098017803,296.9273945411635}}},
735 {{{-708.0077926931004,-154.61669472244046},
736 {-708.0509091919608,-154.64675214697067},
737 {-777.4871194247767,-995.1470120113145}}}
739 {{{-708.0077926931004,-154.61669472244046},
740 {-708.0060491116379,-154.60889321524968},
741 {229.97088707895057,-430.0569357467175}}},
742 {{{-708.0077926931004,-154.61669472244046},
743 {-708.013911296257,-154.6219143988058},
744 {138.13162892614037,-573.3689311737394}}}
746 {{{-543.2570545751013,-237.29243831075053},
747 {-452.4119186056987,-143.47223056267802},
748 {229.97088707895057,-430.0569357467175}}},
749 {{{-543.2570545751013,-237.29243831075053},
750 {-660.5330371214436,-362.0016148388},
751 {138.13162892614037,-573.3689311737394}}},
757 double longLen = longEdge.
length();
759 double shortLen = shortEdge.
length();
760 return longLen / shortLen;
766 mV[0] = mPta - quad[0];
767 mV[1] = mPtb - quad[0];
788 double div = v1.
dot(
v2);
790 double m =
dir / div;
794 double dist1 = v1.
length() *
m;
795 double dist2 =
v2.length() *
m;
797 SkDebugf(
"%c r1=%1.9g r2=%1.9g m=%1.9g dist1=%1.9g dist2=%1.9g "
798 " dir%c 1a=%1.9g 1b=%1.9g 2a=%1.9g 2b=%1.9g\n", agrees ?
'T' :
'F',
800 mV1[0].crossCheck(
v2), mV1[1].crossCheck(
v2),
801 mV2[0].crossCheck(v1), mV2[1].crossCheck(v1));
804 bool use1 = fabs(dist1) < fabs(dist2);
806 SkDebugf(
"%c dist=%1.9g r=%1.9g\n", agrees ?
'T' :
'F', use1 ? dist1 : dist2,
835 SkDebugf(
"%s %d\n", __FUNCTION__, index);
839 i.intersect(quad1, quad2);
849 bool ccw = s0xt0 < 0;
862 q1[1].fX = quad1[0].fX * (1 - hiPass) + quad1[1].fX * hiPass;
863 q1[1].fY = quad1[0].fY * (1 - hiPass) + quad1[1].fY * hiPass;
864 q2[1].fX = quad2[0].fX * (1 - hiPass) + quad2[1].fX * hiPass;
865 q2[1].fY = quad2[0].fY * (1 - hiPass) + quad2[1].fY * hiPass;
876 double midTest = (loFail + hiPass) / 2;
877 double step = (hiPass - loFail) / 4;
878 while (
step > FLT_EPSILON) {
879 q1[1].fX = quad1[0].fX * (1 - midTest) + quad1[1].fX * midTest;
880 q1[1].fY = quad1[0].fY * (1 - midTest) + quad1[1].fY * midTest;
881 q2[1].fX = quad2[0].fX * (1 - midTest) + quad2[1].fX * midTest;
882 q2[1].fY = quad2[0].fY * (1 - midTest) + quad2[1].fY * midTest;
static int step(int x, SkScalar min, SkScalar max)
static bool intersect(const SkPoint &p0, const SkPoint &n0, const SkPoint &p1, const SkPoint &n1, SkScalar *t)
static bool radianBetween(double start, double test, double end)
static double quadAngle(skiatest::Reporter *reporter, const SkDQuad &quad, double t)
static bool checkParallel(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2)
static double mDistance(skiatest::Reporter *reporter, bool agrees, const SkDQuad &q1, const SkDQuad &q2)
static double endCtrlRatio(const SkDQuad quad)
static void bruteForce(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2, bool ccw)
static double maxDist(const SkDQuad &quad)
static double testArc(skiatest::Reporter *reporter, const SkDQuad &quad, const SkDQuad &arcRef, int octant)
static void setQuadHullSweep(const SkDQuad &quad, SkDVector sweep[2])
static double distEndRatio(double dist, const SkDQuad &quad)
static double maxQuad(const SkDQuad &quad)
static const QuadPts extremeTests[][2]
static double radianSweep(double start, double end)
static bool equalPoints(const SkDPoint &pt1, const SkDPoint &pt2, double max)
static void testQuadAngles(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2, int testNo, SkArenaAlloc *allocator)
static void computeMV(const SkDQuad &quad, const SkDVector &v, double m, SkDVector mV[2])
static bool gPathOpsAngleIdeasVerbose
static bool bruteMinT(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2, TRange *lowerRange, TRange *upperRange)
static void midPointAgrees(skiatest::Reporter *reporter, const SkDQuad &q1, const SkDQuad &q2, bool ccw)
static bool bruteForceCheck(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2, bool ccw)
DEF_TEST(PathOpsAngleOverlapHullsOne, reporter)
static bool orderTRange(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2, double r, TRange *result)
static bool angleDirection(double a1, double a2)
static void makeSegment(SkOpContour *contour, const SkDQuad &quad, SkPoint shortQuad[3])
static int quadHullsOverlap(skiatest::Reporter *reporter, const SkDQuad &quad1, const SkDQuad &quad2)
static void orderQuads(skiatest::Reporter *reporter, const SkDQuad &quad, double radius, TArray< double, false > *tArray)
static bool gPathOpsAngleIdeasEnableBruteCheck
static float next(float f)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
void DumpQ(const SkDQuad &quad1, const SkDQuad &quad2, int testNo)
#define SkDEBUGPARAMS(...)
bool approximately_equal(double x, double y)
bool approximately_zero_when_compared_to(double x, double y)
static int SkScalarSignAsInt(SkScalar x)
#define SkDoubleToScalar(x)
#define SK_ScalarTanPIOver8
#define SK_ScalarInfinity
#define SK_ScalarRoot2Over2
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
#define REPORTER_ASSERT(r, cond,...)
static int ConvexHullOverlaps(SkOpAngle &lh, SkOpAngle &rh)
static int EndsIntersect(SkOpAngle &lh, SkOpAngle &rh)
SkOpAngle * debugLastAngle()
void debugAddAngle(double startT, double endT)
SkOpSegment * next() const
float nextRangeF(float min, float max)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
Optional< SkRect > bounds
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SkDPoint fPts[kPointCount]
void debugSet(const SkDPoint *pts)
SkDPoint ptAtT(double t) const
double cross(const SkDVector &a) const
double dot(const SkDVector &a) const
double crossCheck(const SkDVector &a) const