18static constexpr double PI = 3.141592653589793;
35 return std::abs(
A /
B) < 1.0e-7;
44 for (
int i = 0; i < num; ++i) {
54 for (
int i = 0; i < num; ++i) {
73 double Q = (a2 -
b * 3) / 9;
74 double R = (2 * a2 *
a - 9 *
a *
b + 27 * c) / 54;
76 double Q3 = Q * Q * Q;
77 double R2MinusQ3 = R2 - Q3;
86 double* roots = solution;
89 const double theta = acos(
SkTPin(
R / std::sqrt(Q3), -1., 1.));
90 const double neg2RootQ = -2 * std::sqrt(Q);
92 r = neg2RootQ * cos(theta / 3) - adiv3;
95 r = neg2RootQ * cos((theta + 2 *
PI) / 3) - adiv3;
99 r = neg2RootQ * cos((theta - 2 *
PI) / 3) - adiv3;
101 (roots - solution == 1 || !
nearly_equal(solution[1], r))) {
105 const double sqrtR2MinusQ3 = std::sqrt(R2MinusQ3);
106 A = fabs(
R) + sqrtR2MinusQ3;
124 return static_cast<int>(roots - solution);
128 double solution[3]) {
129 double allRoots[3] = {0, 0, 0};
132 for (
int index = 0; index < realRoots; ++index) {
133 double tValue = allRoots[index];
134 if (tValue >= 1.0 && tValue <= 1.00005) {
138 solution[foundRoots++] = 1;
144 solution[foundRoots++] = 0;
146 }
else if (tValue > 0.0 && tValue < 1.0) {
147 solution[foundRoots++] = tValue;
156 return std::abs(
x) < 0.00000001;
164 double roots[2] = {0, 0};
167 for (
int i = 0; i < numRoots; i++) {
168 double tValue = roots[i];
169 if (tValue >= 0 && tValue <= 1.0) {
170 t[validRoots++] = tValue;
190 constexpr int maxIterations = 1000;
191 for (
int i = 0; i < maxIterations; i++) {
197 if ((curr < 0 &&
left < 0) || (curr > 0 &&
left > 0)) {
209 double solution[3]) {
213 double regions[4] = {0, 0, 0, 1};
215 double minMax[2] = {0, 0};
217 int startIndex = 2 - extremaCount;
218 if (extremaCount == 1) {
219 regions[startIndex + 1] = minMax[0];
221 if (extremaCount == 2) {
223 regions[startIndex + 1] = std::min(minMax[0], minMax[1]);
224 regions[startIndex + 2] = std::max(minMax[0], minMax[1]);
230 for (;startIndex < 3; startIndex++) {
231 double root =
binary_search(
A,
B,
C,
D, regions[startIndex], regions[startIndex + 1]);
236 solution[foundRoots++] = root;
static int step(int x, SkScalar min, SkScalar max)
static double binary_search(double A, double B, double C, double D, double start, double stop)
static constexpr double PI
static bool close_to_a_quadratic(double A, double B)
static bool approximately_zero(double x)
static int find_extrema_valid_t(double A, double B, double C, double t[2])
static bool nearly_equal(double x, double y)
bool sk_double_nearly_zero(double a)
static bool SkIsFinite(T x, Pack... values)
static constexpr double sk_ieee_double_divide(double numer, double denom)
bool sk_doubles_nearly_equal_ulps(double a, double b, uint8_t maxUlpsDiff=16)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
static int BinarySearchRootsValidT(double A, double B, double C, double D, double solution[3])
static double EvalAt(double A, double B, double C, double D, double t)
static int RootsValidT(double A, double B, double C, double D, double solution[3])
static int RootsReal(double A, double B, double C, double D, double solution[3])
static int RootsReal(double A, double B, double C, double solution[2])
static bool nearly_equal(SkColor4f x, SkColor4f y)