| 2338 | */ |
| 2339 | |
| 2340 | int cv::solveCubic( InputArray _coeffs, OutputArray _roots ) |
| 2341 | { |
| 2342 | const int n0 = 3; |
| 2343 | Mat coeffs = _coeffs.getMat(); |
| 2344 | int ctype = coeffs.type(); |
| 2345 | |
| 2346 | CV_Assert( ctype == CV_32F || ctype == CV_64F ); |
| 2347 | CV_Assert( (coeffs.size() == Size(n0, 1) || |
| 2348 | coeffs.size() == Size(n0+1, 1) || |
| 2349 | coeffs.size() == Size(1, n0) || |
| 2350 | coeffs.size() == Size(1, n0+1)) ); |
| 2351 | |
| 2352 | _roots.create(n0, 1, ctype, -1, true, DEPTH_MASK_FLT); |
| 2353 | Mat roots = _roots.getMat(); |
| 2354 | |
| 2355 | int i = -1, n = 0; |
| 2356 | double a0 = 1., a1, a2, a3; |
| 2357 | double x0 = 0., x1 = 0., x2 = 0.; |
| 2358 | int ncoeffs = coeffs.rows + coeffs.cols - 1; |
| 2359 | |
| 2360 | if( ctype == CV_32FC1 ) |
| 2361 | { |
| 2362 | if( ncoeffs == 4 ) |
| 2363 | a0 = coeffs.at<float>(++i); |
| 2364 | |
| 2365 | a1 = coeffs.at<float>(i+1); |
| 2366 | a2 = coeffs.at<float>(i+2); |
| 2367 | a3 = coeffs.at<float>(i+3); |
| 2368 | } |
| 2369 | else |
| 2370 | { |
| 2371 | if( ncoeffs == 4 ) |
| 2372 | a0 = coeffs.at<double>(++i); |
| 2373 | |
| 2374 | a1 = coeffs.at<double>(i+1); |
| 2375 | a2 = coeffs.at<double>(i+2); |
| 2376 | a3 = coeffs.at<double>(i+3); |
| 2377 | } |
| 2378 | |
| 2379 | if( a0 == 0 ) |
| 2380 | { |
| 2381 | if( a1 == 0 ) |
| 2382 | { |
| 2383 | if( a2 == 0 ) |
| 2384 | n = a3 == 0 ? -1 : 0; |
| 2385 | else |
| 2386 | { |
| 2387 | // linear equation |
| 2388 | x0 = -a3/a2; |
| 2389 | n = 1; |
| 2390 | } |
| 2391 | } |
| 2392 | else |
| 2393 | { |
| 2394 | // quadratic equation |
| 2395 | double d = a2*a2 - 4*a1*a3; |
| 2396 | if( d >= 0 ) |
| 2397 | { |