inline void
  pcl::PolynomialCalculationsT<real>::solveQuadraticEquation (real a, real b, real c, std::vector<real>& roots) const
{
  //cout << "Trying to solve "<<a<<"x^2 + "<<b<<"x + "<<c<<" = 0\n";

  if (isNearlyZero (a))
  {
    //cout << "Highest order element is 0 => Calling solveLineaqrEquation.\n";
    solveLinearEquation (b, c, roots);
    return;
  }

  if (isNearlyZero (c))
  {
    roots.push_back (0.0);
    //cout << "Constant element is 0 => Adding root 0 and calling solveLinearEquation.\n";
    std::vector<real> tmpRoots;
    solveLinearEquation (a, b, tmpRoots);
    for (unsigned int i=0; i<tmpRoots.size (); i++)
      if (!isNearlyZero (tmpRoots[i]))
        roots.push_back (tmpRoots[i]);
    return;
  }

  real tmp = b*b - 4*a*c;
  if (tmp>0)
  {
    tmp = sqrt (tmp);
    real tmp2 = 1.0/ (2*a);
    roots.push_back ( (-b + tmp)*tmp2);
    roots.push_back ( (-b - tmp)*tmp2);
  }
  else if (sqrtIsNearlyZero (tmp))
  {
    roots.push_back (-b/ (2*a));
  }

#if 0
  cout << __PRETTY_FUNCTION__ << ": Found "<<roots.size ()<<" roots.\n";
  for (unsigned int i=0; i<roots.size (); i++)
  {
    real x=roots[i], x2=x*x;
    real result = a*x2 + b*x + c;
    if (!isNearlyZero (result))
    {
      cout << "Something went wrong during solving of polynomial "<<a<<"x^2 + "<<b<<"x + "<<c<<" = 0\n";
      //roots.clear ();
    }
    //cout << "Root "<<i<<" = "<<roots[i]<<". ("<<a<<"x^2 + "<<b<<"x + "<<c<<" = "<<result<<")\n";
  }
#endif
}
void BarrelCorrection::calculatePixelMapping()
{
	LOG_TRACE("BarrelCorrection::calculatePixelMapping()");
	
	if(m_outputWidth <= 0 || m_outputHeight <= 0)
		return;
	
	int correctedRectangle[8][2] = {
		{0,                   0},
		{m_outputWidth / 2,   0},
		{m_outputWidth - 1,   0},
		{0,                   m_outputHeight / 2},
		{m_outputWidth - 1,   m_outputHeight / 2},
		{0,                   m_outputHeight - 1},
		{m_outputWidth / 2,   m_outputHeight - 1},
		{m_outputWidth - 1,   m_outputHeight - 1}
	};
	
	float M[8][9];
	float correctionVectorA[8];
	float correctionVectorB[8];
	
	// Calculate correctionVectorA
	for (int r = 0; r < 8; r++)
	{
		M[r][0] = (float) (correctedRectangle[r][1]*correctedRectangle[r][1]*correctedRectangle[r][0]);
		M[r][1] = (float) (correctedRectangle[r][1]*correctedRectangle[r][0]*correctedRectangle[r][0]);
		M[r][2] = (float) (correctedRectangle[r][1]*correctedRectangle[r][1]);
		M[r][3] = (float) (correctedRectangle[r][0]*correctedRectangle[r][0]);
		M[r][4] = (float) (correctedRectangle[r][1]*correctedRectangle[r][0]);
		M[r][5] = (float) (correctedRectangle[r][1]);
		M[r][6] = (float) (correctedRectangle[r][0]);
		M[r][7] = 1;
		M[r][8] = (float) (m_distortedRectangle[r][1]);
	}
	solveLinearEquation(M);
	for (int r = 0; r < 8; r++)
	{
		correctionVectorA[r] = M[r][8];
	}
	
	// Calculate correctionVectorB
	for (int r = 0; r < 8; r++)
	{
		M[r][0] = (float) (correctedRectangle[r][1]*correctedRectangle[r][1]*correctedRectangle[r][0]);
		M[r][1] = (float) (correctedRectangle[r][1]*correctedRectangle[r][0]*correctedRectangle[r][0]);
		M[r][2] = (float) (correctedRectangle[r][1]*correctedRectangle[r][1]);
		M[r][3] = (float) (correctedRectangle[r][0]*correctedRectangle[r][0]);
		M[r][4] = (float) (correctedRectangle[r][1]*correctedRectangle[r][0]);
		M[r][5] = (float) (correctedRectangle[r][1]);
		M[r][6] = (float) (correctedRectangle[r][0]);
		M[r][7] = 1;
		M[r][8] = (float) (m_distortedRectangle[r][0]);
	}
	solveLinearEquation(M);
	for (int r = 0; r < 8; r++)
	{
		correctionVectorB[r] = M[r][8];
	}
	
	// Calculate pixel mapping
	int dx, dy;
	int *mapping = m_pixelMapping;
	m_pixelMappingMin = 0;
	m_pixelMappingMax = 0;
	for (int y = 0; y < m_outputHeight; y++)
	{
		for (int x = 0; x < m_outputWidth; x++)
		{
			dy = (int) (correctionVectorA[0]*x*y*y +
				correctionVectorA[1]*x*x*y +
				correctionVectorA[2]*y*y +
				correctionVectorA[3]*x*x +
				correctionVectorA[4]*x*y +
				correctionVectorA[5]*y +
				correctionVectorA[6]*x +
				correctionVectorA[7]);
			
			dx = (int) (correctionVectorB[0]*x*y*y +
				correctionVectorB[1]*x*x*y +
				correctionVectorB[2]*y*y +
				correctionVectorB[3]*x*x +
				correctionVectorB[4]*x*y +
				correctionVectorB[5]*y +
				correctionVectorB[6]*x +
				correctionVectorB[7]);
			
			// TODO: Fix this bug!
			// BUG: m_outputWidth should be the with of the input image. Only output with the same width as the input is supported now!
			*mapping = dy * m_outputWidth + dx;
			m_pixelMappingMin = (*mapping) < m_pixelMappingMin ? (*mapping) : m_pixelMappingMin;
			m_pixelMappingMax = (*mapping) > m_pixelMappingMax ? (*mapping) : m_pixelMappingMax;
			mapping++;
		}
	}
}