Click here to Skip to main content
15,868,109 members
Articles / Programming Languages / C++
Tip/Trick

Affine Transformations in Computer Graphics

Rate me:
Please Sign up or sign in to vote.
5.00/5 (25 votes)
27 Dec 2012CPOL1 min read 40.8K   140   8
Some simple examples of how to apply affine transformations in computer graphics.

Introduction

In computer graphics, affine transformations are very important. With beginners, trying to implement an affine transformation in a programming language (C/C++) is really a challenge. So this article will show you guys some simple examples that apply affine transformations. These were written in C++, and include:

  • A rotation triangle inside a circle
  • A fan rotation

Background

In geometry, an affine transformation or affine map or an affinity (from the Latin, affinis, "connected with") is a transformation which preserves straight lines (i.e., all points lying on a line initially still lie on a line after transformation) and ratios of distances between points lying on a straight line (e.g., the midpoint of a line segment remains the midpoint after transformation). It does not necessarily preserve angles or lengths, but does have the property that sets of parallel lines will remain parallel to each other after an affine transformation.

Examples of affine transformations include translation, geometric contraction, expansion, homothety, reflection, rotation, shear mapping, similarity transformation, and spiral similarities and compositions of them.

An affine transformation is equivalent to a linear transformation followed by a translation.

Example 1: Rotation Triangle

Note: The IDE for usage is Dev-C++. After installing this IDE successfully,  you need to do something to build, and run graphic programs in it. Refer to this.

Firstly, we have to define Affine:

C++
#include<math.h>
 
typedef float Point[2];
typedef float Affine[3][3];
 
void ptoa(Point A,Affine &B){
  B[0][0]=A[0];
  B[0][1]=A[1];
  B[0][2]=1;
}

void MatMul(Affine A,Affine B,Affine &C,int m,int n){
  int i,j,k;
  for(i=0;i<m;i++)
     for(j=0;j<n;j++){
        C[i][j]=0;
          for(k=0;k<n;k++)
            C[i][j]+=A[i][k]*B[k][j];
      }
}
 
void Rotate(Affine &T,float fi){
   T[0][0]=cos(fi);
   T[0][1]=sin(fi);
   T[0][2]=0;
   T[1][0]=-sin(fi);
   T[1][1]=cos(fi);
   T[1][2]=0;
   T[2][0]=0;
   T[2][1]=0;
   T[2][2]=1;
}

void Move(Affine &T,float x,float y){
   T[0][0]=1;
   T[0][1]=0;
   T[0][2]=0;
   T[1][0]=0;
   T[1][1]=1;
   T[1][2]=0;
   T[2][0]=x;
   T[2][1]=y;
   T[2][2]=1;
}  

The main class is as below:

C++
#include <stdio.h>
#include <graphics.h>
#include "affine.h"
#define RAD 0.017452

// @author : Phat (Phillip ) H. Vu <vuhongphat@hotmail.com>

main(){
	int gd=0,gm=0,n=0;
	int k[50];
	Point x={300,200},y;
	Affine Tz,Ty,Tzz,Tx,Txx,Tyy,Tu,Tuu,T;
	initgraph(&gd,&gm,"");
	ptoa(x,Tx);
	
	// Draw a triangle
	Move(T,-x[0],-x[1]);MatMul(Tx,T,Txx,1,3);
	Move(T,0,100);MatMul(Txx,T,Ty,1,3);
	Rotate(T,120*RAD);MatMul(Ty,T,Tz,1,3);
	Rotate(T,120*RAD);MatMul(Tz,T,Tu,1,3);
	Move(T,x[0],x[1]);
	MatMul(Txx,T,Tx,1,3);
	MatMul(Ty,T,Tyy,1,3);
	MatMul(Tz,T,Tzz,1,3);
	MatMul(Tu,T,Tuu,1,3);
	circle(int(x[0]),int(x[1]),101);
	
	//Rotate
	setwritemode(XOR_PUT);
	while(!kbhit()){
	  //Move
	  Move(T,-x[0],-x[1]);
	  MatMul(Tyy,T,Ty,1,3);
	  MatMul(Tzz,T,Tz,1,3);
	  MatMul(Tuu,T,Tu,1,3);
	
	  //Rotate
	  Rotate(T,n*RAD);
	  MatMul(Ty,T,Tyy,1,3);
	  MatMul(Tz,T,Tzz,1,3);
	  MatMul(Tu,T,Tuu,1,3);
	
	  //move
	  Move(T,x[0],x[1]);
      MatMul(Tyy,T,Ty,1,3);
	  MatMul(Tzz,T,Tz,1,3);
	  MatMul(Tuu,T,Tu,1,3);
	  Tyy[0][0]=Ty[0][0];Tyy[0][1]=Ty[0][1];
	  Tzz[0][0]=Tz[0][0];Tzz[0][1]=Tz[0][1];
	  Tuu[0][0]=Tu[0][0];Tuu[0][1]=Tu[0][1];
	  
	  //Draw triangle
	  k[0]=Ty[0][0];k[1]=Ty[0][1];
	  k[2]=Tz[0][0];k[3]=Tz[0][1];
	  k[4]=Tu[0][0];k[5]=Tu[0][1];
	  k[6]=Ty[0][0];k[7]=Ty[0][1];
	  setcolor(LIGHTRED);
	  drawpoly(4,k);
	  delay(50);
	  drawpoly(4,k);
	  n+=1;
	}
	
	getch();
	closegraph();
} 

