コード例 #1
0
	Int32 Cubic( Real x3, Real x2, Real x, Real k, Real roots[3] )
	{
		if( IsZero( x3 ) )
			return Quadratic( x2, x, k, roots );

		Real a, b, c, d, a2, p, q, p3, s;

		// Normalize
		a = x2 / x3;
		b = x  / x3;
		c = k  / x3;

		// Reduction to a depressed cubic
		a2 = a * a;
		p = 1.0f / 3.0f * ( -1.0f / 3.0f * a2 + b );
		q = 1.0f / 2.0f * ( 2.0f / 27.0f * a * a2 - 1.0f / 3.0f * a * b + c );
		s = 1.0f / 3.0f * a;

		// Cardano's method
		p3 = p * p * p;
		d = q * q + p3;

		if( IsZero( d ) )
		{
			if( IsZero( q ) )
			{
				roots[0] = -s;
				return 1;			
			}
			else
			{
				Real u = CubeRoot( -q );
				roots[0] = 2.0f * u - s;
				roots[1] = -u - s;
				return 2;
			}
		}

		if( d < 0.0f )
		{
			Real phi = 1.0f / 3.0f * ACOS( -q / SQRT( -p3 ) );
			Real t = 2.0f * SQRT( -p );
			roots[0] =  t * COS( phi ) - s;
			roots[1] = -t * COS( phi + PI / 3.0f ) - s;
			roots[2] = -t * COS( phi - PI / 3.0f ) - s;
			return 3;
		}

		Real u = CubeRoot( SQRT( d ) + ABS( q ) );
		roots[0] = ( q > 0.0f ? - u + p / u : u - p / u ) - s;
		return 1;
	}
コード例 #2
0
ファイル: cmspcs.c プロジェクト: mworks-project/mw_supporting
static
double f(double t)
{

       if (t <= 0.008856)
              return 7.787037037037037037037037037037*t + (16./116.);
       else
              return CubeRoot((float) t); // more precisse than return pow(t, 1.0/3.0);

}
コード例 #3
0
static
double f(double t)
{

      const double Limit = (24.0/116.0) * (24.0/116.0) * (24.0/116.0);

       if (t <= Limit)
              return (841.0/108.0) * t + (16.0/116.0);
       else
              return CubeRoot((float) t);
}
コード例 #4
0
ファイル: RootSolver.cpp プロジェクト: ak4hige/myway3d
int RootSolver::SolveCubic(float c[4], float s[3])
{
	int    i, num;
	float  sub;
	float  A, B, C;
	float  sq_A, p, q;
	float  cb_p, D;

	// normal form: x^3 + Ax^2 + Bx + C = 0
	A = c[2] / c[3];
	B = c[1] / c[3];
	C = c[0] / c[3];

	// substitute x = y - A/3 to eliminate quadric term: x^3 +px + q = 0
	sq_A = A * A;
	p = 0.33333333333333333333333333333333f * (-0.33333333333333333333333333333333f * sq_A + B);
	q = 0.5 * (0.074074074074074074074074074074074f * A * sq_A - 0.33333333333333333333333333333333f * A * B + C);

	// use Cardano's formula
	cb_p = p * p * p;
	D = q * q + cb_p;

	if (MCore::InRange<float>(D, -0.000001f, +0.000001f))
	{
		// one triple solution
		if (MCore::InRange<float>(q, -0.000001f, +0.000001f))
		{
			s[0] = 0;
			num  = 1;
		}
		else // one single and one float solution
		{
			float u = CubeRoot(-q);
			s[0] = 2 * u;
			s[1] = -u;
			num  = 2;
		}
	}
	else if (D < 0) // Casus irreducibilis: three real solutions
	{
		float phi = 0.33333333333333333333333333333333f * Math::ACos(-q / Math::Sqrt(-cb_p));
		float t = 2 * Math::Sqrt(-p);

		s[0] =  t * Math::Cos(phi);
		s[1] = -t * Math::Cos(phi + Math::PI * 0.33333333333333333333333333333333f);
		s[2] = -t * Math::Cos(phi - Math::PI * 0.33333333333333333333333333333333f);
		num = 3;
	}
	else // one real solution
	{
		float sqrt_D = Math::Sqrt(D);
		float u = CubeRoot(sqrt_D - q);
		float v = -CubeRoot(sqrt_D + q);

		s[0] = u + v;
		num  = 1;
	}

	// resubstitute
	sub = 0.33333333333333333333333333333333f * A;

	for (i=0; i<num; ++i)
		s[i] -= sub;

	return num;
}