Skip to content

Commit 640f188

Browse files
mradul2alalek
andauthored
Merge pull request opencv#19583 from theroyalpekka:patch-1
* Update polynom_solver.cpp This pull request is in the response to Issue opencv#19526. I have fixed the problem with the cube root calculation of 2*R. The Issue was in the usage of pow function with negative values of R, but if it is calculated for only positive values of R then changing x0 according to the parity of R, the Issue is resolved. Kindly consider it, Thanks! * add cv::cubeRoot(double) Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
1 parent a1e2c4f commit 640f188

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

modules/calib3d/src/polynom_solver.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ int solve_deg3(double a, double b, double c, double d,
6565
return 3;
6666
}
6767
else {
68-
x0 = pow(2 * R, 1 / 3.0) - b_a_3;
68+
double cube_root = cv::cubeRoot(2 * R);
69+
x0 = cube_root - b_a_3;
6970
return 1;
7071
}
7172
}
@@ -82,8 +83,15 @@ int solve_deg3(double a, double b, double c, double d,
8283
}
8384

8485
// D > 0, only one real root
85-
double AD = pow(fabs(R) + sqrt(D), 1.0 / 3.0) * (R > 0 ? 1 : (R < 0 ? -1 : 0));
86-
double BD = (AD == 0) ? 0 : -Q / AD;
86+
double AD = 0.;
87+
double BD = 0.;
88+
double R_abs = fabs(R);
89+
if (R_abs > DBL_EPSILON)
90+
{
91+
AD = cv::cubeRoot(R_abs + sqrt(D));
92+
AD = (R >= 0) ? AD : -AD;
93+
BD = -Q / AD;
94+
}
8795

8896
// Calculate the only real root
8997
x0 = AD + BD - b_a_3;

modules/core/include/opencv2/core/base.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,21 @@ _AccTp normInf(const _Tp* a, const _Tp* b, int n)
587587
*/
588588
CV_EXPORTS_W float cubeRoot(float val);
589589

590+
/** @overload
591+
592+
cubeRoot with argument of `double` type calls `std::cbrt(double)` (C++11) or falls back on `pow()` for C++98 compilation mode.
593+
*/
594+
static inline
595+
double cubeRoot(double val)
596+
{
597+
#ifdef CV_CXX11
598+
return std::cbrt(val);
599+
#else
600+
double v = pow(abs(val), 1/3.); // pow doesn't support negative inputs with fractional exponents
601+
return val >= 0 ? v : -v;
602+
#endif
603+
}
604+
590605
/** @brief Calculates the angle of a 2D vector in degrees.
591606
592607
The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured

0 commit comments

Comments
 (0)