blob: 7d122c0304b65dc0f5a4a772e8506e966a226975 [file] [log] [blame]
 /* * Copyright 2023 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/base/SkQuads.h" #include "include/private/base/SkFloatingPoint.h" #include // Solve 0 = M * x + B. If M is 0, there are no solutions, unless B is also 0, // in which case there are infinite solutions, so we just return 1 of them. static int solve_linear(const double M, const double B, double solution[2]) { if (sk_double_nearly_zero(M)) { solution[0] = 0; if (sk_double_nearly_zero(B)) { return 1; } return 0; } solution[0] = -B / M; if (!std::isfinite(solution[0])) { return 0; } return 1; } int SkQuads::RootsReal(const double A, const double B, const double C, double solution[2]) { if (sk_double_nearly_zero(A)) { return solve_linear(B, C, solution); } const double p = B / (2 * A); const double q = C / A; /* normal form: x^2 + px + q = 0 */ const double p2 = p * p; if (!std::isfinite(p2 - q) || (!sk_double_nearly_zero(p2 - q) && p2 < q)) { return 0; } double sqrt_D = 0; if (p2 > q) { sqrt_D = sqrt(p2 - q); } solution[0] = sqrt_D - p; solution[1] = -sqrt_D - p; if (sk_double_nearly_zero(sqrt_D) || sk_doubles_nearly_equal_ulps(solution[0], solution[1])) { return 1; } return 2; }