[C con Clase] [Windows API] Transformación Afín

JHOANA TENESACA j.h.ois en hotmail.es
Vie Abr 13 19:08:51 CEST 2012


ayudemen a realizar este programa en c++ programa que permita el ingreso de varios numeros enteros y deternime el mas cercano y el mas lejano a un valor de referencia previamente ingresado 

Date: Thu, 12 Apr 2012 20:32:31 -0700
From: tute16 en yahoo.com.mx
To: cconclase en listas.conclase.net
Subject: Re: [C con Clase] [Windows API] Transformación Afín

Muchas gracias Steven, pero tal vez no me di a entender, trataré de detallar más mi pregunta:
Creo que lo de checar si hay pixel ahí, si no para pintar negro, el programa ya lo hace porque sí estamos manejando coordenadas y tenemos una imagen que estamos repintando cada vez que se mueve, por tanto con los pixeles no tenemos problemas.
Entonces especificamente queremos saber el orden de la multiplicacion de las matrices de transformación para que la imagen se pueda trasladar arriba-abajo-izquierda-derecha pero tambien pueda rotar con respecto a un punto fuera de la imagen sin que éste se desplace al realizar la traslacion.
Nuestro problema es el siguiente: 
Siendo:T: Traslación de la imagen fuenteS: Escalación de la imagen fuenteR: Rotación de la imagen fuenteTc: Traslación al centro de la imagen fuenteTic: Traslación inversa de la anteriorTcd: Traslación de la imagen fuente al centro de la imagen destinoTicd: Traslación inversa de la anteriorRd: Rotación de la imagen fuente respecto al centro de la imagen destino
Tenemos:
CMatrix3D T,R,Tc,Tic,Tcdest,Ticdest,Rdest,S,Sdest;
		CMatrix3D::Rotation(Rd, g_Thetadest);
		CMatrix3D::Rotation(R, g_Theta);
		CMatrix3D::Traslation(T,(int)g_Tx,(int)g_Ty);
		CMatrix3D::Traslation(Tc,-(int)g_pImagenSource->SizeX()/2,-(int)g_pImagenSource->SizeY()/2);
		CMatrix3D::Traslation(Tic,g_pImagenSource->SizeX()/2,g_pImagenSource->SizeY()/2);
		CMatrix3D::Traslation(Tcd,-(int)g_pImagen->SizeX()/2,-(int)g_pImagen->SizeY()/2);
		CMatrix3D::Traslation(Ticd,g_pImagen->SizeX()/2,g_pImagen->SizeY()/2);
		CMatrix3D::Scalation(S,g_Zoom,g_Zoom);

M=T*Tcd*Rd*Ticd*Tc*S*R*Tic  //se desplaza el punto de rotacion y si tenemos: M=Tcd*Rd*Ticd*T*Tc*S*R*Tic  //se giran los ejes y la traslacion que genera T, al rotar la imagen por ejemplo 45°, se giran los ejes 45° y la traslacion se hace en ese sentido de los ejes
Espero me haya dado a entender mejor :)
De antemano gracias!
Lourdes 
        De: Steven Davidson
 <srd4121 en njit.edu>
 Para: Lista de correo sobre C y C++ <cconclase en listas.conclase.net> 
 Enviado: Jueves, 12 de abril, 2012 21:23:36
 Asunto: Re: [C con Clase] [Windows API] Transformación Afín
   
Hola Lourdes,

On 4/12/2012 7:37 PM, Lourdes Celene Haros Becerra wrote:
> Qué tal, buen día!!
> 
> Revisé las pagina que me sugeriste
> http://graficos.conclase.net/curso/index.php?cap=006c#Transformaciones_Afines
> y sí me sirvió mucho, pero sigo con dudas para implementar que la
> imagen fuente gire con respecto a imagen destino... encontré aqui
> http://es.scribd.com/doc/63650237/54/Coordenadas-homogeneas-y-representacion-matricial
> en la pagina 99 información al respecto, pero nosé cómo
> implementarla, no sé si podrían ayudarme. Porq ahi habla de hacer la
> rotación respecto a un punto de pivote cualquiera, creo que es lo que
> necesito. Mi pregunta es ¿El vector por el que tengo que multiplicar
> cambia? ¿Cómo sería?... porq la ecuación de rotación con pivote en el
> origen es x'=xcos(theta) -ysin(theta) y'=xsin(theta)+ycos(theta)
> 

