xref: /aosp_15_r20/external/skia/tests/PathOpsLineParametetersTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "include/core/SkTypes.h"
8 #include "include/private/base/SkDebug.h"
9 #include "src/pathops/SkLineParameters.h"
10 #include "src/pathops/SkPathOpsCubic.h"
11 #include "src/pathops/SkPathOpsTypes.h"
12 #include "tests/PathOpsTestCommon.h"
13 #include "tests/Test.h"
14 
15 #include <array>
16 #include <cfloat>
17 #include <cmath>
18 #include <cstddef>
19 
20 // tests to verify that distance calculations are coded correctly
21 static const CubicPts tests[] = {
22     {{{0, 0}, {1, 1}, {2, 2}, {0, 3}}},
23     {{{0, 0}, {1, 1}, {2, 2}, {3, 0}}},
24     {{{0, 0}, {5, 0}, {-2, 4}, {3, 4}}},
25     {{{0, 2}, {1, 0}, {2, 0}, {3, 0}}},
26     {{{0, .2}, {1, 0}, {2, 0}, {3, 0}}},
27     {{{0, .02}, {1, 0}, {2, 0}, {3, 0}}},
28     {{{0, .002}, {1, 0}, {2, 0}, {3, 0}}},
29     {{{0, .0002}, {1, 0}, {2, 0}, {3, 0}}},
30     {{{0, .00002}, {1, 0}, {2, 0}, {3, 0}}},
31     {{{0, FLT_EPSILON * 2}, {1, 0}, {2, 0}, {3, 0}}},
32 };
33 
34 static const double answers[][2] = {
35     {1, 2},
36     {1, 2},
37     {4, 4},
38     {1.1094003924, 0.5547001962},
39     {0.133038021, 0.06651901052},
40     {0.0133330370, 0.006666518523},
41     {0.001333333037, 0.0006666665185},
42     {0.000133333333, 6.666666652e-05},
43     {1.333333333e-05, 6.666666667e-06},
44     {1.5894571940104115e-07, 7.9472859700520577e-08},
45 };
46 
47 static const size_t tests_count = std::size(tests);
48 
DEF_TEST(PathOpsLineParameters,reporter)49 DEF_TEST(PathOpsLineParameters, reporter) {
50     for (size_t index = 0; index < tests_count; ++index) {
51         SkLineParameters lineParameters;
52         const CubicPts& c = tests[index];
53         SkDCubic cubic;
54         cubic.debugSet(c.fPts);
55         SkASSERT(ValidCubic(cubic));
56         lineParameters.cubicEndPoints(cubic, 0, 3);
57         double denormalizedDistance[2];
58         denormalizedDistance[0] = lineParameters.controlPtDistance(cubic, 1);
59         denormalizedDistance[1] = lineParameters.controlPtDistance(cubic, 2);
60         double normalSquared = lineParameters.normalSquared();
61         size_t inner;
62         for (inner = 0; inner < 2; ++inner) {
63             double distSq = denormalizedDistance[inner];
64             distSq *= distSq;
65             double answersSq = answers[index][inner];
66             answersSq *= answersSq;
67             if (AlmostEqualUlps(distSq, normalSquared * answersSq)) {
68                 continue;
69             }
70             SkDebugf("%s [%d,%d] denormalizedDistance:%g != answer:%g"
71                     " distSq:%g answerSq:%g normalSquared:%g\n",
72                     __FUNCTION__, static_cast<int>(index), (int)inner,
73                     denormalizedDistance[inner], answers[index][inner],
74                     distSq, answersSq, normalSquared);
75         }
76         lineParameters.normalize();
77         double normalizedDistance[2];
78         normalizedDistance[0] = lineParameters.controlPtDistance(cubic, 1);
79         normalizedDistance[1] = lineParameters.controlPtDistance(cubic, 2);
80         for (inner = 0; inner < 2; ++inner) {
81             if (AlmostEqualUlps(fabs(normalizedDistance[inner]), answers[index][inner])) {
82                 continue;
83             }
84             SkDebugf("%s [%d,%d] normalizedDistance:%1.9g != answer:%g\n",
85                     __FUNCTION__, static_cast<int>(index), (int)inner,
86                     normalizedDistance[inner], answers[index][inner]);
87             REPORTER_ASSERT(reporter, 0);
88         }
89     }
90 }
91