Vous êtes sur la page 1sur 61

TRANSFORMACIONES

GEOMTRICAS
GRAFICACIN I

Transformaciones en dos
dimensiones
Los objetos se definen mediante un conjunto de
puntos. Las transformaciones son procedimientos para
calcular nuevas posiciones de estos puntos, cambiado
el tamao y orientacin del objeto.
Las operaciones bsicas de transformacin son

Traslacin

Escalamiento

Rotacin.

Traslacin
Las coordenadas (x, y) de un objeto se transforman a (x', y')
de acuerdo a las frmulas:

x ' x Tx ,

y ' y Ty

El par (Tx, Ty) se conoce como vector de traslacin.


y

x
(a)

Ejemplo traslacin
Vector de desplazamiento T = (3, 2)

(x1, y1) = (2, 3)


(x2, y2) = (1, 1)
(x3, y3) = (3, 1)

(x1, y1) = (2, 3) + (3, 2) = (1, 1)


(x2, y2) = (1, 1) + (3, 2) = (2, 1)
(x3, y3) = (3, 1) + (3, 2) = (0, 1)

(x1, y1)

Vector de desplazamiento
(x1, y1)

(x2, y2)

(x2, y2)

(x3, y3)

(x3, y3)

Escalamiento
El escalamiento modifica el tamao de un polgono. Para
obtener este efecto, se multiplica cada par coordenado (x, y)
por un factor de escala en la direccin x y en la direccin y
para obtener el par (x', y').
Las frmulas son

x' x Sx

y' y Sy

x
(a)

x
(b)

Ejemplo escalamiento
Factores de escalamiento S = (2, 1)

(x1, y1) = (2, 3)


(x2, y2) = (1, 1)
(x3, y3) = (3, 1)

(x1, y1) = (2*2, (1)3) = (4, 3)


(x2, y2) = (2*1, (1)1) = (2, 1)
(x3, y3) = (2*3, (1)1) = (6, 1)

(x1, y1)

(x2, y2)

(x3, y3)

(x3, y3)

(x2, y2)

(x1, y1)

Rotacin
La rotacin gira los puntos de una figura alrededor de un punto
fijo. De la figura se obtiene
x ' r cos r cos cos r sen sen

y ' r sen r sen cos r cos sen

Simplificando

y
(x', y')

x ' x cos y sen


y ' y cos x sen

(x, y)

Ejemplo rotacin
ngulo de rotacin = 45
(x1, y1) = (2, 3)

(x1, y1)
(x3, y3)
(x1, y1)

(x2, y2) = (1, 1)


(x3, y3) = (3, 1)

(x1, y1) = (2cos(45) 3sen(45), 3cos(45) + 2sen(45))


= (2*0.7073*0.707, 3*0.707+2*0.707) = (0.707, 3,54)
(x2, y2) = (3cos(45) sen(45), cos(45) + 3sen(45))
= (3*0.7070.707, 0.707+3*0.707) = (1.414, 2.828)
(x3, y3) = (cos(45) sen(45), cos(45) + sen(45))
= (0.7070.707, 0.707+0.707) = (0, 1.414)

(x2, y2)

(x2, y2)

(x3, y3)

Escalamiento respecto a un punto


fijo
Se puede llevar a cabo un escalamiento respecto a un punto
fijo trasladando primero ese punto al origen, despus
escalando y luego regresando el objeto a la posicin original.
Las ecuaciones son

x' x F x x F S x , y' y F y y F S y

Reacomodando

x ' x S x 1 S x x F

