00001 #ifndef __cubic_hpp__
00002 #define __cubic_hpp__
00003
00004 #include <crbn/basic/scalar.hpp>
00005
00006
00007 inline int cubic_r(const float& a, const float& b, const float& c, const float& d, float& x0, float& x1, float& x2) {
00008 float a0, a1, a2, a3, q, r, d, s, t;
00009
00010 a3 = a; a2 = b; a1 = c; a0 = d;
00011
00012 a2 /= a3;
00013 a1 /= a3;
00014 a0 /= a3;
00015
00016 q = ((3.0 * a1) - (a2 * a2)) / 9.0;
00017 r = ((9.0 * a1 * a2) - (27.0 * a0) - (2.0 * a2 * a2 * a2)) / 54.0;
00018
00019 d = (q * q * q) + (r * r);
00020
00021 if(d > 0.0f) {
00022 d = sqrt(d);
00023
00024 s = cbrt(r + d);
00025 t = cbrt(r - d);
00026
00027 x0 = x1 = x2 = -(a2 / 3.0) + s + t;
00028
00029 return 1;
00030 }
00031
00032 if (d < 0.0f) {
00033 float theta = acos(r / sqrt(-(q * q * q)));
00034 s = 2.0 * sqrt(-q);
00035 x0 = (s * cos(theta / 3.0)) - (a2 / 3.0);
00036 x1 = (s * cos((theta + (2.0 * M_PI)) / 3.0)) - (a2 / 3.0);
00037 x2 = (s * cos((theta - (4.0 * M_PI)) / 3.0)) - (a2 / 3.0);
00038
00039 if(x0 > x1) {
00040 t = x0;
00041 x0 = x1;
00042 x1 = t;
00043 }
00044 if(x0 > x2) {
00045 t = x0;
00046 x0 = x2;
00047 x2 = t;
00048 }
00049 if(x1 > x2) {
00050 t = x1;
00051 x1 = x2;
00052 x2 = t;
00053 }
00054
00055 return 3;
00056 }
00057
00058 s = cbrt(r);
00059
00060 x0 = -(a2 / 3.0) + (2.0 * s);
00061 x1 = x2 = -(a2 / 3.0) - s;
00062
00063 if(x0 > x1) {
00064 x2 = x0;
00065 x0 = x1;
00066 x1 = x2;
00067 }
00068
00069 return 2;
00070 }
00071
00072 #endif