2014年2月26日 星期三

Rotate an square image by 90 degrees in place

Main idea:

  • There is a relation between the locations of exchanged

 1   2   3   4
 5   6   7   8
 9  10 11 12
13 14 15 16

after rotation

13  9  5 1
14 10 6 2
15 11 7 3
16 12 8 4

(i, j) -> (j, n-1-i) -> (n-1-i, n-1-j) -> (n-1-j, i) -> (i, j)

  • Swapping partial image is enough
  • Carefully handle the size of image
 1   2   3   4 
 5   6   7   8
 9  10 11 12
13 14 15 16

  1   2   3   4   5
  6   7   8   9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25


C++ code :

#include <iostream>
using namespace std;

class Mat{
public:
    Mat( const int *a, const int size );
    ~Mat();
    void showElement() const;
    void rotate( );
private:
    int **m_image;
    int m_size;
};

Mat::Mat( const int *a, const int size ) : m_image(NULL), m_size(size)
{
    if( m_size <= 0 )   return;
    m_image = new int*[m_size]( );
    for( int i = 0 ; i < m_size ; i++ )
        m_image[i] = new int[m_size]( );

    // assign array value to member variable
    for( int i = 0, p = 0 ; i < m_size ; i++ )
        for( int j = 0 ; j < m_size ; j++ )
            m_image[i][j] = a[p++];

}
Mat::~Mat(){
    if(m_image){
        for( int i = 0 ; i < m_size ; i++ )
            delete [] m_image[i];
        delete [] m_image;
    }
}

void Mat::showElement() const{
    for( int i = 0 ; i < m_size ; i++ ){
        for ( int j = 0 ; j < m_size ; j++ )
            cout << m_image[i][j] << " ";
        cout << endl;
    }
}

void Mat::rotate( ){
    const int final_row = (m_size - 1) / 2;
    const int final_col = (m_size % 2) ? (final_row - 1) : final_row;
    const int final_index = m_size - 1;

    // (i, j) -> (j, final_index-i) -> (final_index-i, final_index-j)
    //  -> (final_index-j, i) -> (i, j)

    for( int i = 0 ; i <= final_row ; i++ ){
        for( int j = 0 ; j <= final_col ; j++ )
        {
            int temp = m_image[final_index-j][i];
            m_image[final_index-j][i] = m_image[final_index-i][final_index-j];
            m_image[final_index-i][final_index-j] = m_image[j][final_index-i];
            m_image[j][final_index-i] = m_image[i][j];
            m_image[i][j] = temp;
        }
    }
}
int main( ){
    const int SIZE = 4;
    int image[SIZE * SIZE] = {1, 2, 3, 4,
                             5, 6, 7, 8,
                             9, 10,11,12,
                             13,14,15,16};
    Mat mat( image, SIZE );

    mat.showElement( );
    mat.rotate( );

    cout << endl;
    mat.showElement( );


    cout << endl;
    const int SIZE2 = 5;
    int image2[SIZE2 * SIZE2] = {1, 2, 3, 4, 5,
                             6, 7, 8, 9, 10,
                             11, 12, 13, 14, 15,
                             16, 17, 18, 19, 20,
                             21, 22, 23, 24, 25};
    Mat mat2( image2, SIZE2 );

    mat2.showElement( );
    mat2.rotate( );

    cout << endl;
    mat2.showElement( );

    return 0;
}

沒有留言:

張貼留言