(x

y ' y S y 1 S y y F

,y

x
(a)

x
(b)

Rotacin respecto a un punto


arbitrario
La rotacin respecto a un punto arbitrario es
y

x ' x R x x R cos y y R sen

y ' y R y y R cos x x R sen


x
(x

,y )
R

Ejemplo rotacin 2
ngulo de rotacin = 90
Centro de rotacin (3,1)
(x1, y1) = (2, 3)

(x1, y1)

(x2, y2) = (1, 1)


(x3, y3) = (3, 1)

x1 = 3 + (2 3)cos(90) (3 1) sen(90)= 3 + 2 = 5
y1 = 1 + (3 1)cos(90) + (2 3) sen(90)= 1 + 1 = 2
x2 = 3 + (1 3)cos(90) (1 1) sen(90)= 3
y2 = 1 + (1 1)cos(90) + (1 3) sen(90)= 1 + 2 = 3
x3 = 3 + (3 3)cos(90) (1 1) sen(90)= 3
y3 = 1 + (1 1)cos(90) + (3 3) sen(90)= 1

(x2, y2)
(x1, y1)

(x2, y2)

(x3, y3) = (x3, y3)

Cdigo en C
struct point{
float x,y;
};
void translate(point &p, float tx, float ty){
p.x = p.x + tx;
p.y = p.y + ty;
}
void scale(point &p, float sx, float sy){
p.x = sx*p.x;
p.y = sy*p.y;
}
void rotate(point &p, float a){
float sn = sin(a*PI/180);
float cs = cos(a*PI/180);
p.x = cs*p.x - sn*p.y;
p.y = cs*p.y + sn*p.x;
}

void rotateFix(point &p, float a,float xr, float yr){


translate(p,-xr,-yr);
rotate(p,a);
translate(p,xr,yr);
}
void scaleFix(point &p, float sx, float sy,float xf, float yf)
{
translate(p,-xf,-yf);
scale(p,sx,sy);
translate(p,xf,yf);
}
void translatePoly(point *p,int n, float tx, float ty){
for(int i=0; i<n ; i++)
translate(p[i],tx,ty);
}

Tarea
Escriba una funcin que dibuje un polgono relleno. Haciendo
uso de esa funcin, escriba un programa en C que dibuje la
figura que se muestra transformada mediante traslaciones,
escalamientos y rotaciones para crear la imagen que se
muestra.

Coordenadas homogneas
Para poder representar las tres transformaciones en forma
matricial como producto de matrices, es necesario representar
los puntos en coordenadas homogneas.
Estas coordenadas agregan una tercer componente a las
coordenadas bidimensionales. De tal forma que, un punto (x, y)
pasa a ser (x, y, W). El punto en coordenadas Cartesianas
representado por esta trada es el (x/W, y/W). El valor de W es
generalmente 1.

Representacin matricial de
traslaciones
Haciendo uso de coordenadas homogneas la traslacin puede
representarse como:

x'

y ' 1 x

y 1 0
T
x

0
1

Ty

En forma abreviada la transformacin se representar por T(Tx, Ty)

T Tx , Ty

0
T
x

0
1
Ty

0
1

P' P T Tx , Ty

Representacin matricial de
escalamientos
Haciendo uso de coordenadas homogneas el escalamiento
puede representarse como:

x'

y ' 1 x

Sx

y 1 0
0

0
Sy
0

En forma abreviada la transformacin se representar por S(Sx, Sy)

S Sx , S y

Sx

0
0

0
Sy
0

0
1

P' P S S x , S y

Representacin matricial de
rotaciones
Haciendo uso de coordenadas homogneas la rotacin puede
representarse como:

x'

y ' 1 x

cos sen

y 1 sen cos

0
0

0
1

En forma abreviada la transformacin se representar por R()


cos sen

R sen cos

0
0

0
1

P' P R

Composicin de
transformaciones
Para aplicar varias transformaciones a un conjunto de puntos
basta con combinar las matrices de transformacin en una sola,
mediante multiplicacin matricial. En caso de tener solo
transformaciones del mismo tipo, la combinacin sigue reglas
muy simples.

Traslacin:

T Tx1 , Ty1 T Tx 2 , Ty 2 T Tx1 Tx 2 , Ty1 Ty 2

Escalamiento:

S S x 1 , S y1 S S x 2 , S y 2 S S x1 S x 2 , S y1 S x 2

Rotacin:

R 1 R 2 R 1 2

Escalamiento respecto a un punto


fijo en forma matricial
Para llevar a cabo un escalamiento respecto a un punto fijo, se
procede multiplicando una matriz de traslacin para llevar el
punto fijo al origen por una de escalamiento y posteriormente
por otra de traslacin para llevar al punto fijo a su posicin
original.

0
x F

1
yF

0 S x

0 0
1 0

0 1

0 0
1 x F

0
Sy
0

Sx

Sy

1 S x x F

1 S y
y

1
yF

0
1

(x

,y

(a)
Objeto original y punto fijo

(b)
Traslada de manera que el
punto fijo quede en el origen
(x

(c)
Escala el objeto respecto al origen

,y

(d)
Traslada de manera que el
punto fijo quede en la posicin
original

Rotacin respecto a un punto fijo


en forma matricial
Para llavar a cabo una rotacin respecto a un punto fijo, se
procede multiplicando una matriz de traslacin para llevar el
punto fijo al origen por una de rotacin y posteriormente por
otra de traslacin para llevar al punto fijo a su posicin
original.

1
0
xR

0
1
yR

0
0
1

cos
sen

cos
sen
1 cos x R y R sen

sen
cos
0

0
0
1

1
0
x R

0
1
yR

0
0
1

sen
cos
1 cos y R x R sen

0
0
1

(x

,y

(a)
Objeto original y punto fijo

(b)
Traslada de manera que el
punto fijo quede en el origen
(x

(c)
Rota el objeto respecto al origen

,y

(d)
Traslada de manera que el
punto fijo quede en la posicin
original

Forma general
En general una transformacin que utilice traslaciones,
escalamientos y rotaciones tendr la forma:

x'

y ' 1 x

y 1 b
c

e
f

0
1

Por tanto, el clculo de las coordenadas transformadas se


podr hacer con las siguientes ecuaciones

x' ax by c
y ' dx ey f

Otras transformaciones
Otras transformaciones que permiten llevar
a cabo operaciones muy tiles, estas son:
Reflexiones
Corte.

Reflexiones en x y y
Las reflexiones respecto al eje x y y se obtienen con las matrices
siguientes:
1 0 0
1 0 0

0 1 0
0 1 0
0 0 1
0 0 1
Posicin original

Posicin original

Posicin reflejada

Posicin reflejada
(a)

(b)

Reflexin respecto al origen


La reflexin respecto al origen
se obtiene con :
0

0
0

1 0
0 1

Posicin original

Posicin reflejada
(a)

Reflexin respecto a la recta y =


x
Una reflexin respecto a la recta y = x, puede obtenerse en tres
pasos: girar un ngulo de 45 en el sentido de las manecillas del
reloj, una reflexin respecto al eje x, y una rotacin de 45 grados
en contra del sentido del reloj.
0 1 0

1
0
0

0 0 1
Posicin original
Posicin original
Posicin reflejada

(a) Rotacin de -45 grados

(b) Reflexin respecto a x.

(a) Rotacin de 45 grados

Corte en x
El corte produce una deformacin similar al deslizamiento de
una capa sobre otra. El corte en x se produce por la matriz:
1

SH x

0 0

1 0
0 1

y ' y shy x
y

(0,1)

(0,0)

x' x shx y

(2,1)

(1,1)

(1,0)
(a)

(0,0)

(1,0)
(b)

(3,1)

Corte en y
El corte en y se produce por la matriz
1 SH y

0
0

0
1

1
0

(1,3)
y

y
(1,2)

(0,1)

(0,0)

(1,1)

(1,0)
(a)

(0,1)
x

(0,0)
(b)

Implementacin de transformaciones
con matrices
Para la implementacin de matrices es conveniente definir tipos
para punto y matriz.
Luego funciones para crear las matrices de las transformaciones
bsicas.
Lo primero es crear una matriz unitaria y a partir de est crear las
dems funciones.
Es necesaria definir una funcin para multiplicar matrices y poder
acumular las transformaciones.
Otra funcin debe aplicar una matriz de transformacin a un
punto y regresar el punto transformado.
Finalmente aplicar la matriz a un ppolgono.

Tipos bsicos
Los tipos bsicos para punto, matriz y polgono son los
siguientes:
typedef double Point[3];
typedef double Matrix[3][3];
typedef Point poligono[10];
El punto p(1, -4) se define como
Point p = {1,-4,1};

Crear matriz identidad


La matriz identidad es la base para las dems funciones
void set_identity(Matrix m){
int i,j;
for(i = 0; i<3 ; i++)
for(j = 0; j<3 ; j++)
m[i][j] = (i==j);
}

Matrices de traslacin y
escalamiento
Matriz de traslacin.
void create_traslation_matrix(double tx, double
ty,Matrix t){
set_identity(t);
t[2][0] = tx;
t[2][1] = ty;
}
Matriz de escalamiento:
void create_scale_matrix(double sx, double sy,Matrix
t){
set_identity(t);
t[0][0] = sx;
t[1][1] = sy;
}

Matriz de rotacin
El ngulo se especifica en grados.
void create_rotation_matrix(double
a,Matrix t){
set_identity(t);
double sn = sin(a*PI/180);
double cs = cos(a*PI/180);
t[0][0] = cs; t[0][1] = sn;
t[1][0] = -sn;t[1][1] = cs;
}

Matriz de corte
Solo es necesario definir una matriz de corte. Si se hace solo
corte en x, shy = 0 y si se hace solo corte en y, shx = 0.
void create_shear_matrix(double shx, double
shy,Matrix t){
set_identity(t);
t[0][1] = shy;
t[1][0] = shx;
}

Acumula dos transformaciones


Los parmetros m1 y m2 son de entrada, el resultado se almacena
en m.
void accumulate_matrices(Matrix m1,Matrix
m2,Matrix m){
int i,j,k;
double s;
for(i = 0; i<3 ; i++)
for(j = 0; j<3 ; j++){
s = 0;
for(k = 0; k<3 ; k++)
s = s+m1[i][k]*m2[k][j];
m[i][j] = s;
}
}

Transformar un punto y un polgono


El punto de entrada es p1 y el de salida p2.
void transformPoint(Point p1,Matrix m,Point p2){
p2[0] = m[0][0]*p1[0]+m[1][0]*p1[1]+m[2][0]*p1[2];
p2[1] = m[0][1]*p1[0]+m[1][1]*p1[1]+m[2][1]*p1[2];
p2[2] = m[0][2]*p1[0]+m[1][2]*p1[1]+m[2][2]*p1[2];
}
El polgono de entrada es p1 y el de salida p2. n es el nmero de puntos del
polgono.
void transformPoly(poligono p1,int n,Matrix
m,poligono p2){
for(int i = 0;i<n;i++)
transformPoint(p1[i],m,p2[i]);
}

Dibujar polgono
Dibuja un polgono. Note que la tercer coordenada no se usa.
void draw(poligono p,int n){
moveto((int)p[0][0],(int)p[0][1]);
for(int i=1;i<n;i++){
lineto((int)p[i][0],(int)p[i][1]);
}
}

Transformaciones VentanaPuerto de visin


Las transformaciones ventana-puerto de visin, mapean puntos
en el mundo real a puntos en la pantalla.

Puerto de visin 2

Puerto de visin 1
Ventana
Coordenadas mundiales

Coordenadas de pantalla

Transformaciones de visin
(xmax, ymax)

(xmin, ymin)
Ventana en coordenadas mundiales

Ventana trasladada al origen


(umax, vmax)

(umin, vmin)
Ventana escalada al tamao
del rea de visin.

Traslacin hasta la posicin final.

Transformaciones de visin
(continuacin)
M WV

umax umin vmax vmin


T umin , vmin
T xmin , ymin S
,
xmax xmin ymax ymin
1
0
xmin

0
1
ymin

umax u min
x x
min
0 max
0
0

1
0

0
vmax vmin
ymax ymin
0

1
0 0

1 umin

0
1
vmin

0
0
1

Transformaciones de visin
(continuacin)

u max umin
xmax xmin

M WV

xmin

umax umin
umin
xmax xmin

ymin

vmax vmin
ymax ymin
vmax vmin
vmin
ymax ymin

Implementacin en C
void crate_window_view_matrix(
double xmin,double ymin, double xmax, double
ymax, int umin, int vmin, int umax, int vmax,
Matrix m){
Matrix m1,m2,m3,m4;
create_traslation_matrix(-xmin,-ymin,m1);
create_scale_matrix((umax-umin)/(xmax-xmin),
(vmax-vmin)/(ymax-ymin),m2);
create_traslation_matrix(umin,vmin,m3);
accumulate_matrices(m1,m2,m4);
accumulate_matrices(m4,m3,m);
}

Rutina de despliegue
void show_polygon(
double xmin,double ymin,double xmax,double ymax,
int umin,int vmin,int umax,int vmax,poligono p){
Matrix m1,m2;
poligono p2,p3;
//poligonos transformados
int xv1,xv2,yv1,yv2; //coordenadas del viewport
//es necesario ordenar las coordenadaas del
viewport
if(umin>umax){
xv1 = umax; xv2 = umin;
}else{
xv1 = umin; xv2 = umax;
}
if(vmin>vmax){
yv1 = vmax; yv2 = vmin;
}else{
yv1 = vmin; yv2 = vmax;
}

//dibuja un rectngulo para delimitar el viewport


setlinestyle(DOTTED_LINE,0,NORM_WIDTH);
rectangle(xv1,yv1,xv2,yv2);
//es necesario trasladar al origen porque el viewport
// define coordenadas con 0,0 en la esquina superior
// izquierda
create_traslation_matrix(-xv1,-yv1,m2);
crate_window_view_matrix(xmin,ymin,xmax,ymax,
umin,vmin,umax,vmax,m1);
//transforma a coordenadas de visin
transformPoly(p,10,m1,p2);
//traslada pogono al origen del viewport
transformPoly(p2,10,m2,p3);
//establece viewport
setviewport(xv1,yv1,xv2,yv2,true);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
draw(p3,10);
setviewport(0,0,getmaxx(),getmaxy(),false);
}

Ejemplo de funcin main


main(){
poligono p,p2;
Matrix m1,m2;
initPol(p);
initwindow(500,500);
show_polygon(5,5,20,20,220,350,450,20,p);
show_polygon(-1,-1,11,11,20,100,100,20,p);
show_polygon(-10,-10,20,20,20,200,200,120,p);
show_polygon(-1,-1,5,5,20,370,140,250,p);
getch();
}

Salida del ejemplo

Propiedades de las
transformaciones
Los vectores fila de la submatriz superior 2x2 de rotacin
tienen tres propiedades:
1. Cada uno es un vector unidad
2. Cada uno es perpendicular al otro (su producto punto es
cero)
3. El primer y segundo vector se rotarn por R() para que
caigan sobre los ejes x y y positivos.
Una matriz que cumple esto se le llama ortogonal especial.

Una matriz de transformacin de la forma:

r11
r
21
0

r12
r22
0

tx
t y
1

Donde la submatriz superior de 2x2 es ortogonal, conserva los


ngulos y las longitudes.
Estas transformaciones se denominan de cuerpo rgido.
Una secuencia arbitraria de traslaciones, rotaciones y
escalamientos conserva el paralelismo de las lneas, pero no la
longitud ni los ngulos. Estas transformaciones se denominan
transformaciones afines.

Operaciones de rastreo
El buffer de pantalla se puede manipular directamente para
llevar a cabo algunas transformaciones. La ms sencilla es la
copia de un bloque de un lugar de la pantalla a otro.
Para girar una figura un ngulo mltiplo de 90 grados se
pueden lograr invirtiendo renglones por columnas. La rotacin
por 180 grados se logra invirtiendo cada rengln y
posteriormente invirtiendo los renglones.
Para otros ngulos cada rea de pixel de destino se diagrama
sobre la matriz que se gira y se calcula la cantidad de
superposicin con las reas de pixel que se giran. Entonces se
calcula una intensidad para el pixel al promediar las
intensidades de los pixeles fuente superpuestos.

Rotacin diferente de 90 grados

Escalamiento del mapa de bits


Escalamos las reas de pixeles en el bloque original al
emplear los valores de sx y sy y diagramar el rectngulo que
se escala sobre un conjunto de pixeles destino. La intensidad
de cada pixel destino se designa de acuerdo con el rea de
superposicin con las reas de pixel que se escalan.

Tarea
Escribir una biblioteca para realizar transformaciones de 2D
utilizando matrices, defina lo siguiente:
- Tipo vector y tipo matriz en coordenadas homogneas
- Rutinas para: trasladar, rotar, escalar, reflejar, cortar y
transformacin de puerto de visin.

Animacin
Para lograr una animacin mediante transformaciones es
conveniente mantener una copia del los objetos sin transformar.
Para lograr la animacin se copia el objeto original, luego se le
aplican a esta copia las transformaciones a realizar y se dibuja
el objeto transformado.
-Copiar objeto
- transformar
- dibujar

Ejemplo
Define un cruz:
void init(){
poly[0].x = 0;poly[0].y = 10;
poly[1].x = 10;poly[1].y = 10;
poly[2].x = 10;poly[2].y = 0;
poly[3].x = 20;poly[3].y = 0;
poly[4].x = 20;poly[4].y = 10;
poly[5].x = 30;poly[5].y = 10;
poly[6].x = 30;poly[6].y = 20;
poly[7].x = 20;poly[7].y = 20;
poly[8].x = 20;poly[8].y = 30;
poly[9].x = 10;poly[9].y = 30;
poly[10].x = 10;poly[10].y = 20;
poly[11].x = 0;poly[11].y = 20;
}

void play(){
while(true){
char c;
if(kbhit()){
int i,p=0;
c = (char)getch();
unsigned int size;
switch(c){
point p1[20];
case 27:return;
float a=0,da = 0,vx=0,vy=0,x=0,y=0;
case 'i':vy--;break;
setactivepage(1);
case 'm':vy++;break;
for(i = 0; i< 1000; i++){
putpixel(rand()%400,rand()%400,rand()%15+1); case 'j':vx--;break;
case 'k':vx++;break;
}
case 'r':da--;break;
size = imagesize(0, 0, 400, 400);
case 't':da++;break;
/* allocate memory to hold the image */
case e':s--;break;
img = malloc(size);
case w':s++;break;
/* grab the image */
}
getimage(0,0,400,400,img);
}
x += vx;
y += vy;
a += da;

inicia
Lee teclado

a=(a>360)?a-360:a;
a=(a<-360)?a+360:a;
if(x>400) x= 0;
if(y>400) y= 0;
if(x<0) x= 400;
if(y<0) y= 400;

//copia el polgono orignal


for(i = 0; i<12 ; i++) p1[i] = poly[i];
setfillstyle(1,BLUE);
setcolor(BLUE);
Objeto original
rotatePoly(p1,12,a,15,15);
scalePoly(p1,12,3+s,3+s);
Gira a grados
translatePoly(p1,12,x,y);
setvisualpage(1-p);
Se escala 3+s veces
setactivepage(p);
putimage(0,0,img,COPY_PUT);
Traslada a x,y
fillPoly(p1,12);
delay(10);
swapbuffers( );
p = 1-p;
}

Doble bfer para animar

Biblioteca de transformaciones
//archivo: transform.h
struct point{
float x,y;
};
void translate(point &p, float tx, float ty);
void scale(point &p, float sx, float sy);
void rotate(point &p, float a);
void rotateFix(point &p, float a,float xr, float yr);
void scaleFix(point &p, float sx, float sy,float xf, float
yf);
void translatePoly(point *p,int n, float tx, float ty);
void dibujaPunto(point p);
void dibujaPoly(point *p,int n);
void transW2V(point *p,int n,float xmin,float ymin,float
xmax,float ymax,
int umin,int vmin,int umax, int vmax);
void copia(point *p1,point *p2,int n);

//archivo: transform.cpp
#include <graphics.h>
#include <math.h>
#include "transform.h"
float PI = 3.14159265;
void translate(point &p, float tx, float ty){
...
void transW2V(point *p,int n,float xmin,float ymin,float xmax,float
ymax,int umin,int vmin,int umax, int vmax){
int i;
for(i=0; i<n ; i++){
translate(p[i],-xmin,-ymin);
scale(p[i],(umax-umin)/(xmax-xmin),(vmax-vmin)/(ymax-ymin));
translate(p[i],umin,vmin);
}
rectangle(umin,vmin,umax,vmax);
}
void copia(point *p1,point *p2,int n){
int i;
for(i=0; i<n; i++)
p2[i] = p1[i];
}

#include <graphics.h>
#include "transform.h"
main(){
initwindow(400,400);
point p[10],p1[10];
p[0].x = 0;p[0].y = 10;
p[1].x = 10;p[1].y = 10;
p[2].x = 10;p[2].y = 0;
p[3].x = 20;p[3].y = 0;
p[4].x = 20;p[4].y = 10;
p[5].x = 30;p[5].y = 10;
dibujaPoly(p,6);
copia(p,p1,6);
transW2V(p1,6,0,0,30,30,100,100,150,150);
dibujaPoly(p1,6);
copia(p,p1,6);
transW2V(p1,6,0,0,30,20,200,100,350,300);
dibujaPoly(p1,6);
// setviewport(100,100,200,200,true);
// dibujaPoly(p,6);
getch();
}