Logo Search packages:      
Sourcecode: race version File versions

CL_Surface * CAImageManipulation::rotate ( CL_Surface *  surface,
float  angle,
bool  exact = true 
) [static]

Returns a pointer to a new image, based on 'surface' but rotated by an angle of 'degrees' degrees.

Parameters:
surface The original surface
angle Rotation angle in degrees (clock-wise)
exact true: Exact, smooth coloring (calculates color 'between' pixels) false: Inexact but faster.

Definition at line 46 of file caimagemanipulation.cpp.

References getCoordinateX(), getCoordinateY(), and getExactColor().

{
  int width = surface->get_width();
  int height = surface->get_height();

  // Create a temporary canvas which contains the original surface:
  CL_Canvas* tmpCan = new CL_Canvas( width, height );
  surface->put_target( 0,0, 0, tmpCan );

  // Create a new canvas which will contain the rotated surface:
  CL_Canvas* newCan = new CL_Canvas( width, height );

  // Calc size in bytes:
  int bpp = tmpCan->get_bytes_per_pixel();
  int size = width * height * bpp;

  // Only 24bit supported:
  //
  if( bpp==4 ) {

    newCan->lock();

    int i;             // i is the index for the rotated data
    int r, g, b, a;
    float xo, yo;      // Original pixel
    float xr, yr;      // Rotated pixel
    float cx, cy;      // Rotation center

    r=g=b=a=0;

    cx = (float)width/2;
    cy = (float)height/2;

    // Store original image:
    //
    unsigned char *oriData = (unsigned char*)tmpCan->get_data();
    unsigned char *newData = (unsigned char*)newCan->get_data();

    // needs to be calculated only once since angle doesn't change!!
    //
    float cos_angle = cos( angle/ARAD );     // rotating it clockwise (!) by angle,
    float sin_angle = sin( angle/ARAD );

    float x0;
    float y0;

    // Rotate:
    //
    for( i=0; i<size; i+=bpp ) {
      xr = getCoordinateX( width, i );
      yr = getCoordinateY( width, i );

      x0 = (xr - cx);         // rotation around origin, so i create a relative
      y0 = (yr - cy);         //   vector by subtracting (cx, cy) ...

      xo = cx +  x0 * cos_angle + y0 * sin_angle;  // ... and add it again after rotation
      yo = cy +  y0 * cos_angle - x0 * sin_angle;

      if( (int)xo>-0.5 && (int)xo<width+0.5 &&
          (int)yo>-0.5 && (int)yo<height+0.5   ) {

        getExactColor( oriData,
                       width, height,
                       xo, yo,
                       &r, &g, &b, &a,
                       exact );

        newData[i  ] = a;
        newData[i+1] = b;
        newData[i+2] = g;
        newData[i+3] = r;
      }
      else {
        newData[i  ] = 0;
        newData[i+1] = 0;
        newData[i+2] = 0;
        newData[i+3] = 0;
      }
    }
    newCan->unlock();
  }
  delete tmpCan;

  // Return new surface based on the canvas:
  //
  return CL_Surface::create( newCan );
}


Generated by  Doxygen 1.6.0   Back to index