Bueno, en primer lugar, ten cuidado con los términos que usas. Dudo que estés usando vectores, sino más bien parejas ordenadas para representar puntos o como dices posteriormente píxeles de una imagen.

En una imagen, guardamos las intensidades en cada píxel; y un píxel requiere
 una pareja ordenada para referirnos a un píxel. Analíticamente, podemos representar una imagen como una función de intensidades: f(x,y). Esto significa que por cada pareja de coordenadas (x,y) podemos conocer la intensidad, f, en tal píxel.

Las fórmulas explicadas tanto en el capítulo 6 de nuestro curso de programación como en el libro del enlace sirven para puntos, que seguramente describen vértices de un polígono, de un modelo analítico de una figura en dos dimensiones. Por ejemplo, los vértices de un rectángulo, de un triángulo, o de cualquier otro tipo de polígono en general, al igual que un segmento, o incluso coordenadas para describir curvas.

En tu caso, necesitas una variación de estas fórmulas para que funcionen con píxeles de una imagen. Como todas las coordenadas en una imagen (de píxeles) son válidas, tenemos que aplicar cualquier transformación a TODOS los píxeles y por tanto tenemos que recorrer TODAS las
 coordenadas. El algoritmo entonces podría ser el siguiente:

Imagen Rotar_Imagen( Imagen f, Dimensión M, Dimensión N, Ángulo a )

1.  Crear Imagen: g de M x N
2.  Inicializar 0 intensidad a todos los píxeles de "g"  // 0 => Negro
3.  Para: x = 0 hasta M-1
4.     Para: y = 0 hasta N-1
5.        u <- x * cos(a) - y * sen(a)
6.        v <- x * cos(a) + y * sen(a)
7.        g(u,v) <- f(x,y)
8.  Terminar( g )

(Nota: uso <- para indicar "copiar" o "asignar"). Podemos asignar otro valor incialmente a todos los píxeles de la imagen resultante, pero creo que 0 tiene más sentido. También date cuenta que estamos creando una nueva imagen en este algoritmo y además la rotación es alrededor del origen (0,0). Si quieres otro "centro" para la rotación, entonces aplica una traslación en la rotación.

El
 problema de implementar este algoritmo es que los cálculos de las coordenadas de (u,v) pueden resultar en las mismas más de una vez y por tanto estaríamos copiando diferentes intensidades al mismo píxel. También puede darse el caso de que no todos los píxeles de la imagen resultante son asignados, excepto por el valor inicial.

Una solución alternativa es aplicar la transformación inversa. Esto significa que analizamos cada píxel de la imagen resultante usando sus coordenadas en la transformación inversa para generar las coordenadas de la imagen original y así consultar sus intensidades. Como se trata de una rotación, su inversa es una rotación del ángulo negativo. El algoritmo ahora sería,

Imagen Rotar_Imagen( Imagen f, Dimensión M, Dimensión N, Ángulo a )

1.  Crear Imagen: g de M x N
2.  Para: u = 0 hasta M-1
3.     Para: v = 0 hasta N-1
4.        x <- u * cos(a)
 + u * sen(a)
5.        y <- v * cos(a) - v * sen(a)
6.        g(u,v) <- f(x,y)
7.  Terminar( g )

El paso #6 no es tan directo, porque tenemos que comprobar que las coordenadas calculadas para (x,y) realmente existen; si no, entonces hay que asignar algún valor como por ejemplo 0 (negro).

Como posiblemente obtendremos una imagen rotada con algunos píxeles negros (intesidad cero), podemos aplicar una mejor solución para aproximar la intensidad de esos píxeles sin intensidad, como es una interpolación lineal de los píxeles cercanos o vecinos, interpolación bilineal, o interpolación bicúbica.


Espero que todo esto te sirva.

Steven


_______________________________________________
Lista de correo Cconclase Cconclase en listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ


    
_______________________________________________
Lista de correo Cconclase Cconclase en listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ 		 	   		  
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20120413/33caff36/attachment.html>


Más información sobre la lista de distribución Cconclase