That's it. Let's see the result:

Example 2: Rotation Fan

This example shows how we can have a "moving" object but without using Affine. Let's explore the code below:

C++
#include<graphics.h>
#include<conio.h>
#include<math.h>
#include<dos.h>

#define RAD 0.01745329

// @author : Phat (Phillip ) H. Vu <vuhongphat@hotmail.com>

int main()
{
    int r,tx,ty;  // Radian and coordinate of fan.
    int rc,rq,d;
    int gd =0,gm,i;
    int c1[8];
    int c2[8];
    int c3[8];
    
    // Initial
    initgraph(&gd,&gm,"");
    
    tx=getmaxx()/2;    
    ty=getmaxy()/3;
    c1[0]=c1[6]=tx;c1[1]=c1[7]=ty;
    c2[0]=c2[6]=tx;c2[1]=c2[7]=ty;
    c3[0]=c3[6]=tx;c3[1]=c3[7]=ty;
    d=0;
    r=100;
    rq=r-20;
    rc=30;
    
    // Draw fan
    circle(tx,ty,r);
    rectangle(tx-2,ty+r,tx+2,ty+r*2);
    rectangle(tx-10,ty+r*2,tx+10,ty+r*3);
    rectangle(tx-50,ty+r*3,tx+50,ty+r*3+20);
    while(!kbhit())
    {    
        setcolor(BLACK);
        
        c1[2]=tx+rq*sin(d*RAD);
        c1[3]=ty-rq*cos(d*RAD);
        c1[4]=tx+rq*sin((d+rc)*RAD);
        c1[5]=ty-rq*cos((d+rc)*RAD);
        
        c2[2]=tx+rq*sin((d+120)*RAD);
        c2[3]=ty-rq*cos((d+120)*RAD);
        c2[4]=tx+rq*sin((d+120+rc)*RAD);
        c2[5]=ty-rq*cos((d+120+rc)*RAD);
        c3[2]=tx+rq*sin((d+240)*RAD);
        c3[3]=ty-rq*cos((d+240)*RAD);
        c3[4]=tx+rq*sin((d+240+rc)*RAD);
        c3[5]=ty-rq*cos((d+240+rc)*RAD);
        
        setfillstyle(2,BLUE);
        fillpoly(4,c1);
        fillpoly(4,c2);
        fillpoly(4,c3);
        
        delay(5);
        setfillstyle(2,BLACK);
        fillpoly(4,c1);
        fillpoly(4,c2);
        fillpoly(4,c3);
                
        d+=2;
        if(d==360) d=0;
    }
    getch();
    closegraph();
    return 0;
}

Got the result:

Rotation Fan

References

History

  • First version published on Dec 28, 2012

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionMy 5 vote Pin
Beginner Luck6-Jan-16 19:19
professionalBeginner Luck6-Jan-16 19:19 
GeneralMy vote of 5 Pin
uyentran311@yahoo.com10-Jan-13 14:48
uyentran311@yahoo.com10-Jan-13 14:48 
GeneralRe: My vote of 5 Pin
WebMaster10-Jan-13 14:53
WebMaster10-Jan-13 14:53 
GeneralMy vote of 5 Pin
Thong Nguyen883-Jan-13 14:16
Thong Nguyen883-Jan-13 14:16 
GeneralRe: My vote of 5 Pin
WebMaster10-Jan-13 14:53
WebMaster10-Jan-13 14:53 
GeneralMy vote of 5 Pin
Member 97262843-Jan-13 3:57
Member 97262843-Jan-13 3:57 
GeneralRe: My vote of 5 Pin
WebMaster10-Jan-13 14:53
WebMaster10-Jan-13 14:53 
GeneralMy vote of 3 Pin
ahlav28-Dec-12 4:57
ahlav28-Dec-12 4:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.