SOL9 2.0 Class: AffineTransform

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * AffineTransform.h 
 * Copyright (c) 2009 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 2000.06.19
#pragma once

#include <sol\DC.h>

#include <sol\DIBSection.h>
#include <math.h>


/**
 * AffineTransform class.
 */
namespace SOL {

#define RADIAN(theta)    ((theta)*3.141592/180.0)

class AffineTransform :public Object {

private:

    // This is a typical linear-complement scheme.
    COLORREF AffineTransform::getNearestColor(DIBSection& dibs, double x1, double y1) 
    {
        int ix = (int)x1;
        int iy = (int)y1;

        if (x1 <=0) {
            ix = (int)(x1 - 1.0);
        }
        if ( y1 <=0) {
            iy = (int)(y1 - 1.0);
        }

        // Get colors of near lattice points for x1 and y1.
        COLORREF c1 = dibs.getPixel(ix,   iy  );
        COLORREF c2 = dibs.getPixel(ix+1, iy  );
        COLORREF c3 = dibs.getPixel(ix,   iy+1);
        COLORREF c4 = dibs.getPixel(ix+1, iy+1);

        double deltax = x1 - ix;
        double deltay = y1 - iy;

        // Compute the nearest RGB values from c1, c2, c3 and c4.
        double r = (1.0 - deltay) * ((1.0 - deltax) * GetRValue(c1)
                + deltax * GetRValue(c2) )
                + deltay * ((1.0 - deltax) * GetRValue(c3)
                + deltax * GetRValue(c4) );

        double g = (1.0 - deltay) * ((1.0 - deltax) * GetGValue(c1)
                + deltax * GetGValue(c2) )
                + deltay * ((1.0 - deltax) * GetGValue(c3)
                + deltax * GetGValue(c4) );

        double b = (1.0 - deltay) * ((1.0 - deltax) * GetBValue(c1)
                + deltax * GetBValue(c2) )
                + deltay * ((1.0 - deltax) * GetBValue(c3)
                + deltax * GetBValue(c4) );

        return RGB((int)r, (int)g, (int)b);
    }

public:
    AffineTransform() { }

public:
    ~AffineTransform() { }

public:
    DIBSection* translate(DC& dc, DIBSection& dibs, int dx, int dy)
    {
        int w = dibs.getWidth();
        int h = dibs.getHeight();

        DIBSection* image = new DIBSection(dc, w, h);

        for(int y = 0; y<h; y++) {
            for(int x = 0; x<w; x++) {
                COLORREF color = dibs.getPixel(x, y);
                image->setPixel(x + dx, y + dy, color);
            }
        }
        return image;
    }

    // Note: -90.0 <= angle <= 90.0
    DIBSection*  AffineTransform::rotate(DC& dc, DIBSection& dibs, double theta)
    {
        DIBSection* image = NULL;

        int angle = (int)theta;

        if (angle == 0 || angle == 360 || angle == -360) {
            return image;
        }

        if (theta >360.0 || theta < -360.0) {
            return image;
        }

        int w = dibs.getWidth();
        int h = dibs.getHeight();

        if (theta <0.0) {
            theta = 360.0 +theta;
        }

        double rad = RADIAN(theta);
        double s = sin(rad);
        double c = cos(rad);
    

        // 
        if (theta >=0.0 && theta <= 90.0) {
            int w1 = (int) ((double)w * cos(rad));
            int w2 = (int) ((double)h * sin(rad));
            int h1 = (int) ((double)w * sin(rad));
            int h2 = (int) ((double)h * cos(rad));
        
            image = new DIBSection(dc, (w1 + w2+1), h1 + h2+1);
        
            for(int y = -h1; y <= h2; y++) {
                for(int x = 0; x<= w1 + w2; x++) {
                    double y1 = (double)x * s + (double)y * c;
                    double x1 = (double)x * c - (double)y * s;
                    COLORREF color = getNearestColor(dibs, x1, y1);
                    image->setPixel(x, y+h1, color);
                }
            }
        }

        // 
        if (theta > 90.0 && theta <= 180.0) {
            rad = RADIAN(180.0) - rad;
            int w1 = (int) ((double)w * sin(rad));
            int w2 = (int) ((double)h * cos(rad));
            int h1 = (int) ((double)h * sin(rad));
            int h2 = (int) ((double)w * cos(rad));

            image = new DIBSection(dc, w1 + w2+1, h1 + h2+1);
    
            for(int y = -h1-h2; y <= 0; y++) {
                for(int x = -w2; x<= w1; x++) {
                    double y1 = (double)x * s + (double)y * c;
                    double x1 = (double)x * c - (double)y * s;
                    COLORREF color = getNearestColor(dibs, x1, y1);
                    image->setPixel(x+w2, y+h1+h2, color);
                }
            }
        }

        // 
        if (theta > 180.0 && theta <= 270.0) {
            rad = RADIAN(270.0) - rad;
            int w1 = (int) ((double)h * sin(rad));
            int w2 = (int) ((double)w * cos(rad));
            int h1 = (int) ((double)w * sin(rad));
            int h2 = (int) ((double)h * cos(rad));

            DIBSection* image = new DIBSection(dc, w1 + w2+1, h1 + h2+1);
        
            for(int y = -h1; y <= h2; y++) {
                for(int x = -w1-w2; x<= 0; x++) {
                    double y1 = (double)x * s + (double)y * c;
                    double x1 = (double)x * c - (double)y * s;
                    COLORREF color = getNearestColor(dibs, x1, y1);
                    image->setPixel(x+w1+w2, y+h1, color);
                }
            }
        }

        // 
        if (theta > 270.0 && theta <= 360.0) {
            rad = RADIAN(360.0) - rad;
            int w1 = (int) ((double)h * sin(rad));
            int w2 = (int) ((double)w * cos(rad));
            int h1 = (int) ((double)w * sin(rad));
            int h2 = (int) ((double)h * cos(rad));

            DIBSection* image = new DIBSection(dc, w1 + w2+1, h1 + h2+1);
    
            for(int y = 0; y <= h1+h2; y++) {
                for(int x = -w1; x<= w2; x++) {
                    double y1 = (double)x * s + (double)y * c;
                    double x1 = (double)x * c - (double)y * s;
                    COLORREF color = getNearestColor(dibs, x1, y1);
                    image->setPixel(x+w1, y, color);
                }
            }
        }

        return image;
    }

};

}


Last modified: 19 Dec 2009

Copyright (c) 2009 Antillia.com ALL RIGHTS RESERVED.