Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Rotate

 

Rotate is a VCL math code snippet to rotate a TImage under any angle.

 

Rotate is demonstrated in the tool Image Rotater.

 

//From http://www.richelbilderbeek.nl/CppRotate.htm
void Rotate(
  const TImage * const imageOriginal,
  TImage * const imageResult,
  const double angle)
{
  const int maxx = imageResult->Picture->Bitmap->Width;
  const int maxy = imageResult->Picture->Bitmap->Height;
  const double midx = static_cast<double>(maxx) / 2.0;
  const double midy = static_cast<double>(maxy) / 2.0;

  for (int y=0; y!=maxy; ++y)
  {
    for(int x=0; x!=maxx; ++x)
    {
      const double dx1 = static_cast<double>(x) - midx;
      const double dy1 = static_cast<double>(y) - midy;
      double dx2, dy2; //Coordinats in original
      Translate(dx1,dy1,angle,dx2,dy2);
      const double x2 = (static_cast<double>(
          imageOriginal->Picture->Bitmap->Width )
        / 2.0) + dx2;
      const double y2 = (static_cast<double>(
          imageOriginal->Picture->Bitmap->Height)
        / 2.0) + dy2;
      if ( x2 < 1.0
        || y2 < 1.0
        || x2 >= imageOriginal->Picture->Bitmap->Width - 1.0
        || y2 >= imageOriginal->Picture->Bitmap->Height - 1.0
        )
      { //Out of range
        SetPixelVcl(imageResult,x,y,0,0,0);
        continue;
      }
      unsigned char r,g,b;
      GetPixel(imageOriginal,x2,y2,r,g,b);
      SetPixelVcl(imageResult,x,y,r,g,b);
    }
  }
}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppRotate.htm
void GetPixel(
  const TImage * const image,
  const double x,
  const double y,
  unsigned char& red,
  unsigned char& green,
  unsigned char& blue)
{
  const double xRemainder = x - static_cast<int>(x);
  const double yRemainder = y - static_cast<int>(y);
  const int x_tl = ( xRemainder > 0.5 ? x : x-1);
  const int y_tl = ( yRemainder > 0.5 ? y : y-1);
  const double left = ( xRemainder > 0.5
    ? 1.5 - xRemainder : 0.5 - xRemainder);
  const double top = ( yRemainder > 0.5
    ? 1.5 - yRemainder : 0.5 - yRemainder);
  return GetPixel(image,x_tl,y_tl,left,top,red,green,blue);
}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppRotate.htm
void GetPixel(
  const TImage * const image,
  const int x_tl,
  const int y_tl,
  const double left,
  const double top,
  unsigned char& red,
  unsigned char& green,
  unsigned char& blue)
{
  const double right = 1.0 - left;
  const double bottom = 1.0 - top;
  assert(left >= 0.0 && left <=1.0);
  assert(top >= 0.0 && top <=1.0);
  assert(right >= 0.0 && right <=1.0);
  assert(bottom >= 0.0 && bottom <=1.0);

  unsigned char r_tl, g_tl, b_tl;
  unsigned char r_tr, g_tr, b_tr;
  unsigned char r_bl, g_bl, b_bl;
  unsigned char r_br, g_br, b_br;

  GetPixel(image,x_tl+0,y_tl+0,r_tl,g_tl,b_tl);
  GetPixel(image,x_tl+1,y_tl+0,r_tr,g_tr,b_tr);
  GetPixel(image,x_tl+0,y_tl+1,r_bl,g_bl,b_bl);
  GetPixel(image,x_tl+1,y_tl+1,r_br,g_br,b_br);

  const double rTotal
    = (top * left * static_cast<double>(r_tl))
    + (top * right * static_cast<double>(r_tr))
    + (bottom * left * static_cast<double>(r_bl))
    + (bottom * right * static_cast<double>(r_br));
  const double gTotal
    = (top * left * static_cast<double>(g_tl))
    + (top * right * static_cast<double>(g_tr))
    + (bottom * left * static_cast<double>(g_bl))
    + (bottom * right * static_cast<double>(g_br));
  const double bTotal
    = (top * left * static_cast<double>(b_tl))
    + (top * right * static_cast<double>(b_tr))
    + (bottom * left * static_cast<double>(b_bl))
    + (bottom * right * static_cast<double>(b_br));
  assert(rTotal >= 0.0 && rTotal < 256.0);
  assert(gTotal >= 0.0 && gTotal < 256.0);
  assert(bTotal >= 0.0 && bTotal < 256.0);
  red = static_cast<unsigned char>(rTotal);
  green = static_cast<unsigned char>(gTotal);
  blue = static_cast<unsigned char>(bTotal);

}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppRotate.htm
void Translate(
  const double dx1,
  const double dy1,
  const double dAngle,
  double& dx2,
  double& dy2)
{
  const double oldAngle = GetAngle(dx1,dy1);
  const double newAngle = oldAngle - dAngle;
  const double ray
    = std::sqrt((dx1 * dx1) + (dy1 * dy1)); //Pythagoras
  dx2 = std::sin(newAngle) * ray;
  dy2 = -std::cos(newAngle) * ray;
}


 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict