Vous êtes sur la page 1sur 148

MANUAL PARA EL CURSO DE GRAFICACIN

Mtra. Ana Cecilia Ruiz Calvillo

Cd. Obregn Sonora, Enero 2008


1

DIRECTORIO
Mtro. Sergio Pablo Mariscal Alvarado
Director General ITESCA
Lic. Clara E. Mark Corona
Subdirectora
Mtro. Alejandro Faccinetto Ruiz
Jefe de la Divisin Acadmica
Mtra. Lilia B. Navarro Fragoso
Jefa del Departamento de Desarrollo Acadmico
Mtro. Leobardo Rodrguez
Jefe de Carrera Ingeniera en Sistemas Computacionales
Mtra. Ana Cecilia Ruiz Calvillo
Elaborador del Manual

ESTE MANUAL FUE REALIZADO PARA USO EXCLUSIVO DEL INSTITUTO TECNOLGICO
SUPERIOR DE CAJEME
D.R. ITESCA, Cd.Obregn, Sonora; Mxico. Carretera Internacional a Nogales Km. 2.
Tel. (644) 410-86-50

INDICE

INTRODUCCIN

1. INTRODUCCIN A LA GRAFICACIN POR COMPUTADORA


1.1 Introduccin.
1.2 Evolucin de la programacin de grficos por computadora.

6
10

1.2.1 Nivel Hardware.

10

1.2.2 Nivel Sistema Operativo.

13

1.2.3 GKS y PHIGS.

16

1.2.4 OpenGL.

19

1.2.5 Java.

21

1.2.5.1 Java 2D.

24

1.2.5.2 Java 3D.

26

1.3 Campos relacionados con la graficacin.

28

2. TRANSFORMACIONES GEOMTRICAS
2.1 Transformaciones bidimensionales.

30

2.2 Coordenadas homogneas y representacin matricial.

32

2.3 Tipos de transformaciones bidimensionales.

36

2.4 Composicin de transformaciones bidimensionales.

45

2.5 Transformaciones de la composicin general.

49

2.6 Transformacin ventana-rea de vista.

53

2.7 Representacin matricial de transformaciones tridimensionales.

54

2.7.1 Transformaciones tridimensionales.

56

2.7.2 Matriz de transformacin.

56

2.7.3 Tipos de transformaciones tridimensionales.

61

2.8 Composicin de transformaciones tridimensionales

71

3. MODELADO GEOMTRICO
3.1 Modelos geomtricos.

76

3.2 Proyecciones.

90

3.2.1 El modelo de vistas.

94

3.2.2 Modo de Compatibilidad.

96

3.2.3 Configuracin de vista.

99

3.2.4 Creacin de una vista propia.


3.3 Representacin tridimensional de objetos.

102
105

3.3.1 Superficies de polgonos, curvas y cuadrticas.

105

3.3.2 Representaciones de spline y Curvas Bzier.

112

3.3.3 Superficies Bzier.

122

ANEXOS
Anexo 1. Preguntas y Ejercicios de Unidad 1.

126

Anexo 2. Preguntas y Ejercicios de Unidad 2.

128

Anexo 3. Preguntas y Ejercicios de Unidad 3.

132

Anexo 4. ndice de figuras.

137

Anexo 5. ndice de programas.

139

Anexo 6. ndice de tablas.

141

GLOSARIO

142

BIBLIOGRAFA

147

INTRODUCCIN
El rpido desarrollo del hardware de computadora, las aplicaciones grficas y
tecnologas de red han hecho que la graficacin por computadora sea un tema
crucial en estos das. El modelado y renderizado de objetos grficos virtuales, son
los principales objetivos de la graficacin. Los tpicos involucrados con este
proceso abarcan una gran rama de disciplinas desde las matemticas y
tecnologas de informacin hasta psicologa, medicina, ingeniera y arte.
La materia de graficacin tiene por objetivo lograr que el estudiante aplique
tcnicas y algoritmos bsicos de representacin y visualizacin de objetos en dos
y tres dimensiones para desarrollar modelos de simulacin e interfaces hombre
mquina. El presente manual pretende ayudar a lograr dicho objetivo; ya que
contiene ejemplos de programas que ilustran cada concepto introducido. Cuenta
con un anexo de preguntas y programas a resolver por unidad, para reforzar el
aprendizaje adquirido; as como un glosario de terminolga relacionada con la
graficacin. Est dividido en tres secciones:
Introduccin a la graficacin por computadora: se presenta conceptos
fundamentales de la graficacin, su objetivo y aplicaciones, as como la
evolucin de los lenguajes de programacin utilizados para su desarrollo.
Transformaciones geomtricas: se dan a conocer los principales
conceptos y aplicaciones de transformaciones geomtricas en dos y tres
dimensiones, as como la representacin matricial de objetos grficos.
Modelado geomtrico: se dan a conocer las tcnicas para la
representacin tridimensional de objetos y sus diferentes proyecciones en
el rea de vista.
Se ha utilizado el lenguaje de programacin Java ya que es un lenguaje de
programacin multiplataforma, es simple y orientado a objetos. Se emplean sus
aplicaciones en Java 2D y Java 3D debido a que son paquetes que proporcionan
grandes capacidades y poderosas interfaces para el modelado y programacin de
grficos.

INTRODUCCIN A LA
GRAFICACIN POR
COMPUTADORA

1.1 Introduccin.
La graficacin por computadora estudia la teora y las tcnicas de modelado,
procesamiento y renderizado de objetos grficos en computadoras. El objetivo
bsico de la graficacin por computadora es construir un mundo virtual a partir de
objetos grficos y renderizar una escena del modelo virtual a un dispositivo grfico
a partir de vistas especficas.

Figura 1.1 Tareas principales de la graficacin por computadora: modelando un mundo virtual y
renderizandolo a una escena

Un sistema grfico tpicamente consiste en dos componentes: un modelador y un


renderizador. El modelador es el responsable de la construccin de los modelos
del mundo virtual y el renderizador realiza el renderizado de la escena. Un
sistema de modo retenido mantiene un persistente modelo de los objetos grficos
y la funcin del modelador es explcita. Un sistema de modo inmediato renderiza
los objetos inmediatamente y el modelo es mas transitorio. Esta perspectiva del
paradigma de modelado-renderizado es conveniente para el estudio de sistemas
grficos, an cuando la separacin no es clara en algunos sistemas.
Tpicamente los objetos grficos a modelar estn en un espacio ya sea 2D o 3D.
Este espacio comn alberga todos los objetos grficos y es comnmente llamado
espacio del mundo, espacio mundo o mundo espacial. En una escena
renderizada del espacio mundo, la salida principal del sistema grfico, tiene
tpicamente en un formato en 2D. Consecuentemente las tcnicas involucradas en
grficos 2D y 3D son comnmente tratados en temas separados.
Los objetos grficos a ser modelados en el espacio mundo son usualmente
entidades geomtricas tales como lneas y superficies; pero tambin se incluyen
otros objetos especiales tales como iluminacin, textos e imgenes. Los objetos
grficos pueden poseer muchas caractersticas y propiedades tales como color,
trasparencia y texturas.
Para modelar objetos geomtricos se utilizan diversas representaciones
matemticas. Segmentos de lnea recta y mallas de polgonos simples

proporcionan representaciones simples y compactas. Solo los vrtices de las


estructuras

necesitan

almacenarse

son

fciles

de

implementar.

Las

representaciones ms sofisticadas incluyen curvas spline y Bzier y superficies


Bzier; stas son verstiles y requieren solo del almacenamiento de ciertos
puntos de control relativos.
Las transformaciones geomtricas son aplicadas a los objetos para alcanzar el
posicionamiento propio de los mismos en un espacio virtual. Las transformaciones
de este tipo son llamadas transformaciones de objetos. Las transformaciones
tambin se utilizan para las vistas; estas son conocidas como transformaciones
de visualizacin. Una familia de transformaciones geomtricas muy til es la
AffineTransforms, la cual incluye la mayora de las transformaciones comunes
tales como traslaciones, rotaciones, escalaciones y reflecciones. Un conjunto ms
general de transformaciones son las transformaciones proyectivas, que son muy
utilizadas para las vistas en 3D.
Una vista es empleada para ver el modelo en el mundo virtual desde una
perspectiva especfica. Un proceso de una vista en 2D es relativamente simple; la
transformacin de vistas es usualmente indistinguible de la transformacin del
objeto y las caractersticas de renderizado tales como reglas de composicin y
fragmentos de trayectoria pueden ser aplicadas. Una vista en 3D es mucho ms
complicada; tal como los ojos o las cmaras, las vistas en 3D involucran el
proceso de proyeccin que mapea los objetos 3D a un plano 2D. Muchos
parmetros tales como la proyeccin, la posicin de vista, orientacin y un campo
de vista pueden afectar el renderizado en 3D.
Para poder alcanzar el renderizado realstico del mundo virtual, existen muchos
temas de rendereizado que tienen que direccionarse; es decir las ubicaciones
relativas de los objetos tienen que reflejarse correctamente en las imgenes
renderizadas. Por ejemplo, un objeto puede estar detrs de otro, y la porcin
oculta no debe mostrarse en la imagen; las fuentes de iluminacin deben ser
consideradas ya que las propiedades de los materiales de los objetos afectarn
su apariencia.

Las posibilidades y caractersticas de los dispositivos de hardware tienen un gran


impacto en los sistemas grficos. Los dispositivos de salida ms comunes para
mostrar los resultados del renderizado de grficos son los monitores de video y
las impresoras. Otros dispositivos incluyen los plotters y los proyectores
hologrficos. En cuanto a los dispositivos de entrada se encuentran el ratn,
josticks y las tabletas digitalizadoras.
La animacin es tambin una parte importante de la graficacin por computadora.
En lugar de tener imgenes estticas, la animacin produce contenidos grficos
dinmicos y su renderizado. En las aplicaciones tales como renderizado de
escenas de pelculas y juegos, la animacin juega un papel muy importante. Otro
aspecto dinmico de la graficacin por computadora es la interaccin. En
respuesta a las entradas de usuario, el modelo de grficos puede cambiar acorde
a lo que se le indica. El fundamento principal de GUI (Interfaz Grfica de Usuario)
se basa en las interacciones del usuario con los sistemas grficos.
La graficacin por computadora tiene una amplia gama de aplicaciones. La
popularidad de los ambientes GUI ha hecho de los grficos una parte integral de
los programas de usuario. CAD (Diseo de Ayuda por Computadora) y otras
aplicaciones de ingeniera dependen en gran parte de los sistemas grficos. La
visualizacin de datos y otras aplicaciones cientficas tambin hacen gran uso de
los grficos. Con el rpido desarrollo de la instrumentacin basada en
computadoras tal como el CT (Tomografa por Computadora), PET (Tomografa
de Emisin Positrnica) y MRI (Imagen de Resonancia Magntica), los sistemas
mdicos han abierto sus puertas a tecnlogos en graficacin por computadora.
Adems la graficacin por computadora es un ingrediente crucial para vdeo
juegos y otras aplicaciones en el mundo del entretenimiento.
Tradicionalmente la graficacin por computadora ha lidiado con detalles de
implementacin, utilizando algoritmos de bajo nivel para convertir figuras
primitivas tales como lneas a pixeles, para determinar superficies escondidas de
una vista, para calcular los valores de color de los puntos en una superficie, etc.

Estos algoritmos y mtodos han hecho que la graficacin por computadora sea un
tema considerado como tcnicamente difcil y complejo.

1.2 Evolucin de la programacin en grficos por computadora.


La programacin en grficos por computadora ha aparecido en casi todos los
niveles de la arquitectura de computadora. Hablando en trminos generales se ha
ido moviendo de un nivel bajo (al utilizar mtodos dependientes de la plataforma
utilizada) hasta ambientes abstractos, de alto nivel y portables.
La siguiente tabla nos muestra ejemplos de los ambientes de programacin
grfica en varios niveles de la arquitectura de computadora.
Plataforma independiente (Java 2D y Java 3D)
Estndares Grficos (GKS, PHIGS, OpenGL)
OS (WIN32, X, Mac OS)
Hardware (registro directo / programacin de buffer de video)
Tabla 1.1 Programacin grfica en diferentes niveles

1.2.1 Nivel Hardware.


Los programas de grficos por computadoras dependen de dispositivos de salida
con capacidades grficas. Los dispositivos ms comunes en este caso son los
monitores CRT y paneles LCD. Estos son dispositivos de rasteo 2D que
proporcionan una superficie de pantalla consistente de un arreglo rectangular de
puntos discretos. Un dispositivo de pantalla de este tipo es comnmente
manejado por una tabla de grficos dedicados con su propio procesador y su
propia memoria.
Las aplicaciones grficas de bajo nivel comnmente programan los grficos
directamente al hardware. En computadoras personales con MSDOS, por
ejemplo, la mayora de las aplicaciones grficas accesan directamente a la

10

memoria de la pantalla. A pesar de que el BIOS y el DOS proporcionan cierto


soporte primitivo para funciones grficas, son considerados muy lentos para
programas grficos intensos. Tales programas estn tpicamente escritos en
lenguaje ensamblador y manipulan los registros del hardware y los bferes de
video de una manera muy dependiente del hardware.
El siguiente cdigo muestra un programa en ensamblador que demuestra la
programacin grfica a bajo nivel. Utiliza Microsoft Macro Assembler y puede ser
ejecutado en cualquier mquina compatible con IBM PC y con una tarjeta de
grficos VGA. El programa dibuja un crculo escribiendo directamente en las
localidades de memoria del bfer de video.
.model small,stdcall
.stack 100h
.386
.data
saveMode BYTE ? ; saved video mode
xc WORD ?
; center x
yc WORD ?
; center y
x SWORD ?
; x coordinate
y SWORD ?
; y coordinate
dE SWORD ?
; east delta
dSE SWORD ?
; southeast delta
w WORD 320
; screen width
.code
main PROC
mov ax,@data
mov ds,ax
;Set Video Mode 320X200
mov ah,0Fh
; get current video mode
int 10h
mov saveMode,al ; save mode
mov ah,0 ; set new video mode
mov al,13h
; mode 13h
int 10h
push 0A000h
; video segment address
pop es
; ES = A000h (video segment).
;Set Background
mov dx,3c8h
; video palette port (3C8h)
mov al,0 ; set palette index
out dx,al
;Set screen background color to dark blue.
mov dx,3c9h
; port address 3C9h
mov al,0 ; red
out dx,al
mov al,0 ; green
out dx,al
mov al,32 ; blue (32/63)
out dx,al
; Draw Circle
; Change color at index 1 to yellow (63,63,0)
mov dx,3c8h
; video palette port (3C8h)
mov al,1 ; set palette index 1

11

out dx,al
mov dx,3c9h
mov al,63 ; red
out dx,al
mov al,63 ; green
out dx,al
mov al,0 ; blue
out dx,al

; port address 3C9h

mov xc,160
mov yc,100

; center of screen

; Calculate coordinates
mov x, 0
mov y, 50 ; radius 50
mov bx, -49
; 1-radius
mov dE, 3
mov dSE, -95
DRAW:
call Draw_Pixels

; Draw 8 pixels

cmp bx, 0 ; decide E or SE


jns MVSE
add bx, dE
add dE, 2
add dSE, 2
inc x
jmp NXT

; move east

add bx, dSE


add dE, 2
add dSE, 4
inc x
dec y

; move southeast

MVSE:

NXT:
mov cx, x ; continue if x < y
cmp cx, y
jb DRAW
; Restore Video Mode
mov ah,10h
; wait for keystroke
int 16h
mov ah,0
; reset video mode
mov al,saveMode ; to saved mode
int 10h
.EXIT
main ENDP
; Draw 8 pixels symmetrical about the center
Draw_Pixels PROC
; Calculate the video buffer offset of the pixel.
mov ax, yc
add ax, y
mul w
add ax, xc
add ax, x
mov di, ax
mov BYTE PTR es:[di],1
; store color index
; Horizontal symmetrical pixel
sub di, x
sub di, x
mov BYTE PTR es:[di],1
; store color index
; Vertical symmetrical pixel
mov ax, yc
sub ax, y
mul w
add ax, xc
add ax, x
mov di, ax
mov BYTE PTR es:[di],1
; store color index

12

; Horizontal pixel
sub di, x
sub di, x
mov BYTE PTR es:[di],1
; store color index
; Switch x, y to get other 4 pixels
mov ax, yc
add ax, x
mul w
add ax, xc
add ax, y
mov di, ax
mov BYTE PTR es:[di],1
; store color index
sub di, y
sub di, y
mov BYTE PTR es:[di],1
; store color index
mov ax, yc
sub ax, x
mul w
add ax, xc
add ax, y
mov di, ax
mov BYTE PTR es:[di],1
; store color index
sub di, y
sub di, y
mov BYTE PTR es:[di],1
; store color index
ret
Draw_Pixels ENDP
END main

Programa 1.1 Cdigo en ensamblador que muestra un crculo.

Figura 1.2 Crculo creado al ejecutar el cdigo en ensamblador.

1.2.2 Nivel a Sistema Operativo.


Las infraestructuras de grficos a bajo nivel proporcionan facilidades bsicas para
programar las pantallas. Sin embargo, la programacin directa a los buffers de
video y a los registros del hardware no es una forma efectiva para aplicaciones
generales de grficos. El programar a nivel de hardware requiere del
conocimiento a fondo de los dispositivos adems que es tedioso el hacer tareas

13

simples. Los programas escritos a este nivel no son portales aun para diferentes
dispositivos en la misma plataforma.
La programacin de interfaces a alto nivel es necesaria para facilitar la carga de la
programacin grfica. Debido a las inherentes complejidades de los problemas
grficos, es deseable proporcionar una capa de abstraccin para la programacin
de aplicaciones. Un lugar natural para agregar dicha abstraccin es el sistema
operativo.
Con el desarrollo y la expansin de aplicaciones de interfaces grficas de usuario
(GUI) en los sistemas modernos de computadora, los grficos soportados en los
sistemas operativos se han convertido cada vez en ms comunes y extensivos.
Las APIs proporcionadas al nivel de sistema operativo proporcionan una interfaz
uniforme para la programacin grfica en la misma plataforma. Normalmente las
diferencias de hardware son complacidas al utilizar drivers especficos para los
dispositivos. Un driver implementa una interface estndar con el sistema operativo
para un dispositivo particular. Los programas de aplicaciones solo necesitan
llamar a funciones grficas estndares proporcionadas por el sistema operativo y
se evitan la tarea de lidiar con las especificaciones del hardware.
Win32 es la API para el sistema operativo de 32 bits de Windows tal como
Windows 9x/ME/NT/2000/XP. El siguiente cdigo muestra un programa de WIN32
que dibuja un crculo. Este es un ejemplo simple de un programa en Windows
escrito en lenguaje C. El programa crea una ventana estndar y llama
directamente al API de WIN32 para dibujar el crculo en el rea del cliente de la
ventana principal del programa. El crculo est centrado en la ventana y el tamao
es ajustado automticamente si la ventana se ajusta.
#include <windows.h>
#include <string.h>
LRESULT CALLBACK
MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
/* Device context used for drawing */
PAINTSTRUCT ps;
/* Paint structure used during drawing */
RECT rc;
/* Client area rectangle */
int
cx;
/* Center x-coordinate */
int cy;
/* Center y-coordinate */
int r;
/* Radius of circle */

14

/* Message processing.*/
switch (nMsg) {
case WM_DESTROY:
/* The window is being destroyed, close the application */
PostQuitMessage (0);
return 0;
break;
case WM_PAINT:
/* The window needs to be redrawn. */
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rc);
/* Calculater center and radius */
cx = (rc.left + rc.right)/2;
cy = (rc.top + rc.bottom)/2;
if (rc.bottom - rc.top < rc.right - rc.left)
r = (rc.bottom - rc.top) / 2 - 20;
else
r = (rc.right - rc.left) / 2 - 20;
Ellipse(hdc, cx-r, cy-r, cx+r, cy+r);
EndPaint (hwnd, &ps);
return 0;
break;
}
return DefWindowProc (hwnd, nMsg, wParam, lParam);
}
int WINAPI
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
HWND hwndMain; /* Main window handle */
MSG msg;
/* Win32 message structure */
WNDCLASSEX wndclass;
/* Window class structure */
char* szMainWndClass = "WinCircle"; /* The window class name */
/* Create a window class */
/* Initialize the entire structure to zero */
memset (&wndclass, 0, sizeof(WNDCLASSEX));
/* The class Name */
wndclass.lpszClassName = szMainWndClass;
/* The size of the structure. */
wndclass.cbSize = sizeof(WNDCLASSEX);
/* All windows of this class redraw when resized. */
wndclass.style = CS_HREDRAW | CS_VREDRAW;
/* All windows of this class use the MainWndProc window function. */
wndclass.lpfnWndProc = MainWndProc;
/* This class is used with the current program instance. */
wndclass.hInstance = hInst;
/* Use standard application icon and arrow cursor */
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
/* Color the background white */
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
/* Register the window class */
RegisterClassEx (&wndclass);
/* Create a window using the window class */
hwndMain = CreateWindow (
szMainWndClass,
/* Class name */

15

"Circle",
/* Caption */
WS_OVERLAPPEDWINDOW,
/* Style */
CW_USEDEFAULT,
/* Initial x (use default) */
CW_USEDEFAULT,
/* Initial y (use default) */
CW_USEDEFAULT,
/* Initial x size (use default) */
CW_USEDEFAULT,
/* Initial y size (use default) */
NULL,
/* No parent window */
NULL,
/* No menu */
hInst,
/* This program instance */
NULL
/* Creation parameters */
);
/* Display the window */
ShowWindow (hwndMain, nShow);
UpdateWindow (hwndMain);
/* The message loop */
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}

Programa 1.2 Cdigo en C que muestra un crculo.

Figura 1.3 Crculo creado al ejecutar el cdigo en C.

1.2.3 GKS y PHIGS.


La programacin grfica basada en APIS de sistemas operativos es un paso
mayor desde el nivel de hardware en trminos de independencia y conveniencia
de dispositivos. Sin embargo, los programas grficos que dependen de funciones
de sistema operativo no son portables en diferentes plataformas. Por ejemplo
Microsoft Windows y Mac Os, ambos son sistemas operativos con interfaces de
usuario grficas (GUI). Sin embargo sus APIs son diferentes e incompatibles al
nivel de llamadas de sistema.

16

Es fcil ver las ventajas de una interface estndar para programacin grfica. Ya
que sta proporcionar una capa de abstraccin necesaria para dispositivos e
independencia de plataforma.
GKS (Graphics Kernel System) es el primer estndar internacional para
Graficacin por computadora. GKS (ISO 7942 1985) es un estndar para grficos
en 2D. Especifica funciones grficas bsicas independientes de las plataformas
de computadora. Algunos niveles estn definidos para acomodar diferentes
capacidades de sistemas de hardware. Una implementacin de GKS en un
lenguaje de programacin necesitar de una definicin apropiada de sintaxis para
el lenguaje. Un lenguaje cubierta es utilizado para definir el formato especfico del
GKS en el lenguaje de programacin. El lenguaje cubierta ms comn para GKS
es el FORTRAN. Aunque tambin se pueden utilizar otros lenguajes como Pascal
y C.
GKS-3D (ISO 8805 1988) es una extensin del GKS que soporta grficos en 3D.
GKS y GKS-3D estn diseados principalmente para dibujar objetos individuales
con ciertos atributos. Son tiles para primitivas grficas no estructuradas y
estticas, pero no soportan directamente modelos grficos ms complejos.
PHIGS (Programmers Hierarchical Interactive Graphics System, ISO 9592 1991)
es un estndar grfico similar al GKS. PHIGS y PHIGS+ incluyen las capacidades
de GKS. Tienen funcionalidades adicionales para organizaciones jerrquicas de
las primitivas grficas y de edicin dinmica.
El siguiente cdigo muestra la programacin en GKS en el lenguaje cubierta
FORTRAN. El programa dibuja un crculo rojo usando la primitiva polilnea de
GKS. Los puntos del crculo son calculados con funciones trigonomtricas de alto
nivel proporcionadas por FORTRAN.
PROGRAM CIRCLE
C
C Define error file, Fortran unit number, and workstation type,
C and workstation ID.
C
PARAMETER (IERRF=6, LUNIT=2, IWTYPE=1, IWKID=1)

17

PARAMETER (ID=121)
DIMENSION XP(ID),YP(ID)
C
C Open GKS, open and activate a workstation.
C
CALL GOPKS (IERRF,IDUM)
CALL GOPWK (IWKID,LUNIT,IWTYPE)
CALL GACWK (IWKID)
C
C Define colors.
C
CALL GSCR(IWKID,0, 1.0, 1.0, 1.0)
CALL GSCR(IWKID,1, 1.0, 0.0, 0.0)
C
C Draw a circle.
C
X0 = .5
Y0 = .5
R = .3
JL = 120
RADINC = 2.*3.1415926/REAL(JL)
DO 10 J=1,JL+1
X = X0+R*COS(REAL(J)*RADINC)
Y = Y0+R*SIN(REAL(J)*RADINC)
XP(J) = X
YP(J) = Y
10 CONTINUE
CALL GSPLI(1)
CALL GSPLCI(1)
CALL GPL(JL+1,XP,YP)
C
C Deactivate and close the workstation, close GKS.
C
CALL GDAWK (IWKID)
CALL GCLWK (IWKID)
CALL GCLKS
C
STOP
END

Programa 1.3: Cdigo en FORTRAN que muestra un crculo.

Figura 1.4. Crculo creado al ejecutar el cdigo en FORTRAN.

18

1.2.4 OpenGL.
OpenGL es una API muy popular para grficos en 2D/3D derivada de GL
(Graphics Library) de Silicon Graphics Inc. GL es la interface de programacin
grfica usada en las estaciones de trabajo de SGI. OpenGL est diseado para
ser abierto y es un estndar neutral. Est disponible virtualmente en todas las
plataformas; de hecho muchos vendedores de hardware ofrecen interfaces
OpenGL para sus tarjetas grficas y dispositivos. Con ms de 200 funciones,
proporciona una API grfica ms poderosa que los estndares de GKS.
OpenGL es una API relativamente de bajo nivel con una interface orientada al
procedimiento y es posible utilizar diferentes lenguajes de programacin. Existe
un lenguaje FORTRAN oficial y actualmente se est desarrollando un lenguaje
cubierta en Java. Sin embargo, la raz de OpenGL es el lenguaje C.
OpenGL consiste en dos libreras: GL y GLU (OpenGL Utility Library). La librera
GL contiene las funciones bsicas de grficos, y la librera GLU contiene
funciones de ms alto nivel creadas a partir de las GL. OpenGL por s solo no
tiene funciones para construir una interfaz de usuario. Es necesario un paquete
portable llamado GLUT (OpenGL Utility Toolkit) que puede ser utilizado con
OpenGL para construir programas grficos completos.
El siguiente cdigo muestra un ejemplo que dibuja un crculo en OpenGL. El
programa utiliza GLUT para construir la interface de usuario y tambin funciones
GL y GLU para construir el display.
#include <GL/glut.h>
#include <math.h>
void display(void) {
int i;
int n = 80;
float a = 2*3.1415926535/n;
float x;
float y;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0,0);
glBegin(GL_LINE_LOOP);
for (i = 0; i < n; i++) {

19

x = cos(i*a);
y = sin(i*a);
glVertex2f(x, y);
}
glEnd();
glFlush();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutCreateWindow("Circle");
glutDisplayFunc(display);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.2, 1.2, -1.2, 1.2);
glClearColor(1.0, 1.0, 1.0, 0.0);
glutMainLoop();
}

Programa 1.4: Cdigo utilizando OpenGL que muestra un crculo.

Figura 1.5. Crculo creado al ejecutar el cdigo de OpenGL.

OpenGL como una API de 3D es mucho ms capaz que el dibujar un simple


circulo. A continuacin se muestra un ejemplo que presenta una esfera en 3D.
#include <GL/glut.h>
GLUquadricObj* sphere;
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glRotatef(0.2, 0.0, 0.0, 1.0);
gluSphere(sphere, 1.8, 24, 24);
glutSwapBuffers();
}
void idle(void) {
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Spinning Sphere");
glutDisplayFunc(display);
glMatrixMode(GL_PROJECTION);

20

glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(1.0, 0.5, 0.5);
sphere = gluNewQuadric();
gluQuadricDrawStyle(sphere, GLU_LINE);
glutIdleFunc(idle);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutMainLoop();
}

Programa 1.5: Cdigo utilizando OpenGL que muestra una esfera 3D.

Figura 1.6. Esfera creada al ejecutar el cdigo de OpenGL.

1.2.5 Java.
A pesar de que OpenGL ofrece un nivel de abstraccin procedimental en C, no
est diseado para acomodar directamente el modelado grfico en el paradigma
orientado a objetos. Una API de nivel alto de grficos basados en POO puede
ofrecer grandes beneficios a aplicaciones.
Java 2D y Java 3D son APIs grficas asociadas con el lenguaje de programacin
Java. Son APIs orientadas a objetos de alto nivel con gran capacidad de
portabilidad. Java 3D est tpicamente implementada en la cima de otras APIs de
bajo nivel tal como OpenGL. La siguiente tabla muestra una representacin tpica
de las capas de un sistema grfico

21

Aplicacin grfica
Java APIs

Java 3D

Java VM

OpenGL

OS
Driver de Display
Tarjeta Grfica
Display
Tabla 1.2 Capas de los sistemas grficos.

Java es un lenguaje de programacin de mltiples propsitos, capaz de


desarrollar aplicaciones robustas. En los aos recientes ha obtenido gran
popularidad y se ha convertido en el lenguaje de programacin por defecto de una
amplia gama de aplicaciones. En la actualidad no solo se usa para programacin
web, sino tambin para desarrollar aplicaciones multiplataforma en servidores,
computadoras de escritorio y aparatos mviles.
Un programa en Java es compilado en un formato estndar y es independiente de
cualquier plataforma, es conocido como cdigo byte El cdigo byte compilado
puede ser ejecutado sin tener que realizar algn cambio mientas que la
computadora cuente con el Java Virtual Machine. Esta independencia hace que
Java sea el lenguaje ideal para aplicaciones en internet.
Java est diseado para soportar la programacin orientada a objetos, consiste
en clases y la interaccin e instanciacin de objetos constituye una de las
acciones principales de un programa en Java. Adems de esto, mantiene la
simplicidad, elegancia y eficiencia de su predecesor, el lenguaje C. Al mismo
tiempo, que evita las deficiencias y los riesgos de C y C++.
Mientras que el lenguaje en s es muy simple, la plataforma de Java proporciona
un conjunto de APIs que cubren un amplio rango de tareas y aplicaciones: de
archivos I/O, grficos, multimedia, bases de datos, red, seguridad, etc. Adems de
que facilita la programacin GUI a travs de AWT y Swing.

22

Una opcin para la programacin de grficos para Java es OpenGL. Hay varios
proyectos en marcha para desarrollar un lenguaje cubierta de Java para OpenGL.
JOGL es la implementacin de JSR 231: el lenguaje cubierta Java para OpenGL.
JOGL proporciona las clases GL y GLU para encapsular las funciones en GL y
GLU. Los dos componentes GLCanvas y GLJPanel proporcionan las superfices
de dibujo para las llamadas a OpenGL. El GLCanvas es un componente pesado
que utilizar la aceleracin del hardware. El GLJPanel es un componente ligero
implementado en memoria. La aceleracin del hardware no est disponible para
GLJPanel. A continuacin se muestra un ejemplo de JOGL que es el equivalente
del ejemplo visto con OpenGL.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.java.games.jogl.*;
public class JOGLDemo {
public static void main(String[] args) {
Frame frame = new Frame("JOGL Demo");
GLCapabilities cap = new GLCapabilities();
GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(cap);
canvas.setSize(300, 300);
canvas.addGLEventListener(new Renderer());
frame.add(canvas);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.show();
}
static class Renderer implements GLEventListener {
private GL gl;
private GLU glu;
private GLDrawable gldrawable;
public void init(GLDrawable drawable) {
gl = drawable.getGL();
glu = drawable.getGLU();
this.gldrawable = drawable;
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(-1.2, 1.2, -1.2, 1.2);
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
}
public void display(GLDrawable drawable) {
int i;
int n = 80;
float a = (float)(2*3.1415926535/n);
float x;
float y;
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glColor3f(1.0f,0,0);
gl.glBegin(GL.GL_LINE_LOOP);
for (i = 0; i < n; i++) {
x = (float)Math.cos(i*a);
y = (float)Math.sin(i*a);

23

gl.glVertex2f(x, y);
}
gl.glEnd();
gl.glFlush();
}
public void reshape(GLDrawable drawable, int x, int y, int width,
int height) {}
public void displayChanged(GLDrawable drawable, boolean modeChanged,
boolean deviceChanged) {}
}
}

Programa 1.6: Cdigo utilizando JOGL que muestra una esfera 3D.

1.2.5.1 Java 2D.


La plataforma de Java 2 proporciona mejoras en capacidades grficas con la
introduccin de las APIs de Swing y Java 2D y 3D. Estas APIs proporcionan
soporte a muchas de las tareas de la graficacin por computadora. Juntas han
hecho muy atractiva la opcin de utilizar Java para la programacin grfica.
Java 2D proporciona un conjunto completo de funcionalidades para manipular y
renderizar grficos en 2D. Entre lo que se incluye:
Una jerarqua de clases para objetos geomtricos.
El proceso de renderizacin es mucho ms refinado.
Presenta mucha capacidad para el procesamiento de imgenes.
Se proporcionan modelos, tipografas y otros soportes relacionados con
grficos.
La clase Graphics2D, una subclase de Graphics, es el motor de renderizdo para
Java 2D. Proporciona los mtodos para renderizar figuras geomtricas, imgenes
y texto. El proceso de renderizado puede ser controlado al seleccionar
transformaciones, pinturas, propiedades de lneas, composicin, fragmentos de
trayectoria y otras propiedades.
El siguiente cdigo muestra un ejemplo de Java 2D que utiliza ciertas
capacidades como transparencia, pintura gradual, transformacin y tipografa.

24

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.font.*;
import java.awt.geom.*;
public class Demo2D extends JApplet{
public static void main(String args[]){
JFrame frame = new JFrame();
frame.setTitle ("Demo Java 2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new Demo2D();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
public void init(){
JPanel panel = new Panel2D();
getContentPane().add(panel);
}
}
class Panel2D extends JPanel{
public Panel2D(){
setPreferredSize(new Dimension(500, 400));
setBackground(Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//dibujar elipse
Shape ellipse = new Ellipse2D.Double(150, 100, 200, 200);
GradientPaint paint = new GradientPaint(100, 100, Color.white, 400, 400, Color.gray);
g2.setPaint(paint);
g2.fill(ellipse);
//establecer transparencia
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f);
g2.setComposite(ac);
g2.setColor(Color.blue);
//dibujar el texto transparente
Font font = new Font("Serif", Font.BOLD, 120);
g2.setFont(font);
g2.drawString("Java", 120, 200);
//obtener el outline del texto en glyph
FontRenderContext frc = g2.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, "2D");
Shape glyph = gv.getOutline(150, 300);
//dibujar el glyph rotado
g2.rotate(Math.PI/6, 200, 300);
g2.fill(glyph);
}
}

Programa 1.7: Cdigo utilizando Java2D que muestra un crculo y texto.

25

Figura 1.7. Grfico creado al ejecutar el cdigo de Java2D..

1.2.5.2 Java 3D.


Java 3D proporciona un rea de trabajo para grficos en 3D, incluyendo opciones
adicionales como animacin, interaccin 3D y vistas sofisticadas; adems
proporciona una interface de programacin relativamente simple e intuitiva. El
paradigma de programacin de Java 3D es muy diferente al de Java 2D. Un
modelo abstracto conocido como escena grfica es utilizado para organizar y
retener los objetos visuales y los comportamientos en la escena virtual. La escena
grfica contiene la informacin completa del mundo virtual de grficos. El motor
de renderizacin de Java 3D renderiza automticamente la escena grfica; esto
lo hace con un objeto Canvas 3D. Canvas 3D es un componente pesado que no
funciona adecuadamente con los componentes Swing.
A continuacin se muestra el cdigo de una aplicacin en Java 3D. Se presenta
un globo terrqueo en rotacin y un cadena de texto en 3D Java 3D situado
frente al globo.
import javax.vecmath.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.net.URL;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.image.*;
import com.sun.j3d.utils.applet.MainFrame;
public class Demo3D extends Applet{
public static void main(String[] args){
new MainFrame(new Demo3D(), 480, 480);
}
private SimpleUniverse su;

26

public void init(){


GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv);
BranchGroup bg = createSceneGraph();
bg.compile();
su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
public void destroy(){
su.cleanup();
}
private BranchGroup createSceneGraph(){
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
//texto 3D
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Font3D font = new Font3D(new Font("Helvetica", Font.PLAIN, 1), new FontExtrusion());
Text3D text = new Text3D(font, "Java 3D");
Shape3D shape = new Shape3D(text, ap);
//transformacin del texto
Transform3D tr = new Transform3D();
tr.setScale(0.2);
tr.setTranslation(new Vector3d(-0.35, -0.15, 0.75));
TransformGroup tg = new TransformGroup(tr);
root.addChild(tg);
tg.addChild(shape);
//globo
ap = createAppearance();
spin.addChild(new Sphere(0.7f, Primitive.GENERATE_TEXTURE_COORDS, 50, ap));
//rotacin
Alpha alpha = new Alpha(-1, 6000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//fondo y luces
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white), new Point3f(3f,3f,3f), new
Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
private Appearance createAppearance(){
Appearance ap = new Appearance();
URL filename = getClass().getClassLoader().getResource("earth.jpg");
TextureLoader loader = new TextureLoader(filename, this);
ImageComponent2D image = loader.getImage();
Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, image.getWidth(),
image.getHeight());
texture.setImage(0, image);
texture.setEnable(true);
texture.setMagFilter(Texture.BASE_LEVEL_LINEAR);
texture.setMinFilter(Texture.BASE_LEVEL_LINEAR);
ap.setTexture(texture);
return ap;
}
}

Programa 1.8: Cdigo utilizando Java3D que muestra un globo terrqueo en rotacin y texto.

27

Figura 1.8. Grfico creado al ejecutar el cdigo de Java3D.

1.3 Campos relacionados con la Graficacin.


La Graficacin por computadora, el procesamiento de imgenes y la visin por
computadora son campos relacionados con los objetos grficos. Son diferentes en
cuanto a sus objetivos y tcnicas; sin embargo, existe una relacin cercana y las
lneas divisorias entre ellas han ido desapareciendo con el paso de los aos.
El procesamiento de imgenes concierne a las tcnicas de procesar imgenes
digitales rasterizadas. Usualmente lidea los problemas de mejoramiento de
imagen, reduccin de ruido, compresin de imagen y deteccin de bordes. El
procesamiento de imgenes toma como entrada una imagen existente y realiza
acciones apropiadas en ella. La Graficacin por computadora, por otro lado,
genera imgenes sintticas de un mundo virtual. El procesamiento de imgenes
est cercanamente relacionado con la Graficacin por computadora, el resultado
del renderizado de grficos es normalmente imgenes. Las imgenes
rasterizadas son usadas comnmente en grficos por computadora como grficos
primitivos, adems de que

son utilizadas como texturas para mejorar

el

renderizado grfico.
La visin por computadora tiene la tarea de tratar de entender las imgenes del
mundo real; visto de cierta manera, un sistema de visin por computadora es lo
inverso a un sistema de graficacin por computadora. Su principal objetivo es

28

reconstruir un mundo virtual de imgenes de un mundo real. Por lo tanto la visin


por computadora y la Graficacin por computadora se complementan una con
otra; ambas proporcionan diferentes perspectivas de un sistema comn.
La teora y la prctica de la Graficacin por computadora dependen mayormente
de ciertos conceptos matemticos importantes. Las reas de las matemticas que
se relacionan son la geometra analtica y el algebra lineal. La geometra analtica
proporciona representaciones numricas de objetos grficos. Y el algebra lineal
estudia las operaciones y transformaciones de espacios vectoriales, los cuales
son importantes en muchos problemas fundamentales de la graficacin por
computadora.

29

TRANSFORMACIONES
GEOMTRICAS

2.1 Transformaciones bidimensionales.


Un sistema de grficos 2D modela un mundo virtual en dos dimensiones.
Comparado con los grficos 3D, los grficos en 2D son ms simples en cuanto a
modelado y renderizado. Los objetos 2D son ms fciles de crear y manipular. El
renderizado en 2D normalmente no involucra proyecciones complicadas como las
de los grficos en 3D. A pesar de que un modelo en 2D no puede capturar
completamente la naturaleza de un espacio en 3D, los grficos en 2D son
aplicados debido a su simplicidad y eficiencia. Esto es un ingrediente esencial de
los programas modernos basados en GUI.

30

Los conceptos claves de los grficos 2D incluyen el renderizar por un conducto, el


espacio del objeto, el espacio del mundo, el espacio del dispositivo, los sistemas
de coordenadas, las primitivas grficas, las transformaciones geomtricas, los
colores, fragmentos, reglas de composicin y otros temas. Java 2D proporciona
soporte para grficos 2D.
En los grficos 2D, el espacio del mundo virtual y el espacio de vistas son
bidimensionales. El renderizar involucra la composicin de varios objetos a travs
de transformaciones relativas. Frecuentemente un espacio del mundo no se
necesita cuando se modelan explcitamente las relaciones entre objetos grficos.
Sin embargo, para alcanzar la claridad de las estructuras de los sistemas y para
mantener la analoga con los grficos 3D, la nocin de un mundo virtual es
fundamental.
Conceptualmente un objeto grfico puede definirse en su propio espacio y puede
colocarse en un espacio de un mundo 2D a travs de una transformacin del
mismo. El renderizado 2D toma una foto del mundo y produce una imagen
representndola en una vista particular en el espacio del dispositivo.

Transformacin

Vista

Figura 2.1 Un objeto grfico en 2D es procesado para su transformacin y su vista.

Los componentes esenciales de un sistema grfico en 2D incluyen la


renderizacin modelo del objeto en 2D, la aplicacin de transformaciones
geomtricas al objeto, y una vista particular del mundo virtual en un dispositivo de
display. Los pasos para renderizar un grfico en un programa de grficos 2D son:
1. Construir los objetos en 2D.
2. Aplicar las transformaciones a los objetos.
3. Aplicar color y otras propiedades de renderizado.
4. Renderizar la escena en un dispositivo para grficos.

31

Los objetos grficos en el modelo son de dos dimensiones. Adems de los


objetos geomtricos construidos de primitivas bsicas como lneas, polgonos y
elipses, el modelo puede incluir objetos tales como texto e imgenes.
La transformacin involucrada en los grficos 2D forma parte de una Affine
Transformation. Las transformaciones cambian la forma y ubicacin

de los

objetos visuales a los cuales se les aplica dicha transformacin. Las vistas de
transformacin no cambian el modelo del mundo virtual, pero cambian las vistas
de la escena completa en el espacio mundo. Por ejemplo, si en un modelo virtual
con un crculo y un tringulo, se aplica una traslacin al crculo, (transformacin
de objeto) solo se mover el crculo sin afectar el tringulo. La traslacin como
una transformacin de vista, por otro lado, mover la vista completa.
Adems de la geometra, muchos otros atributos pueden afectar el renderizado de
una escena como colores, transparencia, texturizado y estilos de lnea. Un
sistema de grficos 2D renderizar una escena basada en la informacin
geomtrica, transformacin y el contexto grfico involucrando todos los atributos.

2.2 Coordenadas homogneas y representacin matricial.


Los componentes fundamentales en un modelo grfico son los objetos
geomtricos. Para poder representarlos de manera precisa y eficiente se tiene
que utilizar un sistema de coordenadas. El sistema de coordenadas ms utilizado
en 2D emplea las coordenadas cartesianas como se muestra en la siguiente
figura:

32

Figura 2.2 Sistema de coordenadas en 2D con el ejes (x, y)

Dos ejes perpendiculares son colocados en el plano. Cada eje est etiquetado por
un conjunto de nmeros reales. El eje horizontal se denomina eje

y el vertical

eje . La interseccin de los ejes se identifica con el nmero 0, y se denomina


punto de origen. Cada punto en el plano est asociado a un par de nmeros
reales

conocidos como coordenada

y coordenada

. Las coordenadas

miden la posicin horizontal y vertical de un punto relativo en los ejes.


Un objeto geomtrico en 2D es un conjunto de puntos en el plano. El nmero de
puntos en el conjunto que constituye el objeto geomtrico es usualmente infinito.
Para representar efectivamente tal objeto, se utiliza una ecuacin para definir la
relacin de las coordenadas

que un punto del objeto debe satisfacer.

Por ejemplo una lnea se puede representar a travs de una ecuacin polinomial
de grado 1 o ecuacin lineal:

Figura 2.3 Lnea que pude ser representada por una ecuacin lineal.

33

Un crculo centrado en el origen con un radio

se representa con la siguiente

ecuacin:

Una elipse centrada en ( ,

) presenta la siguiente ecuacin:

Otro tipo comn de ecuacin que se utiliza para representar una curva es la
ecuacin paramtrica. En lugar de una ecuacin que relacione nicamente a
, se utiliza una tercera variable . Ambas

son expresadas en funcin de .

La ventaja de las ecuaciones paramtricas es que proporcionan formas


funcionales explcitas para evaluar las coordenadas. La siguiente figura muestra
una elipse que tambin se puede expresar utilizando la ecuacin paramtrica:

Figura 2.4 Una elipse representada por una ecuacin cuadrtica.

La coleccin de todos los puntos o coordenadas tambin se conoce como


espacio. Tres tipos de espacios estn normalmente relacionados con un sistema
grfico: el espacio del objeto, el espacio del mundo, y el espacio del dispositivo.

34

Cada espacio es caracterizado por su propio sistema de coordenadas. Los


objetos geomtricos en un espacio pueden ser mapeados en otro a travs de
transformaciones.
Un sistema de coordenadas de un objeto, tambin conocido como sistema de
coordenadas de modelado o sistema de coordenadas local, est asociado con la
definicin de un objeto grfico particular o primitivo. Al construir tal objeto, es
conveniente elegir un sistema de coordenadas que sea natural al objeto sin
preocuparse por su destino final y apariencia en el espacio mundo. Por ejemplo,
cuando se define un crculo primitivo, se puede elegir el tener el origen del
sistema de coordenadas en el centro del crculo o simplemente definir una unidad
de crculo (un crculo de radio 1). El crculo posteriormente puede ser colocado en
cualquier parte del espacio mundo a travs de una transformacin llamada
traslacin. Su radio puede cambiar a cualquier valor al efectuar una escalacin.
Tambin se puede transformar en una elipse al utilizar una escalacin no
uniforme.
El sistema de coordenadas del mundo, o sistema de coordenadas del usuario,
define una referencia comn de todos los objetos en un modelo grfico.
Representa el mundo virtual compartido por los subsistemas modelados y
renderizados. Los objetos geomtricos son colocados en este espacio a travs de
transformaciones de objetos. El sistema de renderizacin toma una foto del
espacio y produce una imagen renderizada a travs de un dispositivo de salida.
El sistema de coordenadas del dispositivo representa el espacio del display de un
dispositivo de salida tal como una pantalla o una impresora. La siguiente figura
muestra un ejemplo tpico de tal sistema de coordenadas. El origen est
localizado en la esquina superior izquierda, las posiciones positivas del eje de las
apuntan hacia la derecha y las posiciones positivas del eje de las

apuntan

hacia abajo. Los valores de las coordenadas son valores enteros. Esta opcin
obviamente es diferente a cualquier representacin matemtica, pero es ms
natural para la mayora de los dispositivos de pantalla.

35

(0,0)

y
Figura 2.5 Sistema de coordenadas de Java 2D, con el eje x aumentando hacia la derecha y el eje
y hacia abajo.

Por default las coordenadas del mundo de Java 2D coinciden con las
coordenadas de los dispositivos. Con las transformaciones disponibles en un
sistema de grficos, es fcil definir diferentes espacios mundo que pueden ser los
ms apropiados para aplicaciones particulares.

2.3 Tipos de transformaciones bidimensionales.


Los objetos geomtricos atraviesan un estado de transformacin antes de ser
renderizados. Una familia general de transformaciones geomtricas comnmente
utilizadas en grficos por computadora se denomina Affine Transformation. Una
transformacin afin preserva las lneas paralelas; adems las que

tambin

preservan la distancia se conocen como isomtricas, movimientos euclidean o


movimientos rigidos. Las transformaciones afines ms comunes son:
Traslacin
Rotacin
Refleccin
Escalacin
Sesgar
Una traslacin mueve todos los puntos de un objeto a una cantidad establecida.
La cual est especificada por la cantidad de movimientos en las direcciones

y .

Una traslacin es isomtrica ya que no cambia las longitudes ni los ngulos. La

36

siguiente figura muestra la traslacin de un objeto de (3, -1). Es decir el objeto es


movido tres unidades a la derecha y una hacia arriba.

Figura 2.6 Una traslacin (3, -1)

Una rotacin mueve un objeto aproximadamente un punto por ngulo; es decir


est determinado por el punto y el anglo. Tambin es isomtrico, ya que cambia la
orientacin de la forma. La siguiente figura muestra una rotacin de 45 grados del
orgen.

Figura 2.7 Una rotacin sobre el origen

Una refleccin mapea el objeto a su imagen espejo sobre una lnea; es decir es
determinado por una lnea. La refleccin es isomtrica, ya que cambia la
orientacin del angulo. La siguiente figura muestra una refleccin de una lnea de
45 grados entre los ejes

y .

37

Figura 2.8 Una refleccin sobre una lnea diagonal.

La escalacin redimensiona el objeto por ciertos factores fijados en las


direcciones

y . La escalacin no es isomtrica, ya que cambia las distancias y

los ngulos. Sin embargo, preserva el paralelismo. La siguiente figura muestra


una escalacin de factores (1.5, 2).

Figura 2.9 Escalacin por los factores (1.5, 2).

El sesgar sobre una lnea es mover un punto una cantidad proporcional a la


distancia indicada por la lnea. Los movimientos de los puntos son paralelos a la
lnea; es decir, los puntos en la lnea no se mueven; sin embargo los puntos en el
lado opuesto de la lnea se mueven en direccin opuesta. Este tipo de
trasnformacin no es isomtrica, pero preserva el paralelismo. La siguiente figura
muestra el sesgar por el factor 1.0 sobre la lnea horizontal y =2

38

Figura 2.10 Sesgar por el factor 1 sobre la lnea horizontal punteada.

Matemticamente una transformacin afn puede ser representada por una matriz
3 x 3. Una transformacin afn requiere una matriz de 3 x 3 en lugar de una de 2
x 2, debido a que las transformaciones tales como las traslaciones no son lineales
en un espacio 2D. Utilizando el concepto de coordenadas homogneas, es
posible tratar todas las transformaciones afines en un ambiente lineal al agregar
una dimensin al vector de representacin de los puntos.
Para transformaciones bsicas, es comnmente ms sencillo encontrar las
matrices de transformacin directamente. Una rotacin del angulo sobre el
origen es representado con la matriz:

La traslacin por la cantidad

La escalacin por los factores

tiene la matriz:

tiene la matriz de representacin:

39

La refleccin en la lnea

El sesgar sobre el eje

es representada por la matriz:

por el factor

se da por la matriz:

Java 2D utiliza una clase llamada AffineTransform para definir una transformacin
afn. Ofrece mtodos para establecer la mayora de las transformaciones afines
bsicas definidas anteriormente. Los siguientes mtodos de AffineTransform
establecen las transformaciones nombradas:

void setToIdentity()

void setToRotation(double theta)

void setToRotation(double theta, double x, double y)

void setToScale(double sx, double sy)

void setToShear(double shx, double shy)

void setToTranslation(double tx, double ty)

Una transformacin que no se encuentra entre los mtodos listados es el de


refleccin. Sin embargo, se puede definir una refleccin al establecer su matriz.
La siguiente matriz define una refleccin sobre el eje :

La clase AffineTransform tiene constructores y mtodos que establecen


directamente las primeras dos filas de la matriz de transformacion:

40

AffineTransform(double m00, double m10, double m01, double m11,


double m02, double m12)

AffineTransform(float m00, float m10, float m01, float m11, float m02, float
m12)

AffineTransform(double[ ] flatmatrix)

AffineTransform(float[ ] flatmatrix)

void setTransform(double m00, double m10, double m01, double m11,


double m02, double m12)

Debido a que la ltima fila de una matriz de transformacin afin siempre es (001),
se omite en la lista de parmetros. La matriz de refleccin definida anteriormente
puede establecerse por el siguiente mtodo:
transform.setTranform(-1, 0, 0, 1, 0, 0);
Debido a que la clase de AffineTransform permite la escalacin con factores
negativos, la refleccin tambin puede definirse como un tipo especial de
escalacin:
transform.setToScale(-1, 1);
Un objeto AffineTransform puede ser utilizado por ambas transformaciones: de
objeto y de vista. Los siguientes mtodos de la clase se aplican a la
transformacin de objetos geomtricos.

Shape createTransformedShape(Shape shape)

void transform(double[ ] src, int src0ff, double[ ] dst, int dst0ff, int numPts)

void transform(double[ ] src, int src0ff, float[ ] dst, int dst0ff, int numPts)

void transform(float[ ] src, int src0ff, double[ ] dst, int dst0ff, int numPts)

void transform(float[ ] src, int src0ff, float[ ] dst, int dst0ff, int numPts)

Point2D transform(Point2D src, Point2D dst)

Point2D transform(Point2D[ ] src, int src0ff, Point2D[ ] dst, int dst0ff, int
numPts)

void deltaTransform(double[ ] src, int src0ff, double[ ] dst, int dst0ff, int
numPts)

41

Point2D deltaTransform(Point2D src, Point2D dst)

El mtodo createTransformedShape transforma una figura completa. Los mtodos


de Transform realizan una transformacin de un conjunto de puntos. El mtodo
deltaTransform realiza una transformacin de un conjunto de vectores.
Una transformacin de vista puede realizarse con la transformacin en un objeto
Graphics2D. La clase Graphics2D tiene los siguientes mtodos para manipular
sus transformaciones:

void setTansform(AffineTransform tx)

void transform(AffineTransform tx)

El mtodo setTransform reemplaza la transformacin actual con el objeto


AffineTransform dado. El mtodo transform concatena la actual transformacin
con el objeto AffineTransform de la derecha.
El siguiente ejemplo muestra los efectos de las transformaciones afines. El
usuario puede realizar una transformacin de un objeto grfico usando el mouse.
Las transformaciones affines son seleccionadas a travs de un men que incluye
la traslacin, rotacin, escalacin, sesgar y refleccin.
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class Transformations extends JApplet implements ActionListener {
public static void main(String s[]) {
JFrame frame = new JFrame();
frame.setTitle("Affine Transforms");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new Transformations();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
TransformPanel panel = null;
public void init() {
JMenuBar mb = new JMenuBar();
setJMenuBar(mb);
JMenu menu = new JMenu("Transforms");
mb.add(menu);
JMenuItem mi = new JMenuItem("Translation");
mi.addActionListener(this);
menu.add(mi);
mi = new JMenuItem("Rotation");

42

mi.addActionListener(this);
menu.add(mi);
mi = new JMenuItem("Scaling");
mi.addActionListener(this);
menu.add(mi);
mi = new JMenuItem("Shearing");
mi.addActionListener(this);
menu.add(mi);
mi = new JMenuItem("Reflection");
mi.addActionListener(this);
menu.add(mi);
panel = new TransformPanel();
getContentPane().add(panel);
}
public void actionPerformed(ActionEvent ev) {
String command = ev.getActionCommand();
if ("Translation".equals(command)) {
panel.transformType = panel.TRANSLATION;
} else if ("Rotation".equals(command)) {
panel.transformType = panel.ROTATION;
} else if ("Scaling".equals(command)) {
panel.transformType = panel.SCALING;
} else if ("Shearing".equals(command)) {
panel.transformType = panel.SHEARING;
} else if ("Reflection".equals(command)) {
panel.transformType = panel.REFLECTION;
}
}
}
class TransformPanel extends JPanel implements MouseListener, MouseMotionListener {
static final int NONE = 0;
static final int TRANSLATION = 1;
static final int ROTATION = 2;
static final int SCALING = 3;
static final int SHEARING = 4;
static final int REFLECTION = 5;
int transformType = NONE;
Shape drawShape = null;
Shape tempShape = null;
Point p = null;
int x0 = 400;
int y0 = 300;
public TransformPanel() {
super();
setPreferredSize(new Dimension(800, 600));
setBackground(Color.white);
drawShape = new Rectangle(-50,-50,100,100);
addMouseListener(this);
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.translate(x0, y0);
g2.drawLine(-200,0,200,0);
g2.drawLine(0,-200,0,200);
g2.draw(drawShape);
}
public void mouseClicked(MouseEvent ev) {
}
public void mouseEntered(MouseEvent ev) {
}
public void mouseExited(MouseEvent ev) {
}

43

public void mousePressed(MouseEvent ev) {


p = ev.getPoint();
}
public void mouseReleased(MouseEvent ev) {
Graphics g = getGraphics();
Point p1 = ev.getPoint();
AffineTransform tr = new AffineTransform();
switch (transformType) {
case TRANSLATION:
tr.setToTranslation(p1.x-p.x, p1.y-p.y);
break;
case ROTATION:
double a = Math.atan2(p1.y-y0, p1.x-x0) - Math.atan2(p.y-y0, p.x-x0);
tr.setToRotation(a);
break;
case SCALING:
double sx = Math.abs((double)(p1.x-x0)/(p.x-x0));
double sy = Math.abs((double)(p1.y-y0)/(p.y-y0));
tr.setToScale(sx, sy);
break;
case SHEARING:
double shx = ((double)(p1.x-x0)/(p.x-x0))-1;
double shy = ((double)(p1.y-y0)/(p.y-y0))-1;
tr.setToShear(shx, shy);
break;
case REFLECTION:
tr.setTransform(-1,0,0,1,0,0);
break;
}
drawShape = tr.createTransformedShape(drawShape);
repaint();
}
public void mouseMoved(MouseEvent ev) {
}
public void mouseDragged(MouseEvent ev) {
Point p1 = ev.getPoint();
AffineTransform tr = new AffineTransform();
switch (transformType) {
case TRANSLATION:
tr.setToTranslation(p1.x-p.x, p1.y-p.y);
break;
case ROTATION:
double a = Math.atan2(p1.y-y0, p1.x-x0) - Math.atan2(p.y-y0, p.x-x0);
tr.setToRotation(a);
break;
case SCALING:
double sx = Math.abs((double)(p1.x-x0)/(p.x-x0));
double sy = Math.abs((double)(p1.y-y0)/(p.y-y0));
tr.setToScale(sx, sy);
break;
case SHEARING:
double shx = ((double)(p1.x-x0)/(p.x-x0))-1;
double shy = ((double)(p1.y-y0)/(p.y-y0))-1;
tr.setToShear(shx, shy);
break;
case REFLECTION:
tr.setTransform(-1,0,0,1,0,0);
break;
}
Graphics2D g = (Graphics2D)getGraphics();
g.setXORMode(Color.white);
g.translate(x0, y0);
if (tempShape != null)
g.draw(tempShape);
tempShape = tr.createTransformedShape(drawShape);
g.draw(tempShape);
}
}

Programa 2.1: Cdigo que muestra efectos de las transformaciones afines.

44

Figura 2.11 Salida de la ejecucin del programa 2.1.

2.4 Composicin de transformaciones bidimensionales.


Las transformaciones pueden combinarse para formar nuevas transformaciones.
Por ejemplo, se puede aplicar una traslacin seguida de una rotacin y esta a su
vez seguida por otra traslacin. Cualquier composicin de transformaciones afines
sigue siendo una transformacin afin. Cualquier composicin de movimiento rgido
sigue siendo un movimiento rgido. Por lo contrario, una transformacin puede
descomponerse en una serie (normalmente ms simples) de transformaciones.
La matriz de transformacin de una transformacin compuesta es el producto de
las matrices de las transformaciones individuales. Por ejemplo, si
matrices de las transformaciones afines
matriz de la composicin

, es

son

, respectivamente, entonces la
. Cabe mencionar que la

operacin de la composicin de la transformacin es no conmutativa, por lo que el


orden al aplicar las transformaciones es significativo. En esta notacin, las
transformaciones de una transformacin compuesta son aplicadas de derecha a
izquierda. Por ejemplo, cuando una transformacin compuesta
aplicada a un punto , el orden de las transformaciones es

es

45

Las transformaciones compuestas son utilies cuando se desean construir


transformaciones complejas a partir de transformaciones simples. Si se necesita
una rotacin sobre el punto (3, 4) a 30 grados, primero se realiza la traslacin
para mover el punto (3, 4) del origen. Despus se realiza una rotacin de 30
grados sobre el origen. Finalmente se puede trasladar el origen de regreso al
punto (3, 4). Al combinar las tres tranformaciones, obtendremos la transformacin
requerida. En una matriz, la traslacin que mueve de (3, 4) al origen est dada
por:
1

-3

-4

La rotacin de 30 grados sobre el origen:


3/2

-1/2

1/2

3/2

La segunda traslacin sera:


1

Combinando las tres transformaciones, la rotacin final tendra la matriz de


transformacin:

3/2

-1/2

-3

3/2

-4

En Java 2D, la clase AffineTransform proporciona los siguientes mtodos que


soportan las tranformaciones compuestas:

46

void rotate(double theta)

void rotate(double theta, double x, double y)

void scale(double sx, double sy)

void shear(double shx, double shy)

void translate(double tx, double ty)

Estos mtodos no limpian las transformaciones existentes en los objetos actuales,


sino que combinan las transformaciones actuales con las nuevas especificadas.
Las nuevas transformaciones son aadidas a la derecha de las actuales. Adems
de

las

transformaciones

simples

listadas,

es

posible

combinar

las

transformaciones actuales con otro objeto de AffineTransform:

void concatenate(AffineTransform tx)

void preConcatenate(AffineTransform tx)

El primer mtodo concatena la segunda transformacin a la derecha de la actual.


El segundo mtodo concatena la segunda transformacin a la izquierda de la
actual.
Cabe notar que el orden de la composicin de la transformacin es de izquierda a
derecha, y los mtodos anteriores, excepto el de preConcatenate, concatena la
transformacin a la derecha. Si se crea una transformacin de composicin al
llamar a los mtodos mencionados anteriormente, las transformaciones son
aplicadas en el orden opuesto a la secuencia del llamado. Por ejemplo:
AffineTransform transform = new AffineTransform();
transform.rotate(Math.PI/3);
transform.scale(2, 0.3);
transform.translate(100, 200);
La primera transformacin a aplicar es la traslacin y la ltima es la rotacin. El
siguiente cdigo muestra el uso de las composiciones en transformaciones. El
ejemplo trata de rotar una elipse sobre su centro que no est localizado en el
origen, por lo que lo primero que traslada el objeto al origen, luego lo rota en el
origen y finalmente trasladar la elipse rotada a su punto original.

47

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class Composition extends JApplet {
public static void main(String s[]) {
JFrame frame = new JFrame();
frame.setTitle("Transformation Composition");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new Composition();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
public void init() {
JPanel panel = new CompositionPanel();
getContentPane().add(panel);
}
}
class CompositionPanel extends JPanel {
public CompositionPanel() {
setPreferredSize(new Dimension(640, 480));
this.setBackground(Color.white);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.translate(100,100);
Shape e = new Ellipse2D.Double(300, 200, 200, 100);
g2.setColor(new Color(160,160,160));
g2.fill(e);
AffineTransform transform = new AffineTransform();
transform.translate(-400,-250);
e = transform.createTransformedShape(e);
g2.setColor(new Color(220,220,220));
g2.fill(e);
g2.setColor(Color.black);
g2.drawLine(0, 0, 150, 0);
g2.drawLine(0, 0, 0, 150);
transform.setToRotation(Math.PI / 6.0);
e = transform.createTransformedShape(e);
g2.setColor(new Color(100,100,100));
g2.draw(e);
transform.setToTranslation(400, 250);
e = transform.createTransformedShape(e);
g2.setColor(new Color(0,0,0));
g2.draw(e);
}
}

Programa 2.2: Cdigo que aplica la composicin de transformaciones.

Figura 2.12 Salida de la ejecucin del programa 2.2.

48

2.5 Transformaciones de la composicin general.


Las reglas de composicin determinan los resultados de objetos renderizados
superpuestos. Al elegir reglas de composicin se pueden obtener varios efectos
visuales, como diferentes grados de transparencia.
Para establecer las reglas de composicin, el concepto de un canal
necesario. El canal

es

puede ser visto como parte de las propiedades del color que

especifican la transparencia. Un valor

es un nmero entre 0.0 y 1.0, siendo el

0.0 la transparencia completa y el 1.0 la opacidad completa.


Dando la fuente y destino del pixel de color y los valores , las reglas Porter-Duff
definen el resultado del color y los valores

como una combinacin lineal de la

fuente y los valores de destino:

Frecuentemente los components de color deben tener valores

premultiplicados

para acelerar el clculo. Las diferentes elecciones de los dos coeficientes

en la equacin definen las diferentes reglas de composicin. Existen 12 reglas


Porter Duff, que tienen los coeficientes mostrados en la tabla 2.1.
Las reglas Porter-Duff pueden derivarse sistemticamente de un modelo
probabilstico. El valor

de un color puede ser interpretado como la probabilidad

de que el color se mostrar, o ms concretamente como la porcin del rea del


pixel cubierto por un color especfico. Al combinar el cdigo y los colores destinos
con sus respectivos valores , se deben considerar cuatro diferentes casos: solo
se presenta el color fuente, solo se presenta el color destino, ambos colores se
presentan o ningn color se presenta. La figura 2.13 muestra los cuatro eventos,
los cuales ocurren con una probabilidad de
d),

s(1-

d),

d(1-

),

d,

y (1-

s)(1-

respectivamente. Una regla de composicin simplemente decide si retiene el

color cuando este ocurra. En el evento de solo cdigo fuente, una regla puede

49

elegir el matener el color fuente u omitirlo. En el evento solo color destino, el color
destino puede ser seleccionado u omitido, en el evento de ambos colores, una
regla puede elegir el color fuente, el color destino o ninguno de ellos. En el evento
ningn color, una regla solo puede no elegir color. Por lo tanto el nmero total de
reglas basado en este modelo es 2 x 2 x 3 x 1 = 12.
Ninguno

Fuente

Ambos Destino

Figura 2.13 Cuatro eventos diferentes de color que pueden ocurrir en el modelo probabilstico de
composicin.

Por ejemplo, la regla SrcOver elige el color fuente en el evento de solo color
fuente y el evento de ambos colores. Elige el color destino en el evento solo color
destino. No debe elegir ningn color en el evento de ninguno. Por consecuencia la
probabilidad de que ocurra el color fuente en el color es
probabilidad del color destino es

d(1-

s).

s(1-

d),

y la

Esto lleva a la seleccin del coeficiente

como se muestra en la tabla:


Regla Porter-Duff
Clear

SrcOver

DstOver

1-

SrcIn
DstIn
SrcOut

0
1d

1
0

0
1-

s
d

DstOut

1-

Src

Dst

50

SrcAtop

1-

DstAtop

1-

Xor

1-

s
s

1-

Tabla 2.1 Las 12 reglas de composicin Porter Duff

En las versiones anteriores de Java 2D se soportan las primeras ocho reglas. A


partir de J2SDK 1.4, las 12 reglas son soportadas. La clase AlphaComposite
encapsula dichas reglas. Una instancia para una regla de AlphaComposite puede
obtenerse por un campo esttico de AlphaComposite con el nombre mostrado en
la tabla. Para aplicar las reglas de composicin un objeto Graphics2D
siemplemente llama al mtodo setComposite. Por ejemplo, los siguientes
comandos establecen una regla de composicin de SrcIn:
Graphics2D g2 = (Graphics2D)g;
g2.setComposite(AlphaComposite.SrcIn);
El siguiente cdigo muestra una aplicacin de la clase AlphaComposite que
implementa las reglas Porter-Duff. El ejemplo muestra ciertos objetos visuales
renderizados con las 12 reglas de composicin. Las reglas son seleccionadas al
dar click con el mouse en el panel de display.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.io.*;
import java.net.URL;
import javax.imageio.*;
public class Compositing extends JApplet {
public static void main(String s[]) {
JFrame frame = new JFrame();
frame.setTitle("Compositing Rules");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new Compositing();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
public void init() {
JPanel panel = new CompositPanel();
getContentPane().add(panel);
}
}
class CompositPanel extends JPanel implements MouseListener {
BufferedImage image;

51

int[] rules = {AlphaComposite.CLEAR, AlphaComposite.SRC_OVER,


AlphaComposite.DST_OVER, AlphaComposite.SRC_IN,
AlphaComposite.DST_IN, AlphaComposite.SRC_OUT,
AlphaComposite.DST_OUT, AlphaComposite.SRC,
AlphaComposite.DST, AlphaComposite.SRC_ATOP,
AlphaComposite.DST_ATOP, AlphaComposite.XOR};
int ruleIndex = 0;
public CompositPanel() {
setPreferredSize(new Dimension(500, 400));
setBackground(Color.white);
URL url = getClass().getClassLoader().getResource("images/earth.jpg");
try {
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
addMouseListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(image, 100, 100, this);
AlphaComposite ac = AlphaComposite.getInstance(rules[ruleIndex], 0.4f);
g2.setComposite(ac);
Shape ellipse = new Ellipse2D.Double(50, 50, 120, 120);
g2.setColor(Color.red);
g2.fill(ellipse);
g2.setColor(Color.orange);
Font font = new Font("Serif", Font.BOLD, 144);
g2.setFont(font);
g2.drawString("Java", 90, 240);
}
public void mouseClicked(MouseEvent e) {
ruleIndex++;
ruleIndex %= 12;
repaint();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}

Programa 2.3: Objetos renderizados con las 12 reglas de composicin.

Figura 2.14 Salida de la ejecucin del programa 2.3.

52

2.6 Transformacin ventana-rea de vista.


Una trayectoria de recorte define una regin en la cual los objetos pueden ser
visibles. Graphics2D mantiene una regin actual para el recorte. Cuando se dibuja
objeto, este es entrecortado por la trayectoria de recorte. Las porciones del objeto
que se encuentran fuera de la trayectoria no se dibujarn. El siguiente segmento
de cdigo muestra una elipse como la forma del recorte y dibuja una imagen; solo
la porcin de la imagen que se encuentra dentro de la elipse ser visible.
Graphics2D g2 = (Graphics2D)g;
Shape ellipse = new Ellipse2D.Double(0,0,300,200);
g2.setClip(ellipse);
g2.drawImage(image, 0, 0, this);
Otro metodo de Graphics2D que cambia la regin de recorte es:

void clip(Shape path)

El mtodo cortar la regin actual de recorte con la figura especificada. El


siguiente ejemplo demuestra el uso de la trayectoria de recorte. En el programa
se crea una figura y la cual es utilizada como la trayectoria de recorte para un
objeto Graphics2D. El dibujo es entrecortado por la figura.
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
public class TestClip extends JApplet {
public static void main(String s[]) {
JFrame frame = new JFrame();
frame.setTitle("Clip Path");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new TestClip();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
public void init() {
JPanel panel = new ClipPanel();
getContentPane().add(panel);
}
}
class ClipPanel extends JPanel {
public ClipPanel() {
setPreferredSize(new Dimension(500, 500));
setBackground(Color.white);
}

53

public void paintComponent(Graphics g) {


super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
path.moveTo(100,200);
path.quadTo(250, 50, 400, 200);
path.lineTo(400,400);
path.quadTo(250,250,100,400);
path.closePath();
g2.clip(path);
g2.setColor(new Color(200,200,200));
g2.fill(path);
g2.setColor(Color.black);
g2.setFont(new Font("Serif", Font.BOLD, 60));
g2.drawString("Clip Path Demo",80,200);
g2.drawOval(50, 250, 400, 100);
}
}

Programa 2.4: Cdigo que presenta un ejemplo de trayectoria de recorte.

Figura 2.15 Salida de la ejecucin del programa 2.4.

2.7 Representacin matricial de transformaciones tridimensionales.


Las transformaciones juegan un papel importante en los grficos por
computadora. A travs de transformaciones geomtricas apropiadas, los objetos
grficos pueden cambiar en forma, tamao y ubicacin. Las transformaciones
afines son utilizadas frecuentemente en el modelado del mundo virtual. Un tipo
especial de transformacin es la perspectiva o proyeccin ortogonal, que
comnmente se utiliza en las vistas para constuir el mapeo de un espacio 3D a
una imagen 2D. La animacin frecuentemente involucra la aplicacin de
transformaciones geomtricas para alcanzar los movimientos en una escena.
Java 3D proporciona soporte para

transformaciones en diversos niveles. Las

clases de matrices tal como Matrix4d ofrecen la representacin de datos de bajo

54

nivel

de

las

transformaciones.

La

clase

Transform3D

encapsula

las

transformaciones 3D con las facilidades necesarias para establecer y componer


las transormaciones y para aplicarlas a puntos y vectores. La clase
TransformGroup representa el nivel alto de los nodos de transformacin en las
grficas de la escena.
Con el uso de las coordenadas homogenas, todas las transformaciones
proyectivas en 3D (incluyendo las transformaciones affines) estn completamente
determinadas por transformaciones matriciales 4 x 4. Las transformaciones con
interpretaciones geomtricas directas tales como las rotaciones y las traslaciones
pueden ser expresadas con matrices. Sin embargo, la construccin de matrices
explcitas de ciertas transformaciones tales como rotaciones generales en 3D
pueden ser complicadas. Otras representaciones, como la de un vector de cuatro
dimensiones para presentar una rotacin 3D, pueden proporcionar formas
intermedias ms convenientes para construcciones y manipulaciones de objetos.
Las transformaciones pueden combinarse para formar nuevas transformaciones.
Una manera poderosa para construir y manipular transformaciones complejas es
la composicin de transformaciones simples. En Java 3D la composicin puede
ocurrir en el nivel mas bajo de una matriz o de un objeto Transform3D a travs de
la multiplicacin de las transformaciones. Aunque tambin puede ocurrir en un
nivel alto de una escena grfica, donde la cadena de los nodos de
transformaciones crea el efecto de una transformacin compuesta.
La aplicacin principal de las transformaciones es cambiar las caractersticas
geomtricas de los objetos. En Java 3D los nodos de TransformGroup
representan las transformaciones y aplican a su hijo la transformacin definida en
el nodo. Otra aplicacin de las transformaciones es el ayudar a la construccin de
figuras geometricas. La clase Transform3D ofrece mtodos convenientes para
aplicar los puntos o vectores de transformacin. Para construir figuras
geometricas que tienen diversas propiedades simtricas, se puede tomar la
ventaja de las capacidades de la transformacin al generar muchos puntos de la
figura a travs de transformaciones de un conjunto de puntos base.

55

2.7.1 Transformaciones tridimensionales.


Una transformacin es un mapeo de un espacio de un vector a si mismo o a otro
espacio de vector. Ciertas familias de transformaciones que preservan algunas
propiedades goemtricas tienen un significado muy especial para la graficacin
por computadora. Por ejemplo, las transformaciones proyectivas son cruciales en
las vistas en 3D. Las transformaciones afines, son un subconjunto de las
transformaciones proyectivas, y son utilizadas extensamente en el modelado
visual de los objetos.
Una transformacin afin mapea lneas a lneas y preserva el paralelismo. Por
ejemplo, una transformacin afin puede no mapear un rectagulo a un rectngulo,
pero siempre mapear un rectngulo a un paralelograma. As como en el caso de
2D,

las

transformaciones

afines

3D

incluyen

traslaciones,

rotaciones,

escalaciones, sesgaciones y reflecciones. Sin embargo, las versiones de las


trasnformaciones en 3D son frecuentemente ms complejas, especialmente las
rotaciones.
Las transformaciones afines que adems preservan las distancias son conocidas
como movimientos rgidos, movimientos Euclidean o movimientos isomtricos.
Las traslaciones, rotaciones y reflecciones son ejemplos de movimientos rgidos.

2.7.2 Matriz de transformacin.

Las transformaciones afines pueden representarse en forma de matriz. Si un


punto en un espacio en 3D es representado por tres coordenadas:

Entonces la transformacin afin puede ser representada como una equacin


matriz:

56

Las rotaciones, escalaciones y sesgaciones relativas al origen pueden ser


representados por la matriz de multiplicacin sola. La adicin de la columna vector
representa una traslacin. Debido a que se requiere de un tratamiento especial
para las traslaciones, la transformacin descrita arriba no es lineal en el espacio
. Sin embargo, al utilizar coordenadas homogneas para representar puntos
3D, todas las transformaciones afines y las transformaciones proyectivas pueden
ser

representadas

como

matriz

de

multiplicaciones.

homogneas de un punto 3D tiene cuatro componentes:


es 0, corresponde a una coordenada regular 3D

Las

coordenadas
. Cuando

no

. Con las

coordenadas homogneas, las mismas transformaciones afines dadas en la parte


superior pueden ser representadas equivalentemente como una transformacin
lineal en el espacio

La matriz de transformacin 4 x 4 en la equacin determina completamente una


transformacin afin. Las operaciones involucradas en la transformacin pueden
ser representadas como su correspondiente matriz de operaciones. El combinar
diversas transformaciones afines produce otra transformacin afin. La matriz de
una transformacin de composicin es el producto de las matrices de
trasnformaciones correspondientes. La matriz inversa de una transformacin
corresponde a la misma transformacin inversa. Una trasformacin proyectiva
puede ser representada con una equacin de matriz similar a:

Java 3D ofrece diversas clases que soportan las transformaciones. Adems de


clases de vector, el paquete javax.vecmath contiene clases de matrices que

57

representan matrices de 3 x 3, y de 4 x 4, y matrices generales como: Matrix3f,


Matrix3d, Matrix4f, Matrix4d, GMatrix. El siguiente segmento de cdigo contruye
un objeto Matrix4d:
double[ ] array = { 1.0, 2.0, 3.0, 1.0,
0.0, 1.0, -1.0, 2.0,
4.0, 0.0, 0.5, -1.0,
0.0, 0.0, 0.0, 1.0 };
Matrix4d matrix = new Matrix4d(array);
La clase GMatrix puede ser utilizada para representar una matriz de tamaos
arbitrarios con elementos del tipo double. Por ejemplo el siguiente cdigo crea
una matriz de 3 x 4:
double[ ] array = {1.0, 2.0, 3.0, 1.0,
0.0, 1.0, -1.0, 2.0,
4.0, 0.0, 0.5, -1.0};
GMatrix matrix = new GMatrix(3, 4, array);
Las operaciones bsicasde las matrices tales como la suma, multiplicacin, e
inversin son posibles de realizar. La siguiente es una lista parcial de mtodos de
la clase Matrix4d para operaciones con matrices. Otras clases contienen mtodos
similares:
void add(Matrix4d m1): suma una matriz m1 a la matriz actual.
void sub(Matrix4d m1): resta una matriz m1 a la matriz actual.
void mul(Matrix4d m1): multiplica una matriz m1 a la matriz actual.
void invert(): invierte la matriz actual.
void add(Matrix4d m1, Matrix4d m2): establece la matriz actual a la suma
de las matrices m1 y m2.
void sub(Matrix4d m1, Matrix4d m2): establece la matriz actual a la resta de
las matrices m1 y m2.
void mul(Matrix4d m1, Matrix4d m2): establece la matriz actual a la
multiplicacin de las matrices m1 y m2.
void invert(Matrix4d m1): establece la matriz actual con la inversin de la
matriz m1.

58

void transpose(): traspone la matriz actual.


void mul(doubl scalar): multiplica la matriz actual por el numero dado en
scalar.
double determinant(): regresa el determinante de la matriz actual.
El siguiente cdigo proporciona una clase que despliega una matriz.
import java.awt.*;
import javax.vecmath.*;
public class MatrixPanel extends Panel {
TextField[] fields = new TextField[16];
public MatrixPanel() {
setLayout(new GridLayout(4, 4));
for (int i = 0; i < 16; i++) {
fields[i] = new TextField(5);
if (i/4 == i%4)
fields[i].setText("1");
else
fields[i].setText("0");
add(fields[i]);
}
}
public MatrixPanel(Matrix4d m) {
setLayout(new GridLayout(4, 4));
for (int i = 0; i < 16; i++) {
fields[i] = new TextField(5);
fields[i].setText("" + m.getElement(i/4, i%4));
add(fields[i]);
}
}
public void set(Matrix4d m) {
for (int i = 0; i < 16; i++) {
fields[i].setText("" + m.getElement(i/4, i%4));
}
}
public void get(Matrix4d m) {
for (int i = 0; i < 16; i++) {
m.setElement(i/4, i%4, Double.parseDouble(fields[i].getText()));
}
}
}

Programa 2.5: Cdigo que proporciona una clase que despliega una matriz.

El siguiente cdigo proporciona al usuario la vista de la matriz del programa 2.5.


El usuario puede realizar ciertas operaciones con la matriz utilizando los mtodos
dados por la clase Matrix4d.
import java.awt.*;
import java.awt.event.*;
import javax.vecmath.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestMatrix extends Applet implements ActionListener {
public static void main(String[] args) {
new MainFrame(new TestMatrix(), 600, 200);
}

59

MatrixPanel mp;
Matrix4d m = new Matrix4d();
TextField tf;
public void init() {
this.setLayout(new BorderLayout());
mp = new MatrixPanel();
add(mp, BorderLayout.CENTER);
Panel p = new Panel();
p.setLayout(new GridLayout(6,1));
Button button = new Button("Identity");
button.addActionListener(this);
p.add(button);
button = new Button("Zero");
button.addActionListener(this);
p.add(button);
button = new Button("Negate");
button.addActionListener(this);
p.add(button);
button = new Button("Transpose");
button.addActionListener(this);
p.add(button);
button = new Button("Invert");
button.addActionListener(this);
p.add(button);
button = new Button("Determinant");
button.addActionListener(this);
p.add(button);
this.add(p, BorderLayout.EAST);
tf = new TextField();
add(tf, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if ("Identity".equals(cmd)) {
mp.get(m);
m.setIdentity();
mp.set(m);
} else if ("Zero".equals(cmd)) {
mp.get(m);
m.setZero();
mp.set(m);
} else if ("Negate".equals(cmd)) {
mp.get(m);
m.negate();
mp.set(m);
} else if ("Transpose".equals(cmd)) {
mp.get(m);
m.transpose();
mp.set(m);
} else if ("Invert".equals(cmd)) {
mp.get(m);
m.invert();
mp.set(m);
} else if ("Determinant".equals(cmd)) {
mp.get(m);
tf.setText("" + m.determinant());
}
}
}

Programa 2.6: Cdigo que proporciona una interface para visualizar una matriz y realizar diversas
operaciones sobre ella.

60

Figura 2.16 Salida de la ejecucin del programa 2.6.

2.7.3 Tipos de transformaciones tridimensionales.


Java 3D incluye la clase Transform3D que representa las transformaciones afines
3D o transformaciones proyectivas. Transform3D internamente mantiene una
matriz double 4 x 4 para realizar una transformacin. Para crear un objeto
Transform3D se debe utilizar cualquiera de sus constructores disponibles, el
constructor por default crea una matriz de identidad; aunque tambin se puede
administrar un objeto matriz, un arreglo u otra forma de matriz de transformacin.
Por ejemplo el siguiente cdigo presenta tres objetos Transform3D y sus
transformaciones equivalentes:
double[ ] array = {1.0, 2.0, 3.0, 1.0,
0.0, 1.0, -1.0, 2.0,
4.0, 0.0, 0.5, -1.0,
0.0, 0.0, 0.0, 1.0};
Matrix4d matrix = new Matrix4d(array);
GMatrix gmatrix = new GMatrix(4, 4, array);
Transform3D transform1 = new Transform3D(matrix);
Transform3D transform2 = new Transform3D(gmatrix);
Transform3D transform3 = new Transform3D(array);
Transform3D contiene un gran nmero de mtodos que establecen y manipulan la
tansformacin. Algunos de los mtodos que directamente manejan la matriz de
transformacin son los siguientes:
void set(Matrix4d m1): establece la matriz de transformacin a m1.
void set(Matrix4f m1): establece la matriz de transformacin a m1.

61

void set(GMatrix m1): establece la matriz de transformacin a m1.


void set(double[ ] array): establece la matriz de transformacin al arreglo.
void set(float[ ] array): establece la matriz de transformacin al arreglo.
void get(Matrix4d m1): obtiene la matriz de transformacin a m1.
void get(Matrix4f m1): obtiene la matriz de transformacin a m1.
void get(GMatrix m1): obtiene la matriz de transformacin a m1.
void get(double[ ] array): obtiene la matriz de transformacin al arreglo.
void get(float[ ] array): obtiene la matriz de transformacin al arreglo.
Las transformaciones afines 3D ms comunes son:
Traslacin
Escalacin
Refleccin
Sesgar
Rotacin
Una traslacin puede ser representada por la matriz de transformacin:

Debajo de la traslacin, cada punto se mueve por las cantidades constantes


en las direcciones

, respectivamente. La forma y orientacin de la

figura geomtrica no cambiar debido a la traslacin. El inverso de una traslacin


por

es una traslacin por

Transform3D incluye los siguientes mtodos para establecer traslaciones:


void set(Vector3d trans)
void set(Vector3f trans)
void setTraslation(Vector3d trans)
void setTranslation(Vector3f trans)

62

El conjunto de mtodos reemplazan la transformacin completa con la traslacin


especificada. Los mtodos setTranslation modifican solo los componentes de la
traslacin de la transformacin existente.
Una escalacin por los factores

en las direcciones

tiene la

siguiente matriz de representacin:

Si todos los factores de escalacin no son ceros, la transformacin de escalacin


es invertible. La matriz inversa tambin es una escalacin con los factores
. Una escalacin es uniforme si

Transform3D incluye los siguientes mtodos para establecer las escalaciones:


void set(double scale)
void setScale(double scale)
void setScale(Vector3d scales)
El conjunto de mtodos reemplazan la transformacin completa con una
escalacin. Los mtodos setScale modifican solo los componentes a escalar de la
transformacin existente.
Una refleccin 3D es realizada sobre un plano. Una simple refleccin sobre el
plano

, por ejemplo, tendra la siguiente matriz:

63

Una refleccin siempre es inversible, y la inversin de una refleccin es la


refleccin misma. Una refleccin sobre un plano a travs del origen con el vector
normal

puede expresarse como:

Una matriz de representacin puede derivarse de su equacin.


Una sesgacin 3D mueve un punto a lo largo del plano, y la cantidad del
movimiento depende de la distancia del punto al plano. Una sesgacin simple que
solo cambia las coordenadas

Las coordenadas
coordenadas

presenta la siguiente matriz:

no son modificadas al realizar esta transformacin. Las

son movidas acorde a la ecuacin:

Una sesgacin ms general

mueve a ambas coordenadas y se representa

como:

La sesgacin es inversible. La inversin de la sesgacin presentada en la matriz


de arriba es otra sesgacin del mismo tipo con parmetros

La rotacin en 3D es una operacin compleja. Una rotacin general en 3D tiene


un eje de rotacin que puede ser cualquier lnea en el espacio. Alrededor del eje
todos los puntos son rotados por un angulo fijo. Una rotacin del angulo
eje

sobe el

puede ser representado por la siguiente matriz:

64

A pesar de que cualquier rotacin puede ser representada como una matriz de
transformacin, es difcil obtener la matriz de transformacin directamente de las
especificaciones geomtricas de una rotacin general. Por ejemplo, puede ser
fcil el obtener matrices para rotaciones sobre los ejes ,
matriz de rotacin del ngulo

o ; pero cul sera la

sobre los ejes (1, 1, 1)? Una representacin de

una rotacin general en 3D que ofrece una coneccin ms directa a sus


propiedades geomtricas involucra el uso de cuaterniones. El cuaternin es un
sistema numrico que extiende los campos de nmeros complejos.
Un punto

en un espacio 3D utilizando un cuaternin puro (cuaternin con

parte real 0) se representa como:


Siendo

un cuaternin fijo. Una transformacin en el espacio 3D puede estr

definida por:

Si

es una unidad de cuaternin, entonces se puede ver que la transformacin

definida arriba es una rotacin. En este caso

La unidad vector

puede ser representado por:

define la direccin del eje de rotacin, y el eje pasa a travs

del origen. El ngulo de rotacin est dado por .


Java 3D incluye las clases Quat4f y Quat4d para representar cuaterniones.
Adems de las operaciones inherentes de las clases Tuple4*, las operaciones
estndares para cuaterniones tales como conjugar, multiplicar, invertir y
normalizar son soportadas en estas clases. Debido a la coneccin con rotaciones

65

dichas clases soportan adems mtodos convenientes para directamente


establecer una rotacin de cuaternin basadas en un eje y ngulo especificado.
void set(AxisAngle4d r)
La clase Transform3D proporciona constructores y mtodos para aceptar
directamente parmetros de cuaterniones como especificaciones de rotacin:
Transform3D(Quat4d q, Vector3d translation, double scale)
Transform3D(Quat4f q, Vector3d translation, double scale)
Transform3D(Quat4f q, Vector3f translation, float scale)
void set(Quat4d q)
void set(Quat4f q)
Otra manera de representar rotaciones en 3D es el usar tres rotaciones
de ciertos ngulos sobre las coordenadas ejes. El eje para
ejes

es diferente de los

. Los tres angulos son conocidos como los ngulos Euler. La clase

Transform3D proporciona los mtodos para establecer la rotacin basada en los


ngulos Euler.
void setEuler(Vector3d eulerAngles)
El objeto Vector3d especifica los ngulos Euler sobre los ejes

. Los

ngulos son conocidos como elevacin, azimut e inclinacin. ****banco, altitud y


cabecera. Sin embargo, no existe ningn mtodo en Transform3D para recuperar
los angulos Euler. Se puede utilizar un mtodo get para recuperar un cuaternin y
despus convertir lo en ngulos Euler. El siguiente cdigo muestra una
conversin de un cuaternin a los ngulos Euler:
public static Vector3d quat2Euler(Quat4d q1) {
double sqw = q1.w*q1.w;
double sqx = q1.x*q1.x;
double sqy = q1.y*q1.y;
double sqz = q1.z*q1.z;
double heading = Math.atan2(2.0 * (q1.x*q1.y + q1.z*q1.w),(sqx - sqy - sqz + sqw));
double bank = Math.atan2(2.0 * (q1.y*q1.z + q1.x*q1.w),(-sqx - sqy + sqz + sqw));
double attitude = Math.asin(-2.0 * (q1.x*q1.z - q1.y*q1.w));
return new Vector3d(bank, attitude, heading);
}

Programa 2.7: Cdigo que muestra la conversin de un cuaternin a los ngulos Euler.

66

Transform3D contiene mtodos similares a los de la clase Matrix4d para las


operaciones de la matriz de transformacin. Tambin permite la aplicacin directa
de la transformacin a puntos o vectores. Esta caracterstica facilita la
construccin de geometras a travs de transformaciones.
El siguiente cdigo proporciona una clase que despliega un conjunto de
coordenadas.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class Axes extends Group {
public Axes() {
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Font3D font = new Font3D(new Font("SanSerif", Font.PLAIN, 1),
new FontExtrusion());
Text3D x = new Text3D(font, "x");
Shape3D xShape = new Shape3D(x, ap);
Text3D y = new Text3D(font, "y");
Shape3D yShape = new Shape3D(y, ap);
Text3D z = new Text3D(font, "z");
Shape3D zShape = new Shape3D(z, ap);
// transform for texts
Transform3D tTr = new Transform3D();
tTr.setTranslation(new Vector3d(-0.12, 0.6, -0.04));
tTr.setScale(0.5);
// transform for arrows
Transform3D aTr = new Transform3D();
aTr.setTranslation(new Vector3d(0, 0.5, 0));
// x axis
Cylinder xAxis = new Cylinder(0.05f, 1f);
Transform3D xTr = new Transform3D();
xTr.setRotation(new AxisAngle4d(0, 0, 1, -Math.PI/2));
xTr.setTranslation(new Vector3d(0.5, 0, 0));
TransformGroup xTg = new TransformGroup(xTr);
xTg.addChild(xAxis);
this.addChild(xTg);
TransformGroup xTextTg = new TransformGroup(tTr);
xTextTg.addChild(xShape);
xTg.addChild(xTextTg);
Cone xArrow = new Cone(0.1f, 0.2f);
TransformGroup xArrowTg = new TransformGroup(aTr);
xArrowTg.addChild(xArrow);
xTg.addChild(xArrowTg);
// y axis
Cylinder yAxis = new Cylinder(0.05f, 1f);
Transform3D yTr = new Transform3D();
yTr.setTranslation(new Vector3d(0, 0.5, 0));
TransformGroup yTg = new TransformGroup(yTr);
yTg.addChild(yAxis);
this.addChild(yTg);
TransformGroup yTextTg = new TransformGroup(tTr);
yTextTg.addChild(yShape);
yTg.addChild(yTextTg);
Cone yArrow = new Cone(0.1f, 0.2f);
TransformGroup yArrowTg = new TransformGroup(aTr);
yArrowTg.addChild(yArrow);
yTg.addChild(yArrowTg);
// z axis
Cylinder zAxis = new Cylinder(0.05f, 1f);
Transform3D zTr = new Transform3D();

67

zTr.setRotation(new AxisAngle4d(1, 0, 0, Math.PI/2));


zTr.setTranslation(new Vector3d(0, 0, 0.5));
TransformGroup zTg = new TransformGroup(zTr);
zTg.addChild(zAxis);
this.addChild(zTg);
TransformGroup zTextTg = new TransformGroup(tTr);
zTextTg.addChild(zShape);
zTg.addChild(zTextTg);
Cone zArrow = new Cone(0.1f, 0.2f);
TransformGroup zArrowTg = new TransformGroup(aTr);
zArrowTg.addChild(zArrow);
zTg.addChild(zArrowTg);
}
}

Programa 2.8: Cdigo que proporciona la clase que despliega un conjunto de coordenadas.

El siguiente cdigo demuestra las caractersticas de la clase Transform3D


grficamente. Una matriz de transformacin correspondiente a un objeto
Transform3D es desplegado y puede ser editado por el usuario. Los componentes
de rotacin, traslacin y escalacin de la transformacin son extrados y
desplegados separadamente. El usuario adems puede especificar tres
componentes y aplicarlos a la transformacin. La transformacin puede aplicarse
a un objeto visual o un conjunto de coordenadas 3D, por lo que su efecto puede
visualizarse inmediantamente. El programa proporciona una herramienta para
explorar la relacin entre las matrices de transformacin y la interpretacin
geomtrica de las transformaciones.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestTransform extends Applet implements ActionListener {
public static void main(String[] args) {
new MainFrame(new TestTransform(), 640, 300);
}
TransformGroup trGroup;
Transform3D transform = new Transform3D();
MatrixPanel mp = new MatrixPanel();
TextField rx = new TextField();
TextField ry = new TextField();
TextField rz = new TextField();
TextField ra = new TextField();
TextField tx = new TextField();
TextField ty = new TextField();
TextField tz = new TextField();
TextField sx = new TextField();
TextField sy = new TextField();
TextField sz = new TextField();
public void init() {
setLayout(new BorderLayout());

68

Panel eastPanel = new Panel();


eastPanel.setLayout(new BorderLayout());
eastPanel.add(mp, BorderLayout.NORTH);
add(eastPanel, BorderLayout.EAST);
Button button = new Button("Transform");
button.addActionListener(this);
Panel p = new Panel();
p.add(button);
eastPanel.add(p, BorderLayout.EAST);
p = new Panel();
p.setLayout(new GridLayout(4,5));
p.add(new Label("x"));
p.add(new Label("y"));
p.add(new Label("z"));
p.add(new Label("angle"));
p.add(new Label(""));
p.add(rx);
p.add(ry);
p.add(rz);
p.add(ra);
button = new Button("Rotate");
button.addActionListener(this);
p.add(button);
p.add(tx);
p.add(ty);
p.add(tz);
p.add(new Panel());
button = new Button("Translate");
button.addActionListener(this);
p.add(button);
p.add(sx);
p.add(sy);
p.add(sz);
p.add(new Panel());
button = new Button("Scale");
button.addActionListener(this);
p.add(button);
eastPanel.add(p, BorderLayout.SOUTH);
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
trGroup = new TransformGroup();
trGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(trGroup);
//object
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Group shape = new Axes();
Transform3D tr = new Transform3D();
tr.setScale(0.5);
TransformGroup tg = new TransformGroup(tr);
trGroup.addChild(tg);
tg.addChild(shape);
//background and light
BoundingSphere bounds = new BoundingSphere();

69

Background background = new Background(1.0f, 1.0f, 1.0f);


background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green), new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange), new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
public void actionPerformed(ActionEvent e) {
Matrix4d m = new Matrix4d();
mp.get(m);
transform.set(m);
String cmd = e.getActionCommand();
if ("Transform".equals(cmd)) {
Quat4d quat = new Quat4d();
Vector3d translation = new Vector3d();
transform.get(quat, translation);
Vector3d scale = new Vector3d();
transform.getScale(scale);
AxisAngle4d rotation = new AxisAngle4d();
rotation.set(quat);
rx.setText("" + rotation.x);
ry.setText("" + rotation.y);
rz.setText("" + rotation.z);
ra.setText("" + rotation.angle);
tx.setText("" + translation.x);
ty.setText("" + translation.y);
tz.setText("" + translation.z);
sx.setText("" + scale.x);
sy.setText("" + scale.y);
sz.setText("" + scale.z);
trGroup.setTransform(transform);
} else {
if ("Rotate".equals(cmd)) {
double x = Double.parseDouble(rx.getText());
double y = Double.parseDouble(ry.getText());
double z = Double.parseDouble(rz.getText());
double a = Double.parseDouble(ra.getText());
transform.setRotation(new AxisAngle4d(x, y, z, a));
} else if ("Translate".equals(cmd)) {
double x = Double.parseDouble(tx.getText());
double y = Double.parseDouble(ty.getText());
double z = Double.parseDouble(tz.getText());
transform.setTranslation(new Vector3d(x, y, z));
} else if ("Scale".equals(cmd)) {
double x = Double.parseDouble(sx.getText());
double y = Double.parseDouble(sy.getText());
double z = Double.parseDouble(sz.getText());
transform.setScale(new Vector3d(x, y, z));
}
transform.get(m);
mp.set(m);
}
}
}

Programa 2.9: Cdigo que muestra las caractersticas de la clase Transform3D.

70

Figura 2.17 Salida de la ejecucin del programa 2.9.

2.8 Composicin de transformaciones tridimensionales.

Dos o ms trasnformaciones pueden ser combinadas para formar una


trasnformacin compuesta. Por ejemplo si

son dos transformaciones,

entonces la transformacin de composicin est definida como:

Cabe notar que en general, la composicin de dos transformaciones no es


conmutativa:

En esta notacin las transformaciones compuestas son aplicadas de derecha a


izquierda. Por ejemplo
aplica primero a

denota la transformacin de composicin que se

, seguido por

En forma de matriz, la composicin de las transformaciones corresponde a la


multiplicacin de matriz. Si las matrices de trasnformaciones para

son

, respectivamente, entonces la matriz para la transformacin compuesta


es la matriz

La clase Transform3D incluye diversos mtodos para multiplicar matrices de


transformacin para as poder formar transformaciones compuestas.

void

mul(Transform3D

t):

multiplica

la

transformacin

con

la

transformacin actual a la derecha.

71

void mul(Transform3D t1, Transform3D t2): multiplica la transformacin t1


por t2.

void mulInverse(Transform3D t): multiplica la transformacin inversa t por


la transformacin actual de la derecha.

void

mulInverse(Transform3D

t1,

Transform3D

t2):

multiplica

la

transformacin t1 por la transformacin t2 inversa de la derecha.

void mulTransposeBoth(Transform3D t1, Transform3D t2): multiplica la


transposicin de la transformacin t1 por la transposicin de la
transformacin t2 de la derecha.

void mulTransposeLeft(Transform3D t1, Transform3D t2): multiplica la


transposicin de la transformacin t1 por la transformacin t2 de la
derecha.

void mulTransposeRight(Transform3D t1, Transform3D t2): multiplica la


transformacin t1 por la transposicin de la

transformacin t2 de la

derecha.
Cuando se desea establecer una transformacin compleja, es mucho ms sencillo
componerla de transformaciones simples, que construir su matriz directamente.
Supongamos que queremos contruir una rotacin de

sobre los ejes a travs de

(1, 1, 0) y (1, 2, 1). Debido a que los ejes no pasan por el origen, no podemos
aplicar la equacin de cuaterniones directamente. Sin embargo, podemos primero
realizar una traslacin para mover los ejes al origen, realizar la rotacin sobre los
nuevos ejes, y finalmente aplicar la traslacin inversa para enviar los ejes de
regreso a su ubicacin original. Supongamos que

es la traslacin por (-1,-1,0).

Entonces

es la rotacin de

.Y

sobre los

ejes a travs del origen y (0, 1, 1). Por lo tanto la rotacin original puede ser
descompuesta en

Este patrn de descomposicin es muy comn. Si una transformacin particular


se localiza en una posicin estndar, una transformacin similiar en una posicin
ms general puede obtenerse de la siguiente manera: primero se transforma a la

72

posicin estndar,

despus se realiza la transformacin dada en la forma

estndar y despus se transforma a su posicin original.


Consideremos otro ejemplo, en este caso de refleccin. Una matriz general de
refleccin sera difcil de construir, por lo que se tratar de reducir el problema de
a un plano

debido a que es mucho ms fcil de construir. Supongamos que el

plano de refleccin es un plano a travs del origen dado por la ecuacin:

En lugar de encontrar la matriz de transformacin directamnte, se usar una


transformacin compuesta. Primero se puede construir una rotacin para mapear
el plano de refleccin al plano

; despus se realiza la refleccin sobre el plano

y finalmente se completar la transformacin compuesta al realizar la rotacin


inversa que mapea el plano

de regreso al plano de refleccin original. La

transformacin compuesta es el equivalente de la refleccin original.


Para obtener la rotacin que mapea la refleccin del plano descrita anteriormente
al plano

, es equivalente a hacer lo siguiente: mapear el vector normal

, el vector normal para el plano

. El eje de rotacin sera

a
y la

ecuacin de cuaternin de la rotacin tendra la forma:

El ngulo de rotacin apropiado debera satisfacer la condicin:

Al denotar esta rotacin por

y la refleccin sobre el plano

por , entonces la

refleccin sobre el plano puede representarse como:

El siguiente cdigo ilustra la construccin de reflecciones utilizando este mtodo.


Un plano en una posicin general acta como un espejo para la refleccin. Un
texto en 3D est rotando en la escena y la imagen espejo sobre el plano tambin

73

se despliega. El plano se muestra en una forma semitransparente para dar un


efecto de refleccin en espejo para el objeto transformado.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class Mirror extends Applet {
public static void main(String[] args) {
new MainFrame(new Mirror(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
//object
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Font3D font = new Font3D(new Font("Serif", Font.PLAIN, 1),
new FontExtrusion());
Shape3D shape = new Shape3D(new Text3D(font, "Java"), ap);
//translation
Transform3D trans = new Transform3D();
trans.setTranslation(new Vector3d(-0.5,0,0));
TransformGroup transg = new TransformGroup(trans);
transg.addChild(shape);
//rotation
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spin.addChild(transg);
//scaling, translation
Transform3D tr = new Transform3D();
tr.setScale(0.25);
tr.setTranslation(new Vector3d(0.5,0,0));
TransformGroup tg = new TransformGroup(tr);
tg.addChild(spin);
//shared group
SharedGroup share = new SharedGroup();
share.addChild(tg);
//link leaf nodes to shared group
Link link1 = new Link(share);
Link link2 = new Link(share);
//reflection
Transform3D reflection = getReflection(1,1,1);
TransformGroup reflectionGroup = new TransformGroup(reflection);
reflectionGroup.addChild(link2);
//the mirror
QuadArray qa = new QuadArray(4, QuadArray.COORDINATES);
qa.setCoordinate(0, new Point3d(0,-0.5,0.5));
qa.setCoordinate(1, new Point3d(1,-0.5,-0.5));
qa.setCoordinate(2, new Point3d(0,0.5,-0.5));
qa.setCoordinate(3, new Point3d(-1,0.5,0.5));
ap = new Appearance();
ap.setTransparencyAttributes(

74

new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.7f));


Shape3D mirror = new Shape3D(qa, ap);
//rotator
Alpha alpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
//background and lights
Background background = new Background(0.5f, 0.5f, 0.5f);
background.setApplicationBounds(bounds);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
//branch group
BranchGroup root = new BranchGroup();
root.addChild(link1);
root.addChild(reflectionGroup);
root.addChild(mirror);
root.addChild(rotator);
root.addChild(background);
root.addChild(light);
root.addChild(ptlight);
root.addChild(ptlight2);
return root;
}
static Transform3D getReflection(double a, double b, double c) {
Transform3D transform = new Transform3D();
double theta = Math.acos(c/Math.sqrt(a*a+b*b+c*c));
double r = Math.sqrt(a*a+b*b);
Transform3D rot = new Transform3D();
rot.set(new AxisAngle4d(b/r, -a/r, 0, theta));
Transform3D ref = new Transform3D();
ref.setScale(new Vector3d(1,1,-1));
transform.mulInverse(rot);
transform.mul(ref);
transform.mul(rot);
return transform;
}
}

Programa 2.10: Cdigo que muestra la construccin de reflecciones.

Figura 2.18 Salida de la ejecucin del programa 2.10.

75

MODELADO
GEOMTRICO

3.1 Modelos geomtricos.


Los grficos utilizados para construir graficos en 3D son los objetos con formas
visuales. Constituyen los objetos visibles en una escena renderizada. Un objeto
con forma est definido por su geometra y apariencia. La geometra proporciona
la descripcin matemtica de la forma, tamao y otras propiedades estructurales
del objeto. La apariencia define el color, textura, material y otros atributos del
objeto.

76

La geometra de un objeto visual puede ser construidoa de un conjunto de objetos


simples tales como los triangulos. A otros objetos ms complejos como los cubos
y esferas que estn preconstruidos y pueden ser reutilizados se les conoce como
figuras primitivas. Las figuras primitivas proporcionan un nivel de abstraccin que
simplificar la construccin de muchos objetos complejos. Los objetos de texto
basados en fuentes proporcionan otra fuente de objetos geomtricos. Tanto los
objetos de texto 2D como 3D son elementos tiles para una escena grfica en 3D.
Java 3D proporciona la clase Shape3D que representa la forma de los objetos. La
geometra y apariencia de un nodo Shape3D estn definidas al hacer referencia a
objetos del tipo Geometry y Appearance. La clase Geometry tiene subclases que
ayudan a definir varios tipos de figuras geomtricas de diferentes maneras. La
clase Appearance contiene referencias a varios atributos de los objetos que
definen diferentes aspectos de su apariencia. Comunmente se utilizan las
primitivas como cubos, esferas, cilindros y conos los cuales son proporcionados
por Java 3D. Java 3D proporciona adems el soporte necesario para utilizar texto
en 2D y 3D como objetos geomtricos.
El modelado geomtrico empieza con el modelado de un punto. Para representar
los puntos en las computadoras, se utiliza un concepto algebraico conocido como
vector y espacios de vector. Un vector de

dimensin es una tupla de

nmeros:

La coleccin de todos los


dimensional
vector 3D
un vector 4D

vectores dimensionales forma el

espacio

. En un espacio 3D, un punto puede ser representado por un


; utilizando coordenadas homogneas un punto est asociado a
.

Existe un concepto geomtrico de vectores que representa cantidades con


direcciones. Ejemplos de tales vectores incluyen la direccin de la lnea, la fuerza,
velocidad y aceleracin. Un vector geomtrico tambin es representado como una
-tupla. Algebraicamente no hay distincin entre un punto geomtrico y un vector

77

geomtrico; la diferencia existe solo en la interpretacn general de las cantidades


matemticas.
En los grficos 3D la construccin y transformacin geomtricas dependen
enormemente de la notacin matemtica de vectores. Java proporciona un gran
conjunto de clases que representan puntos, vectores y matrices en el paquete
javax.vecmath; este paquete contiene muchas variaciones de clases de vectores
y matrices.
Las figuras geomtricas bsicas de objetos 3D son modelados como puntos,
lneas y superficies. Los puntos y lneas (incluyendo las curvas) son relativamente
simples de definir debido a que son usuamente extensiones que corresponden a
modelos 2D. Los modelos de superficies en 3D presentan algunos retos reales; es
decir los objetos solidos 3D pueden usualmente ser modelados como superficies.
Matemticamente una superficie puede ser representada por una ecuacin
implcita en las coordenadas:

Alternativamente, es usualmente ms conveniente utilizar una ecuacin


paramtrica con dos parmetros para realizar aplicaciones grficas como se
muestra a continuacin:

Debido a la complejidad que involucra el representar una superficie 3D, es


necesario utilizar una coleccin de superficies ms simples. Una representacin
comnmente utilizada es una malla de polgonos simples, tales como tringulos y
cuadrilteros. Otra representacin para las superficies 3D son las superfices
polinomiales y spline. La figura 3.1 muestra un ejemplo de mallas de polgonos
representando una superficie.

78

Figura 3.1: Esfera representada por mallas de tringulos de diferentes resoluciones.

Java 3D ofrece soporte directo para arreglos de puntos, lneas y tringulos o


cuadrilteros como herramientas bsicas para las construcciones geomticas. En
Java 3D, un objeto visual es comnmente representado por Shape3D. Los objetos
de este tipo hacen referencia a objetos de Geometry los cuales definen la forma y
otras caractersticas. Shape3D tambin hace referencia a los objetos del tipo
Appearance que definen la apariencia en el renderizado.
La clase Geometry es una clase abstracta con un gran nmero de descendientes.

Figura 3.2: Jerarqua de clases de Geometry.

A continuacin se presentarn algunas de estas clases.


GeometryArray es la familia de clases que proporcionan las facilidades para
construir directamente figuras geomtricas con arreglos de polgonos, lneas o

79

puntos. Define los vrtices que especifican la relacin estructural entre los
vrtices.
En un objeto del tipo GeometryArray las definiciones para los vrtices siempre
incluyen coordenadas, aunque tambin pueden incluir otro tipo de datos como
superficies normales y colores.
Normalmente un objeto de la familia GeometryArray es creado al llamar al
constructor apropiado con los datos especificados y los tamaos de los arreglos.
Los datos del vrtice son establecidos con llamadas a mtodos. GeometryArray
proporciona una variedad de mtodos para establecer las coordenadas y otros
datos. Por ejemplo, una coordenada puede establecerse individualmente o a
travs de un arreglo de coordenadas:
void setCoordinate(int index, Point3f coord.)
void setCoordinates(int startIndex, Point3f[ ] cords)
La clase PointArray define la geometra consistente de un conjunto de puntos.
Cada vrtice corresponde un punto en la figura. Por ejemplo el siguiente
fragmento de cdigo define tres puntos:
PointArray pa = new PointArray(3, GeometryArray.COORDINATES);
pa.setCoordinate(0, new Point3f(0f, 0f, 0f));
pa.setCoordinate(1, new Point3f(1f, 0f, 0f));
pa.setCoordinate(3, new Point3f(0f, 1f, 0f));

Figura 3.3: Geometra de un PointArray.

80

La clase LineArray define segmentos de lnea. Cada dos vrtices especificados


secuencialmente corresponden al segmento de lnea como se ve en el siguiente
fragmento de cdigo:
LineArray la = new LineArray(6, GeometryArray.COORDINATES);
Point3f[ ] coords = new Point3f[6];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 1f, 0f);
cords[2]= new Point3f(1f, 0f, 0f);
cords[3]= new Point3f(2f, 1f, 0f);
cords[4]= new Point3f(2f, 1f, 0f);
cords[5]= new Point3f(3f, 0f, 0f);
la.setCoordinates(0, coords);

Figura 3.4: Geometra de un LineArray.

La clase TriangleArray define la superfice consistente en arreglos de trangulos,


cada tres vrtices definen un triangulo. El siguiente fragmento de cdigo define un
objeto geomtrico conformado por dos triangulos:
TriangleArray ta = new TriangleArray(6, GeometryArray.COORDINATES);
Point3f[ ] coords = new Point3f[6];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 1f, 0f);
cords[2]= new Point3f(1f, 0f, 0f);
cords[3]= new Point3f(2f, 1f, 0f);
cords[4]= new Point3f(2f, 1f, 0f);
cords[5]= new Point3f(3f, 0f, 0f);
ta.setCoordinates(0, coords);

81

Figura 3.5: Geometra de un TriangleArray.

La geometra de un cono puede estr definido como una serie de tringulos que
utilizan TriangleArray como se muestra en el siguiente fragmento de cdigo:
int n=0; //numero de parches de triangulo
TriangleArray ta = new TriangleArray(3*n,
GeometryArray.COORDINATES);
Point3f apex = new Point3f(0, 0, 1);
Point3f p1 = new Point3f(1, 0,0);
int count = 0;
for (int i=1; i<=n; i++){
float x = (float)Math.cos(i*2*Math.PI/n);
float y = (float)Math.sin(i*2*Math.PI/n);
Point3f p2 = new Point3f(x, y, 0);
ta.setCoordinate(count++, apex);
ta.setCoordinate(count++, p1);
ta.setCoordinate(count++, p2);
p1=p2;
}
La base circular del cono est dividida en

segmentos. Los dos puntos de cada

segmento son las puntas que forman el triangulo. Debido a que TriangleArray
requiere de especificaciones explcitas de cada vrtice en cada triangulo, es
necesario definir

coordenadas, aunque haya solo

puntos distintivos.

La clase QuadArray define la superficie de arreglos de cuadrilteros. Cada cuatro


secuencias de vrtices definen el cuadriltero. Los cuatro vrtices son necesarios

82

que se encuentren en el plano. El siguiente fragmento de cdigo consiste en dos


cuadrados que no estn en el mismo plano, pero los vrtices de cada uno se
encuentran en el mismo plano:
QuadArray qa = new QuadArray(8, GeometryArray.COORDINATES);
Point3f[ ] coords = new Point3f[8];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 0f, 0f);
cords[2]= new Point3f(1f, 1f, 0f);
cords[3]= new Point3f(0f, 1f, 0f);
cords[4]= new Point3f(1f, 1f, 0f);
cords[5]= new Point3f(0f, 1f, 0f);
cords[6]= new Point3f(0f, 1f, 1f);
cords[7]= new Point3f(1f, 1f, 1f);
qa.setCoordinates(0, coords);

Figura 3.6: Geometra de un QuadArray.

Cabe mencionar que aunque solo hay seis puntos distintivos en la figura, se
necesitan definir los ocho vrtices del objeto debido a que es necesario
especificar cada figura con cuatro vrtices.
Comnmente los vrtices en un arreglo son compartidos por diversos polgonos
diferentes. Utilizando el TriangleArray o el QuadArray se pueden agregar los
vrtices compartidos mltiples veces. La clase GeometryStripArray usa la idea de
franjas para permitir compartir los vrtices adyacentes. Para definir franjas
separadas, el nmero de vrtices de cada una de ellas debe estr especificado
por un arreglo de enteros:
void setStripVertexCounts(int[ ] stripVertexCounts);

83

La longitud de cada arreglo es el nmero de franjas; y la cantidad introducida en


cada posicin del arreglo representa el nmero de vrtices de la franja.
GeometryStripArray tiene tres subclases. LineStripArray que define una franja
como polilnea. Se utiliza una secuencia de puntos para especificar las franjas sin
duplicar los puntos internos. El siguiente fragmento de cdigo define la misma
figura presentada con LineArray en la figura 3.3,

pero utilizando el objeto

LineStripArray:
int[ ] stripVertexCounts = {2, 3};
LineStripArray lsa = new LineStripArray(5, GeometryArray.COORDINATES,
stripVertexCounts);
Point3f[ ] coords = new Point3f[5];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 1f, 0f);
cords[2]= new Point3f(1f, 0f, 0f);
cords[3]= new Point3f(2f, 1f, 0f);
cords[4]= new Point3f(3f, 0f, 0f);
lsa.setCoordinates(0, coords);
La clase TriangleStripArray define franjas de tringulos. En cada franja, cada tres
vrtices consecutivos definen el tringulo, la siguiente figura ilustra una figura
construida utilizando un objeto TriangleStripArray con conteo de franjas de
vrtices (5, 4):

Figura 3.7: Representacin de un TriangleStripArray.

La clase TriangleFanArray ofrece una alternativa para definir franjas de tirangulos.


En cada franja el primer vrtice con dos vrtices consecutivos definen el trangulo

84

La siguiente figura muestra un objeto de esta clase con conteo de franjas de


vrtices (5, 4):

Figura 3.8: Representacin de un TriangleFanArray.

Un cono puede estr denifido por varios TriangleFanArray como se muestra en el


cdigo:
int n=0; //numero de parches;
int[ ] stripVertexCounts = {n+2} //un strip
TriangleFanArray tfa = new TriangleFanArray(n+2,
GeometryArray.COORDINATES, stripVertexCounts);
Point3f apex = new Point3f(0, 0, 1);
tfa.setCoordinate(0, apex);
for (int i=1; i<=n; i++){
float x = (float)Math.cos(i*2*Math.PI/n);
float y = (float)Math.sin(i*2*Math.PI/n);
Point3f p = new Point3f(x, y, 0);
tfa.setCoordinate(i+1, p);
}
Los

arreglos de tringulos estn definidos por

puntos en cada franja.

Para evitar los vrtices duplicados se utiliza IndexedGeometryArray. En lugar de


definir un polgono especificando los vrtices directamente, un objeto de este tipo
especifica los ndices de los vrtices en el arreglo de puntos. Consecuentemente
los vrtices necesitan definirse solo una vez, pero pueden ser referenciados
varias veces a travs de sus ndices. Por ejemplo, el siguiente segmento de
cidgo define una figura de dos cuadros. Solo utiliza seis vrtices en lugar de

85

ocho como se ocupaba con el GeometryArray. Cada figura est especificada por
sus cuatro ndices correspondientes a los vrtices de sus esquinas:
IndexedQuadArray iqa = new IndexedQuadArray(6,
GeometryArray.COORDINATES, 8);
Point3f[ ] coords = new Point3f[6];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 0f, 0f);
cords[2]= new Point3f(1f, 1f, 0f);
cords[ 3]= new Point3f(0f, 1f, 0f);
cords[4]= new Point3f(0f, 1f, 1f);
cords[5]= new Point3f(1f, 1f, 1f);
iqa.setCoordinates(0, coords);
int[ ] indices = {0, 1, 2, 3, 4, 5};
iqa.setCoordinateIndices(0, indices);
Tambien existe

la

clase IndexedGeometryStripArray con sus subclases

IndexedLineStripArray, IndexedTriangleStripArray, e IndexedTriangleFanArray.


Estas clases agregan ndices al arreglo de franjas y combinan sus caractersticas.
Para definir franjas separadas, necesita especificarse en el constructor un arrego
stripIndex a travs del siguiente mtodo:
void setStripIndexCounts(int[ ] stripIndexCounts)
El siguiente cdigo construye un tetraedro regular utilizando la clase
IndexedTriangleArray. El tetraedro es uno de los cinco poliedros conocidos como
solidos Platnicos. Un tetraedro consiste en cuatro caras de tringulos
equilteros.
import javax.vecmath.*;
import javax.media.j3d.*;
public class Tetrahedron extends IndexedTriangleArray {
public Tetrahedron() {
super(4, TriangleArray.COORDINATES | TriangleArray.NORMALS, 12);
setCoordinate(0, new Point3f(1f,1f,1f));
setCoordinate(1, new Point3f(1f,-1,-1f));
setCoordinate(2, new Point3f(-1f,1f,-1f));
setCoordinate(3, new Point3f(-1f,-1f,1f));
int[] coords = {0,1,2,0,3,1,1,3,2,2,3,0};
float n = (float)(1.0/Math.sqrt(3));
setNormal(0, new Vector3f(n,n,-n));
setNormal(1, new Vector3f(n,-n,n));
setNormal(2, new Vector3f(-n,-n,-n));

86

setNormal(3, new Vector3f(-n,n,n));


int[] norms = {0,0,0,1,1,1,2,2,2,3,3,3};
setCoordinateIndices(0, coords);
setNormalIndices(0, norms);
}
}

Programa 3.1: Cdigo que construye un tetraedro regular.

El siguiente programa despliega el tetraedro creado en el cdigo anterior rotando


en el espacio para que sea visto desde diferentes ngulos:
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestTetrahedron extends Applet {
public static void main(String[] args) {
new MainFrame(new TestTetrahedron(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
//object
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Shape3D shape = new Shape3D(new Tetrahedron(), ap);
//rotating object
Transform3D tr = new Transform3D();
tr.setScale(0.25);
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
tg.addChild(shape);
Alpha alpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//light and background
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);

87

root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
}

Programa 3.2: Cdigo que despliega un tetraedro en rotacin.

Figura 3.9: Salida de la ejecucin del programa 3.2.

Java 3D ofrece clases tiles para las primitivas geomtricas ms utilizadas. La


clase abstracta Primitive es una subclase de Group y encapsula los atributos
geomtricos predefinidos.
La siguiente figura muestra la jerarqua de clase de las primitivas definidas en el
paquete com.sun.j3d.utils.geometry. La apariencia de la primitiva puede
establecerse a travs de los siguientes mtodos:
void setAppearance();
void setAppareance(Appearance appearance)
void setAppearance(int subpart, Appearance appearance)

Figura 3.10: Subclases de la clase Primitive.

88

El tamao de las primitivas puede establecerse con algunos de sus constructores


por ejemplo:
Box(float xdim, float ydim, float zdim, Appearance appearance)
Cone(float radius, float height)
Cylinder(float radius, float height)
Sphere(float radius)
La clase Primitive es una subclase de Group, por lo tanto un objeto primitivo
puede agregarse directamente a una escena.
El siguiente cdigo muestra una aplicacin de primitivas. El programa despliega
instancias de las cuatro primitivas bsicas proporcionadas por Java 3D.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestPrimitives extends Applet {
public static void main(String[] args) {
new MainFrame(new TestPrimitives(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
//primitives
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Box box = new Box(1.2f, 0.3f, 0.8f, ap);
Sphere sphere = new Sphere();
Cylinder cylinder = new Cylinder();
Cone cone = new Cone();
Transform3D tr = new Transform3D();
tr.setScale(0.2);
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
tg.addChild(box);
tr.setIdentity();

89

tr.setTranslation(new Vector3f(0f,1.5f,0f));
TransformGroup tgSphere = new TransformGroup(tr);
tg.addChild(tgSphere);
tgSphere.addChild(sphere);
tr.setTranslation(new Vector3f(-1f,-1.5f,0f));
TransformGroup tgCylinder = new TransformGroup(tr);
tg.addChild(tgCylinder);
tgCylinder.addChild(cylinder);
tr.setTranslation(new Vector3f(1f,-1.5f,0f));
TransformGroup tgCone = new TransformGroup(tr);
tg.addChild(tgCone);
tgCone.addChild(cone);
Alpha alpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//background and light
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
}

Programa 3.3: Cdigo que despliega las cuatro primitivas bsicas en rotacin.

Figura 3.11: Salida de ejecucin del programa 3.3.

3.2 Proyecciones.

Es posible realizar vistas de una escena 3D con una imagen 2D a travs de una
transformacin llamada proyeccin. Existen dos tipos de proyecciones: la

90

proyeccin paralela y la proyeccin de perspectiva. En cada caso un plano


conocido como plano vista es colocado en un mundo virtual. Las proyecciones
mapean los puntos en el mundo virtual del plano. Solo una ventana finita
(usualmente rectangular) en el plano de vista ser utilizada para imgenes
renderizadas. A esta ventana se le llama placa de vista y es anloga a un
fotograma de una pelcula en una cmara ordinaria. Solo necesitan calcularse los
puntos del espacio 3D que proyectan la vista de la placa. Los puntos muy
cercanos o muy alejados del usuario tambin se excluyen; lo que da como
resultado un volumen finito en un espacio 3D que participar en la proyeccin.
Dicho volumen es conocido como vista frustum.
Una proyeccin paralela proyecta los puntos 3D en el plano vista a travs de
lneas paralelas en una direccin fija. Cuando las lneas de la proyeccin son
perpendiculares a la vista del plano, la proyeccin paralela se conoce como
ortogrfica. Tres proyecciones ortogrficas sobre los tres ejes son conocidas
como elevacin frontal, elevacin superior y elevacin lateral. La vista del
volumen de una proyeccin paralela es un paralelograma.
La siguiente figura muestra una proyeccin paralela:

Figura 3.12: Proyeccin paralela.

Las formulas para las proyecciones paralelas son relativamente simples.


Supongamos que la vista del plano es sobre el plano
direccin del eje
mapeado al punto

. Entonces un punto

y la proyeccin es en

en el espacio es simplemente

en un plano de vista 2D. La transformacin est dada por

la matriz:

91

Comunmente es recomendable retener la informacin de las coordenadas


mientras se realiza la proyeccin. Por lo tanto la proyeccin paralela es
esencialmente la identidad de la transformacin:

En la proyeccin de perspectiva, todas las lneas de proyeccin convergen en el


punto de vista (la posicin del ojo del espectador). Los objetos que estn ms
cercanos a el aparecern ms grandes que los que estn ms alejados. Este
modo asemeja la proyeccin del ojo humano en cmaras regulares.

Figura 3.13: Proyeccin perspectiva.

Las frmulas matemticas de la proyeccin perspectiva son ms complejas.


Asumamos que el plano de vista es el plano

y el ojo est en

hacia abajo en el eje de las , siendo el eje

la vista desde arriba. Como se

viendo

muestra en la siguiente figura:

92

Figura 3.14: Ejemplo de proyeccin perspectiva.

Considerando los dos triangulos similares, se tiene que:

O lo que es lo mismo:

Similarmente, en la direccin de :

Por lo tanto la transformacin no es lineal en el espacio 3D. Sin embargo, puede


expresarsen en una forma lineal con las coordenadas homogneas como se
muestra a continuacin:

Si la coordenada

es retenida, entonces la transformacin se convierte en:

Al utilizar coordenadas homogneas y matrices de transformacin 4 x 4, las


proyecciones paralelas y de perspectiva pueden ser tratadas uniformemente.

93

Ambos tipos son transformaciones proyectivas y pueden ser representadas por


matrices 4 x 4 si

Esta matriz se

se aproxima al infinito como se muestra a continuacin:

convierte en la matriz de proyeccin paralela descrita

anteriormente. Una proyeccin paralela puede ser resguardada como un caso


especial de proyeccin de perspectiva con los puntos de vista al infinito. Los
puntos de vista de la proyeccin de perspectiva tienen coordenadas
cordenadas homogneas
aproxima a

. Mientras que

, el punto de vista se

un punto al infinito en una coordenada homognea.

3.2.1 El modelo de vistas.


Java 3D proporciona un sistema de vistas muy verstil que soporta ajustes
dinmicos basados en los cambios del ambiente as como la tradicional cmara
esttica basada en vistas. Las clases que estn directamente relacionadas con
las

vistas

son:

ViewPlatform,

View,

PhysicalBody,

PhysicalEnvironment,

Canvas3D, Screen3D.
Un objeto ViewPlatform define la presencia de la vista en un mundo virtual. Este
objeto puede atravesar una cadena de transformaciones y eventualmente ser
adjuntado al objeto del tipo Locale. El TransformGroup define la transformacin de
vista de la plataforma que determina principalmente la posicin y orientacin de la
vista, o la matriz de vista. La clase Transform3D tiene un mtodo que ayuda a
construir la transformacin:
void lookAt(Point3d eye, Point3d look, Vector3d up)
La transformacin es contruida para posicionar el ViewPlatform para que el ojo se
coloque en el punto dado, viendo hacia el centro especificado y con la direccin
dada hacia arriba en la placa de vista. La inversin de la transformacin definida

94

por el mtodo puede ser colocada en TransformGroup sobre ViewPlatform para


realizar el posicionamiento especificado en ViewPlatform.
El objeto View es el corazn del sistema de vista; define la configuracin principal
de la vista con propiedades como el tipo de proyeccin y el volumen de vista (la
matriz de proyeccin de la vista). Tambin puede acomodar cambios dinmicos
en los parmetros de la vista a travs de sus conecciones con los objetos
PhysicalBody y PhysicalEnvironment. Los mtodos de la clase View para
establecer el volumen de vista o la matriz de proyeccin son:
void setFieldOfView(double fov)
void setFrontClipDistance(double d)
void setBackClipDistance(double d)
void setProjectionPolicy(int projection)
Los objetos PhysicalBody y PhysicalEnvironment proporcionan soporte para
calibraciones automticas con sistemas dinmicos de vista. El PhysicalBody
describe las caractersticas fsicas del cuerpo o cabeza del usuario.

El

PhysicalEnvirontment contiene la informacin sobre el ambiente fsico del usuario.


La clase Canvas3D es una subclase de la clase AWT Canvas y puede colocarse
en un contenedor AWT. Un objeto de este tipo representa la superficie
renderizada. El siguiente constructor es tpicamente utilizado para construir un
objeto Canvas3D:
public Canvas3D(GraphicsConfiguration gc)
Se debe definir una clase separada Screen3D para describir los dispositivos de
visualizacin, sta clase es referenciada por un objeto del tipo Canvas3D. La
separacin de la descripcin de dispositivos evita la duplicacin de la misma
informacin en mltiples objetos Canvas3D. La clase Screen3D no tiene
constructor pblico, y sus instancias pueden llamarse a travs del mtodo
getScreen3D de la clase Canvas3D.

95

3.2.2 Modo de Compatibilidad.


Java 3D tambin ofrece un modo de vista de compatibilidad; para permitir este
modo, se puede utilizar el siguiente objeto del tipo View:
public void setCompatibilityModeEnable(boolean enabled)
La clase Transform3D contiene mtodos para construir la matriz de vista y la
matriz de proyeccin. La matriz de vista puede construirse a partir del siguiente
mtodo:
public void lookAt(Point3d eye, Point3d look, Vector3d up)
La matriz de proyeccin puede construirse con uno de los siguientes mtodos:
public void perspective(double fov, double aspect, double near, double far).
Public void frustum(double left, double right, double bottom, double top,
double near, double far)
Public void ortho(double left, double right, double bottom, double top,
double near, double far)
Las coordenadas en estos mtodos son relativas a la posicin del ojo. El mtodo
perspective define una matriz de proyeccin de perspectiva al especificar el
campo horizontal de la vista, la relacin de aspecto, y los planos cercanos y
lejanos. Los

mtodos frustum y ortho definen la matriz de proyeccin

al

especificar las coordenadas de las esquinas de la vista del volumen. El mtodo


frustum define una proyeccin de perspectiva y el ortho una de paralela.
Por ejemplo las siguientes llamadas definen la misma proyeccin de perspectiva:
perspective(Math.PI/2, 2, 1, 2);
frustum(-1, 1, -0.5, 0.5, 1, 2)
El volumen de vista tiene un campo horizontal de vista de

y una relacin de

aspecto de 2.0. La distancia del plano ms cercano es 1 y del ms lejano 2. El


plano cercano es de 2 x 1 y el lejano de 4 x 2. Asumiendo que el plano cercano es
la placa de vista la proyeccin puede representarse como:

96

La matriz de proyeccin para dicha proyeccin est dada por:

La matriz de proyeccin construida apropiadamente y la matriz de vista pueden


establecerse con los siguientes mtodos de View:
public void setVpcToEc(Transform3D viewingMatrix)
public void setLeftProjection(Transform3D projectionMatrix)
public void setRightProjection(Transform3D projectionMatrix)
En el modo de compatibilidad, virtualmente todos los parmetros son establecidos
por un objeto View. Por otro lado en el modo de vista estndar (sin
compatibilidad), las especificaciones de la vista final pueden ser influenciadas por
otros objetos tales como PhysicalBody y PhysicalEnvironment. Los mtodos
descritos anteriormente no son vlidos para el modo de incompatibilidad. El modo
de compatibilidad es un modo restringido y no presenta todas las caractersticas
de la vista de Java 3D.
El siguiente cdigo muestra un tetraedro y utiliza vistas de modo de
compatibilidad construidas manualmente.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;

97

public class CompatibilityMode extends Applet {


public static void main(String[] args) {
new MainFrame(new CompatibilityMode(), 640, 650);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
VirtualUniverse universe = new VirtualUniverse();
Locale locale = new Locale(universe);
BranchGroup bg = createView(cv);
locale.addBranchGraph(bg);
bg = createContent();
bg.compile();
locale.addBranchGraph(bg);
}
private BranchGroup createView(Canvas3D cv) {
BranchGroup bg = new BranchGroup();
ViewPlatform platform = new ViewPlatform();
bg.addChild(platform);
View view = new View();
view.addCanvas3D(cv);
view.setCompatibilityModeEnable(true);
view.attachViewPlatform(platform);
Transform3D projection = new Transform3D();
projection.frustum(-0.1, 0.1, -0.1, 0.1, 0.2, 10);
view.setLeftProjection(projection);
Transform3D viewing = new Transform3D();
Point3d eye = new Point3d(0,0,1);
Point3d look = new Point3d(0,0,-1);
Vector3d up = new Vector3d(0,1,0);
viewing.lookAt(eye, look, up);
view.setVpcToEc(viewing);
PhysicalBody body = new PhysicalBody();
view.setPhysicalBody(body);
PhysicalEnvironment env = new PhysicalEnvironment();
view.setPhysicalEnvironment(env);
return bg;
}
private BranchGroup createContent() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
//object
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Shape3D shape = new Shape3D(new Tetrahedron(), ap);
//rotating object
Transform3D tr = new Transform3D();
tr.setScale(0.25);
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
tg.addChild(shape);
Alpha alpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//light and background
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);

98

root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
}

Programa 3.4: Cdigo que muestra un tetraedro y utiliza vistas en modo de compatibilidad.

Figura 3.15: Salida de la ejecucin del programa 3.4.

3.2.3 Configuracin de vista.


La clase SimpleUniverse divide los componentes de los objetos relacionados en
dos clases: la clase Viewer y la ViewingPlatform. Un objeto Viewer consiste en un
objeto

View,

un

PhysicalEnvironment

objeto
y

un

ViewAvatar,
conjunto

de

un

objeto

objetos

PhysicalBody,

Canvas3D.

El

un

objeto

ViewingPlatform contiene un objeto ViewPlatform y un objeto MultiTransform que


contiene una serie de nodos del tipo TransformGroup que estn relacionados. Los
constructores de SimpleUniverse son:
SimpleUniverse(int numTrans)
SimpleUniverse(Canvas3D canvas, int numTrans)
Se puede obtener el View de un objeto SimpleUniverse con la siguiente sentencia:
View view = su.getViewer().getView();

99

As mismo, para obtener el nodo TransformGroup sobre el ViewPlatform, se


deben realizar las siguientes llamadas a mtodos:
TransformGroup tg = su.getViewingPlatform().getViewPlatformTransform();
Para obtener un TransformGroup especfico en el objeto MultiTransformGroup, se
hace la siguiente llamada:
TransformGroup tg = su.getViewingPlatform().getMultiTransformGroup().
getTransformGroup(idx);
El siguiente cdigo muestra una aplicacin de SimpleUniverse y sus efectos al
controlar vistas estndares de Java3D. Este ejemplo despliega un dodecaedro, en
su posicin fija. Sin embargo la vista se establece en el eje de rotacin

permitiendo al usuario ver los diferentes lados de la figura.


import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.geometry.*;
public class Dodecahedron extends Shape3D{
public Dodecahedron() {
GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
double phi = 0.5*(Math.sqrt(5)+1);
Point3d[] vertices = {new Point3d(1,1,1),
new Point3d(0,1/phi,phi),new Point3d(phi,0,1/phi),new Point3d(1/phi,phi,0),
new Point3d(-1,1,1),new Point3d(0,-1/phi,phi),new Point3d(1,-1,1),
new Point3d(phi,0,-1/phi),new Point3d(1,1,-1),new Point3d(-1/phi,phi,0),
new Point3d(-phi,0,1/phi),new Point3d(-1,-1,1),new Point3d(1/phi,-phi,0),
new Point3d(1,-1,-1),new Point3d(0,1/phi,-phi),new Point3d(-1,1,-1),
new Point3d(-1/phi,-phi,0),new Point3d(-phi,0,-1/phi),new Point3d(0,-1/phi,-phi),
new Point3d(-1,-1,-1)};
int[] indices = {0,1,5,6,2, 0,2,7,8,3, 0,3,9,4,1,
1,4,10,11,5, 2,6,12,13,7, 3,8,14,15,9,
5,11,16,12,6, 7,13,18,14,8, 9,15,17,10,4,
19,16,11,10,17, 19,17,15,14,18, 19,18,13,12,16};
gi.setCoordinates(vertices);
gi.setCoordinateIndices(indices);
int[] stripCounts = {5,5,5,5,5,5,5,5,5,5,5,5};
gi.setStripCounts(stripCounts);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
this.setGeometry(gi.getGeometryArray());
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class RotateView extends Applet {

100

public static void main(String[] args) {


new MainFrame(new RotateView(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
SimpleUniverse su = new SimpleUniverse(cv, 2);
su.getViewingPlatform().setNominalViewingTransform();
BranchGroup bg = createSceneGraph(su.getViewingPlatform().
getMultiTransformGroup().getTransformGroup(0));
bg.compile();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph(TransformGroup vtg) {
BranchGroup root = new BranchGroup();
//object
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Shape3D shape = new Dodecahedron();
shape.setAppearance(ap);
Transform3D tr = new Transform3D();
tr.setScale(0.25);
TransformGroup tg = new TransformGroup(tr);
root.addChild(tg);
tg.addChild(shape);
//view rotator
Alpha alpha = new Alpha(-1, 4000);
RotationInterpolator rotator = new RotationInterpolator(alpha, vtg);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
root.addChild(rotator);
//lights
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
}

Programa 3.5: Cdigo que muestra un dodecaedro.

101

Figura 3.16: Salida de la ejecucin del programa 3.5.

3.2.4 Creacin de una vista propia.


A pesar de que SimpleUniverse proporciona maneras convenientes para construir
una amplia rama de aplicaciones en Java 3D, puede que stas no sean
adecuadas en algunos casos. Es posible crear vistas manualmente al establecer
los objetos apropiados relacionados con la vista, tales como View, ViewPlatform,
PhysicalBody, PhysicalEnvironment, etc. El siguiente fragmento de cdigo ilustra
el procedimiento para crear una vista manualmente:
View view = new View();
view.setProjectionPolicy(View.PARALLEL_PROYECTION);
ViewPlatform vp = new ViewPlatform();
view.addCanvas3D(cv);
view.attachViewPlatform(vp);
view.setPhysicalBody(new PhysicalBody());
view.setPlysicalEnvironment(new PhysicalEnvironment());
Transform3D trans = new Transform3D();
trans.lookAt(eye, center, vup);
trans.invert();
TransformGroup tg = new TransformGroup(trans);
tg.addChild(vp);
BranchGroup bgView = new BranchGoup();
bgView.addChild(tg);

102

El siguiente cdigo muestra una aplicacin con multiples vistas. El objeto, un texto
3D en rotacin, es renderizado de cuatro diferentes vistas. Una es la vista de
perspectiva estndar poporcionada por SimpleUniverse. Las otras tres son
proyecciones paralelas en las direcciones ,

y .

import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class MultipleViews extends Applet {
public static void main(String[] args) {
new MainFrame(new MultipleViews(), 640, 480);
}
public void init() {
// create 4 Canvas3D objects
this.setLayout(new GridLayout(2,2));
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
// first view: standard
Canvas3D cv = new Canvas3D(gc);
add(cv);
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
// second view: x direction
cv = new Canvas3D(gc);
add(cv);
BranchGroup bgView = createView(cv, new Point3d(2.7,0,0),
new Point3d(0,0,0), new Vector3d(0,1,0));
su.addBranchGraph(bgView);
// third view: z direction
cv = new Canvas3D(gc);
add(cv);
bgView = createView(cv, new Point3d(0, 0, 2.7),
new Point3d(0,0,0), new Vector3d(0,1,0));
su.addBranchGraph(bgView);
// fourth view: y direction
cv = new Canvas3D(gc);
add(cv);
bgView = createView(cv, new Point3d(0,2.7,0),
new Point3d(0,0,0), new Vector3d(0,0,1));
su.addBranchGraph(bgView);
// content branch
BranchGroup bg = createSceneGraph();
bg.compile();
su.addBranchGraph(bg);
}
private BranchGroup createView(Canvas3D cv, Point3d eye,
Point3d center, Vector3d vup) {
View view = new View();
view.setProjectionPolicy(View.PARALLEL_PROJECTION);
ViewPlatform vp = new ViewPlatform();
view.addCanvas3D(cv);
view.attachViewPlatform(vp);
view.setPhysicalBody(new PhysicalBody());
view.setPhysicalEnvironment(new PhysicalEnvironment());
Transform3D trans = new Transform3D();
trans.lookAt(eye, center, vup);
trans.invert();
TransformGroup tg = new TransformGroup(trans);
tg.addChild(vp);
BranchGroup bgView = new BranchGroup();
bgView.addChild(tg);

103

return bgView;
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
// object
Font3D font = new Font3D(new Font("Serif", Font.PLAIN, 1),
new FontExtrusion());
Text3D text = new Text3D(font, "Java");
Appearance ap = new Appearance();
ap.setMaterial(new Material());
Shape3D shape = new Shape3D(text, ap);
Transform3D tr = new Transform3D();
tr.setTranslation(new Vector3f(-1f, -0.25f, 0f));
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
tg.addChild(shape);
// rotator
Alpha alpha = new Alpha(-1, 24000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
// background and light
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.green),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
PointLight ptlight2 = new PointLight(new Color3f(Color.orange),
new Point3f(-2f,2f,2f), new Point3f(1f,0f,0f));
ptlight2.setInfluencingBounds(bounds);
root.addChild(ptlight2);
return root;
}
}

Programa 3.6: Cdigo que muestra un texto 3D en 4 vistas.

Figura 3.17: Salida de la ejecucin del programa 3.6.

104

3.3 Representacin tridimensional de objetos.

La transformacin es til no solo para trasnformar objetos completos, sino que


adems sirve para construir primitivas. Las primitivas geomtricas frecuetemente
presentan ciertos grados de simetra. Como resultado, algunos vrtices de las
primitivas pueden obtenerse al transformar otros vrtices.
La clase Transform3D proporciona los mtodos para aplicar la transformacin
representada por el objeto en puntos o vectores.
void transform(Point3d p)
void transform(Point3d p, Point3d pOut)
void transform(Point3f p)
void transform(Point3f p, Point3f pOut)
void transform(Vector3d v)
void transform(Vector3d v, Vector3d vOut)
void transform(Vector3f v)
void transform(Vector3f v, Vector3f vOut)
void transform(Vector4d v)
void transform(Vector4d v, Vector4d vOut)
void transform(Vector4f v)
void transform(Vector4f v, Vectorfd vOut)
Los mtodos con un parmetro transforman al punto o vector en su lugar. Los
mtodos con dos parmetros realizan transformaciones en el primero, siendo esta
una tranformacin no destructiva y guarda el resultado en el segundo parmetro.

3.3.1 Superficies de polgonos, curvas y cuadrticas.


Una forma de crear superficies 3D es el extruir o (barrer) una curva 2D a travs
del espacio. La extrusin puede ser implementada con las traslaciones.
Empezando en un punto de la curva se aplica la traslacin sobre la direccin de la

105

extrusin para generar otros puntos. Por ejemplo el siguiente cdigo de un


mtodo toma una figura 2D y realiza una extrusin sobre el eje .
// se assume que la fugura tiene una nica curva continua
Geometry extrudeShape(Shape curve, float depth) {
PathIterator iter = curve.getPathIterator(new AffineTransform());
Vector ptsList = new Vector();
float[] seg = new float[6];
float x = 0, y = 0;
float x0 = 0, y0 = 0;
while (!iter.isDone()) {
int segType = iter.currentSegment(seg);
switch (segType) {
case PathIterator.SEG_MOVETO:
x = x0 = seg[0];
y = y0 = seg[1];
ptsList.add(new Point3f(x,y,0));
break;
case PathIterator.SEG_LINETO:
x = seg[0];
y = seg[1];
ptsList.add(new Point3f(x,y,0));
break;
case PathIterator.SEG_QUADTO:
for (int i = 1; i < 10; i++) {
float t = (float)i/10f;
float xi = (1-t)*(1-t)*x + 2*t*(1-t)*seg[0] + t*t*seg[2];
float yi = (1-t)*(1-t)*y + 2*t*(1-t)*seg[1] + t*t*seg[3];
ptsList.add(new Point3f(xi,yi,0));
}
x = seg[2];
y = seg[3];
ptsList.add(new Point3f(x,y,0));
break;
case PathIterator.SEG_CUBICTO:
for (int i = 1; i < 20; i++) {
float t = (float)i/20f;
float xi = (1-t)*(1-t)*(1-t)*x + 3*t*(1-t)*(1-t)*seg[0] +
3*t*t*(1-t)*seg[2] + t*t*t*seg[4];
float yi = (1-t)*(1-t)*(1-t)*y + 3*t*(1-t)*(1-t)*seg[1] +
3*t*t*(1-t)*seg[3] + t*t*t*seg[5];
ptsList.add(new Point3f(xi,yi,0));
}
x = seg[2];
y = seg[3];
ptsList.add(new Point3f(x,y,0));
break;
case PathIterator.SEG_CLOSE:
x = x0;
y = y0;
ptsList.add(new Point3f(x,y,0));
break;
}
iter.next();
}
int n = ptsList.size();
IndexedQuadArray qa = new IndexedQuadArray(2*n,
IndexedQuadArray.COORDINATES, 4*(n-1));
Transform3D trans = new Transform3D();
trans.setTranslation(new Vector3f(0,0,depth));
for (int i = 0; i < n; i++) {
Point3f pt = (Point3f)ptsList.get(i);
qa.setCoordinate(2*i, pt);
trans.transform(pt);
qa.setCoordinate(2*i+1, pt);
}
int quadIndex = 0;
for (int i = 0; i < n-1; i++) {
qa.setCoordinateIndex(quadIndex++, 2*i);
qa.setCoordinateIndex(quadIndex++, 2*i+1);
qa.setCoordinateIndex(quadIndex++, 2*(i+1)+1);
qa.setCoordinateIndex(quadIndex++, 2*(i+1));

106

}
GeometryInfo gi = new GeometryInfo(qa);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
return gi.getGeometryArray();
}

Programa 3.7: Cdigo que muestra un mtodo que toma un objeto 2D y le aplica una extrusin.

Muchas superficies pueden obtenerse a travs de las rotaciones. Por ejemplo un


cilindro puede obtenerse al rotar una lnea, y una esfera es el resultado de rotar
un semicrculo. Un toro puede construirse al rotar un crculo sobre un eje fuera
del mismo crculo. El crculo puede obtenerse al rotar un punto. El rotar un punto
repetidamente con diferentes ngulos genera un conjunto de puntos para el
crculo. El rotar los puntos del crculo sobre diferentes ejes genera los vrtices
para el toro. Este procedimiento se ilustra en la siguiente figura:

Figura 3.18: Construccin de un toro a travs de rotaciones.

Dados un cojunto de puntos para la curva; para crear la superficie en rotacin con
franjas, se puede rotar a un ngulo

. Al aplicar sucesivamente la rotacin

de los puntos de la curva se pueden generar los vrtices para un arreglo.


El siguiente cdigo muestra la construccin de un toro via dos rotaciones
diferentes.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class Torus extends Shape3D {
public Torus(double r1, double r2) {
int m = 20;
int n = 40;
Point3d[] pts = new Point3d[m];
pts[0] = new Point3d(r1+r2, 0, 0);
double theta = 2.0 * Math.PI / m;
double c = Math.cos(theta);

107

double s = Math.sin(theta);
double[] mat = {c, -s, 0, r2*(1-c),
s, c, 0, -r2*s,
0, 0, 1, 0,
0, 0, 0, 1};
Transform3D rot1 = new Transform3D(mat);
for (int i = 1; i < m; i++) {
pts[i] = new Point3d();
rot1.transform(pts[i-1], pts[i]);
}
Transform3D rot2 = new Transform3D();
rot2.rotY(2.0*Math.PI/n);
IndexedQuadArray qa = new IndexedQuadArray(m*n,
IndexedQuadArray.COORDINATES, 4*m*n);
int quadIndex = 0;
for (int i = 0; i < n; i++) {
qa.setCoordinates(i*m, pts);
for (int j = 0; j < m; j++) {
rot2.transform(pts[j]);
int[] quadCoords = {i*m+j, ((i+1)%n)*m+j,
((i+1)%n)*m+((j+1)%m), i*m+((j+1)%m)};
qa.setCoordinateIndices(quadIndex, quadCoords);
quadIndex += 4;
}
}
GeometryInfo gi = new GeometryInfo(qa);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
this.setGeometry(gi.getGeometryArray());
}
}

Programa 3.8: Cdigo que muestra la construccin de un toro va dos rotaciones diferentes.

El siguiente cdigo despliega dos toros. Los vrtices de los toros son generados
con transformaciones y se encuentran rotando en el espacio.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestTorus extends Applet {
public static void main(String[] args) {
new MainFrame(new TestTorus(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);

108

Transform3D tr = new Transform3D();


tr.setScale(0.8);
tr.setRotation(new AxisAngle4d(1, 0, 0, Math.PI/6));
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
//object
Shape3D torus1 = new Torus(0.2, 0.5);
Appearance ap = new Appearance();
ap.setMaterial(new Material());
torus1.setAppearance(ap);
tg.addChild(torus1);
Shape3D torus2 = new Torus(0.2, 0.5);
ap = new Appearance();
ap.setMaterial(new Material());
ap.setTransparencyAttributes(
new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.5f));
torus2.setAppearance(ap);
Transform3D tr2 = new Transform3D();
tr2.setRotation(new AxisAngle4d(1, 0, 0, Math.PI/2));
tr2.setTranslation(new Vector3d(0.5,0,0));
TransformGroup tg2 = new TransformGroup(tr2);
tg.addChild(tg2);
tg2.addChild(torus2);
Alpha alpha = new Alpha(-1, 8000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//background and lights
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.blue));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white),
new Point3f(3f,3f,3f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
}

Programa 3.9: Cdigo que despliega dos toros generados con transformaciones.

Figura 3.19: Salida de la ejecucin del programa 3.9.

109

La construccin de contenidos visuales complejos normalmente involucra


transformaciones en diferentes niveles. El siguiente ejemplo despliega una flecha.
Ilustra la combinacin de transformaciones para reusar subestructuras simtricas.
import javax.vecmath.*;
import javax.media.j3d.*;
public class Arrow extends IndexedTriangleArray {
float w = 1f;
float h = 0.15f;
float d = 0.1f;
public Arrow() {
super(5, TriangleArray.COORDINATES | TriangleArray.NORMALS, 12);
Point3f[] pts = {new Point3f(0f,0f,d),
new Point3f(w,0f,0f),
new Point3f(h,h,0f),
new Point3f(h,-h,0f),
new Point3f(0f,0f,-d)};
setCoordinates(0, pts);
int[] coords = {0,1,2,0,3,1,4,1,3,4,2,1};
setCoordinateIndices(0, coords);
Vector3f v1 = new Vector3f();
v1.sub(pts[1], pts[0]);
v1.normalize();
Vector3f v2 = new Vector3f();
v2.sub(pts[2], pts[0]);
v2.normalize();
Vector3f v = new Vector3f();
v.cross(v1, v2);
setNormal(0, v);
v.y = -v.y;
setNormal(1, v);
v.z = -v.z;
setNormal(2, v);
v.y = -v.y;
setNormal(3, v);
int[] norms = {0,0,0,1,1,1,2,2,2,3,3,3};
setNormalIndices(0, norms);
}
}

Programa 3.10: Cdigo que despliega una flecha ilustrando la combinacin de transformaciones.

En el siguiente cdigo se muestra un logo en 3D con 16 flechas y un anillo


alrededor de ellas.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class Logo extends Applet {
public static void main(String[] args) {
new MainFrame(new Logo(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();

110

Canvas3D cv = new Canvas3D(gc);


setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
Transform3D tr = new Transform3D();
tr.setScale(0.9);
tr.setRotation(new AxisAngle4d(1, 0, 0, Math.PI/2));
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
//torus
Shape3D torus = new Torus(0.04, 0.6);
Appearance ap = new Appearance();
ap.setMaterial(new Material());
torus.setAppearance(ap);
tg.addChild(torus);
// shared group of 4 arrows
SharedGroup sg = new SharedGroup();
Shape3D arrow;
Transform3D tra;
TransformGroup tga;
for (int i = 0; i < 4; i++) {
arrow = new Shape3D(new Arrow(), ap);
tra = new Transform3D();
tra.setRotation(new AxisAngle4d(0, 0, 1, i*Math.PI/2));
tga = new TransformGroup(tra);
sg.addChild(tga);
tga.addChild(arrow);
}
// four links to shared group
Link link = new Link();
link.setSharedGroup(sg);
tr = new Transform3D();
tr.setScale(0.675);
tg = new TransformGroup(tr);
tg.addChild(link);
spin.addChild(tg);
link = new Link();
link.setSharedGroup(sg);
tr = new Transform3D();
tr.setScale(0.55);
tr.setRotation(new AxisAngle4d(0, 0, 1, Math.PI/4));
tg = new TransformGroup(tr);
tg.addChild(link);
spin.addChild(tg);
link = new Link();
link.setSharedGroup(sg);
tr = new Transform3D();
tr.setScale(0.4);
tr.setRotation(new AxisAngle4d(0, 0, 1, Math.PI/8));
tg = new TransformGroup(tr);
tg.addChild(link);
spin.addChild(tg);
link = new Link();
link.setSharedGroup(sg);
tr = new Transform3D();
tr.setScale(0.4);
tr.setRotation(new AxisAngle4d(0, 0, 1, 3*Math.PI/8));
tg = new TransformGroup(tr);
tg.addChild(link);

111

spin.addChild(tg);
//rotation
Alpha alpha = new Alpha(-1, 8000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//background and lights
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white),
new Point3f(2f,2f,2f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
}

Programa 3.11: Cdigo que despliega una figura en 3D.

Figura 3.20: Salida de la ejecucin del programa 3.11.

3.3.2 Representaciones de spline y curvas Bzier.


Una curva spline consiste en una secuencia de curvas de polinomios unidas
suavemente.

Las curvas B-spline son comnmente utilizadas en grficos por

computadora.
Las curvas cuadrticas y curvas cbicas soportadas en Java 2D son casos
especiales de curvas Bzier con grados de

, repectivamente. Sus

ecuaciones pueden expresarse como:

112

Una curva B-spline est definida por una secuencia de puntos de control; sigue
direcciones generales de dichos puntos, pero no necesariamente necesita
interpolar los puntos. Una curva general B-spline con grado
con puntos de control

est definida por

y una secuencia de parmetros de

conocidos como nodos:

. La ecuacin paramtrica

de una curva B-spline puede expresarse como:

La curva est definida no solo sobre los intervalos

. Las funciones

son conocidas como funciones normalizadas B-spline combinadas y


pueden definirse recursivamente por:

De otra manera:

Las curvas B-spline son herramientas de modelado muy verstiles. La suavidad y


continuidad de la curva puede controlarse por los nodos. Cuando las diferencias
entre los valores de nodos adjacentes son constantes:

, la curva se

conoce como B-spline uniforme; en general, las curvas B-spline no son uniformes.
La formulacin de B-spline puede tambin aplicarse a coordenadas homogneas
en la misma combinacin de funciones para los componentes

. Cuando un punto

de control est representado en coordenadas homogneas, la curva se conoce


como B-spline racional. Por lo tanto la familia de curvas B-spline ms general es
conocida como NURBS (B-spline racionales no uniformes).

113

En las curvas B-spline los nodos estn uniformemente distribudos, excepto los
primeros cuatro y los ltimos cuatro nodos que se establecen para que sean
iguales:

Los nodos duplicados ocasionarn que los primeros y ltimos puntos de control
sean interpolados por la curva, similar a lo que ocurre con una curva Bzier. De
hecho si

, una B-spline cbica de ste tipo es exactamente una curva cbica

regular Bzier:

denota las caractersticas del intervalo de la funcin

. La ecuacin

paramtrica para el B-spline es:

sta es exactamente la ecuacin de una curva cbica Bzier. Cuando

, la

curva B-spline tiene ms de un segmento polinomial y ms puntos de control que


una curva Bzier.
Java 2D no soporta directamente curvas B-spline; sin embargo una curva cbica
B-spline puede convertirse a varias series de curvas Bzier, que pueden ser
renderizadas. Si los puntos

son los puntos de control de una B-spline,

cada segmento puede ser convertido a una curva cbica Bzier. Si los puntos

114

, son los puntos de control de una curva Bzier, entonces, a excepcin


del primer y ltimo segmento, la conversin est dada por las siguientes frmulas:

Tanto el primer como el ltimo segmento son manejados de forma diferente,


debido a que el primer y ltimo punto de control son los puntos finales de la curva,
la conversin del primer segmento est dado por las siguientes frmulas:

El ltimo segmento utiliza las siguientes frmulas:

El siguiente cdigo ilustra la conversin y renderizado de una curva B-spline. En


el ejemplo la curva es convertida a una serie de curvas cbicas Bzier. El
programa permite al usuario introducir los puntos de control con un mouse.
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class BSpline extends JApplet {
public static void main(String s[]) {
JFrame frame = new JFrame();
frame.setTitle("B-Spline");

115

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet applet = new BSpline();
applet.init();
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
public void init() {
JPanel panel = new BSplinePanel();
getContentPane().add(panel);
}
}
class BSplinePanel extends JPanel implements MouseListener, MouseMotionListener {
Vector points = null;
boolean completed = true;
public BSplinePanel() {
setPreferredSize(new Dimension(640, 480));
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
points = new Vector();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
Point p0 = null;
Point p1 = null;
Point p2 = null;
Point p3 = null;
float x1,y1,x2,y2,x3,y3, x4, y4;
Iterator it = points.iterator();
if (it.hasNext()) {
p1 = (Point)(it.next());
}
while (it.hasNext()) {
p2 = (Point)(it.next());
g2.drawLine(p1.x, p1.y, p2.x, p2.y);
p1 = p2;
}
GeneralPath spline = new GeneralPath();
int n = points.size();
if (n == 0) return;
p1 = (Point)points.get(0);
spline.moveTo(p1.x, p1.y);
g2.drawRect(p1.x-3, p1.y-3, 6, 6);
p1 = (Point)points.get(1);
p2 = (Point)points.get(2);
p3 = (Point)points.get(3);
x1 = p1.x;
y1 = p1.y;
x2 = (p1.x + p2.x)/2.0f;
y2 = (p1.y + p2.y)/2.0f;
x4 = (2.0f*p2.x+p3.x)/3.0f;
y4 = (2.0f*p2.y+p3.y)/3.0f;
x3 = (x2+x4)/2.0f;
y3 = (y2+y4)/2.0f;
spline.curveTo(x1, y1, x2, y2, x3, y3);
g2.drawRect((int)x1-3, (int)y1-3, 6, 6);
g2.drawRect((int)x2-3, (int)y2-3, 6, 6);
g2.drawRect((int)x3-3, (int)y3-3, 6, 6);
for (int i = 2; i < n - 4; i++) {
p1 = p2;
p2 = p3;
p3 = (Point)points.get(i+2);
x1 = x4;
y1 = y4;
x2 = (p1.x+2.0f*p2.x)/3.0f;
y2 = (p1.y+2.0f*p2.y)/3.0f;
x4 = (2.0f*p2.x+p3.x)/3.0f;

116

y4 = (2.0f*p2.y+p3.y)/3.0f;
x3 = (x2+x4)/2.0f;
y3 = (y2+y4)/2.0f;
spline.curveTo(x1,y1,x2,y2,x3,y3);
g2.drawRect((int)x1-3, (int)y1-3, 6, 6);
g2.drawRect((int)x2-3, (int)y2-3, 6, 6);
g2.drawRect((int)x3-3, (int)y3-3, 6, 6);
}
p1 = p2;
p2 = p3;
p3 = (Point)points.get(n-2);
x1 = x4;
y1 = y4;
x2 = (p1.x+2.0f*p2.x)/3.0f;
y2 = (p1.y+2.0f*p2.y)/3.0f;
x4 = (p2.x+p3.x)/2.0f;
y4 = (p2.y+p3.y)/2.0f;
x3 = (x2+x4)/2.0f;
y3 = (y2+y4)/2.0f;
spline.curveTo(x1,y1,x2,y2,x3,y3);
g2.drawRect((int)x1-3, (int)y1-3, 6, 6);
g2.drawRect((int)x2-3, (int)y2-3, 6, 6);
g2.drawRect((int)x3-3, (int)y3-3, 6, 6);
p2 = p3;
p3 = (Point)points.get(n-1);
x1 = x4;
y1 = y4;
x2 = p2.x;
y2 = p2.y;
x3 = p3.x;
y3 = p3.y;
spline.curveTo(x1,y1,x2,y2,x3,y3);
g2.drawRect((int)x1-3, (int)y1-3, 6, 6);
g2.drawRect((int)x2-3, (int)y2-3, 6, 6);
g2.drawRect((int)x3-3, (int)y3-3, 6, 6);
g2.draw(spline);
}
public void mouseClicked(MouseEvent ev) {
}
public void mouseEntered(MouseEvent ev) {
}
public void mouseExited(MouseEvent ev) {
}
public void mousePressed(MouseEvent ev) {
Graphics g = getGraphics();
if (completed) {
points.clear();
completed = false;
}
if (ev.getClickCount() == 1) {
Point p =ev.getPoint();
points.add(p);
g.fillOval(p.x-3, p.y-3, 6, 6);
}
}
public void mouseReleased(MouseEvent ev) {
if (ev.getClickCount() > 1) {
completed = true;
repaint();
}
}
public void mouseMoved(MouseEvent ev) {
}
public void mouseDragged(MouseEvent ev) {
}
}

Programa 3.12: Cdigo que muestra una curva B-spline.

117

Figura 3.21: Salida de la ejecucin del programa 3.12.

La ecuacin paramtrica para una curva Bzier general de un grado


de control

Donde

con puntos

est dada por:

es conocido como un polinomio Bernstein o base Bernstein:

Una curva Bzier tiene un grado de

y est definida por cuatro puntos de

control:

El algoritmo deCasteljau proporciona un mtodo para calcular el punto de la curva


desde los puntos de control utilizando interpolaciones lineales. El algoritmo
construye un esquema triangular de los puntos, similar al tringulo de Pascal.
Para la curva Bzier, se utiliza el el siguiente esquema triangular:

118

La primera fila contiene los puntos originales de control de la curva Bzier. Las
filas subsecuentes son calculadas con la frmula:

La ltima entrada da el valor del punto de la curva Bzier en el punto :

El proceso se ilustra en la siguiente figura, todos los clculos son simples


interpolaciones lineales:

Figura 3.22: Algoritmo deCasteljau

Una curva Bzier puede ser subdividida en dos curvas Bzier. El algoritmo
deCasteljau tambin ofrece un mtodo para la subdivisin. En la figura anterior,
dos curvas Bzier subdivididas tienen los puntos de control

respectivamente.
Versiones actuales de la API Java 3D no incluye soporte directo para curvas y
superficies de curvas. Se implementarn las propias versiones de curvas Bzier y
superficies utilizando los arreglos de lnea y polgonos porporcionados por Java
3D. Otras curvas spline y superficies pueden ser implementadoas como series de
curvas y superficies Bzier.
El siguiente ejemplo muestra una curva cbica Bzier con sus subdivisiones
recursivas.

119

import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class BezierCurve extends LineStripArray {
static int level = 4;
static int[] vCnts = {(1<<level)+1};
int index = 0;
public BezierCurve(Point3d p0,Point3d p1,Point3d p2,Point3d p3) {
super(vCnts[0], GeometryArray.COORDINATES, vCnts);
setCoordinate(index, p0);
index++;
subdivide(0,p0,p1,p2,p3);
}
void subdivide(int lev, Point3d p0, Point3d p1, Point3d p2, Point3d p3) {
if (lev >= level){
setCoordinate(index, p3);
index++;
}
else {
Point3d p10 = new Point3d();
p10.add(p0,p1);
p10.scale(0.5);
Point3d p11 = new Point3d();
p11.add(p1,p2);
p11.scale(0.5);
Point3d p12 = new Point3d();
p12.add(p2,p3);
p12.scale(0.5);
Point3d p20 = new Point3d();
p20.add(p10,p11);
p20.scale(0.5);
Point3d p21 = new Point3d();
p21.add(p11,p12);
p21.scale(0.5);
Point3d p30 = new Point3d();
p30.add(p20,p21);
p30.scale(0.5);
subdivide(lev+1,p0,p10,p20,p30);
subdivide(lev+1,p30,p21,p12,p3);
}
}
}

Programa 3.13: Cdigo que muestra una curva Bzier con sus divisiones recursivas.

El siguiente cdigo despliega la curva Bzier creada en el cdigo anterior. La


clase BezierCurve est implementada como una subclase de LinesStripArray.
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestBezierCurve extends Applet {
public static void main(String[] args) {
new MainFrame(new TestBezierCurve(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();

120

Canvas3D cv = new Canvas3D(gc);


setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
// object
Point3d p0 = new Point3d(-1,0,0.5);
Point3d p1 = new Point3d(-0.2,0.6,-0.2);
Point3d p2 = new Point3d(0.3,-0.8,0.3);
Point3d p3 = new Point3d(0.9,0.1,0.6);
Appearance ap = new Appearance();
ap.setColoringAttributes(new ColoringAttributes(0f, 0f, 0f,
ColoringAttributes.FASTEST));
Shape3D shape = new Shape3D(new BezierCurve(p0,p1,p2,p3), ap);
spin.addChild(shape);
// rotation interpolator
Alpha alpha = new Alpha(-1, 10000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
// background
Background background = new Background(1f, 1f, 1f);
background.setApplicationBounds(bounds);
root.addChild(background);
return root;
}
}

Programa 3.14: Cdigo que despliega una curva Bzier.

Figura 3.23: Salida de la ejecucin del programa 3.14.

121

3.3.3 Superficies Bzier.


Una superficie Bzier est formada al extender una curva Bzier a una superficie
sobre otra curva Bzier utilizando el mtodo llamado clculo tensorial.

La

ecuacin paramtrica de una superfice de una superficie Bzier est dada por:

El tipo ms comn utilizado para las superficies Bzier es la superfice bicbica


dada por

, la cual est definida por 16 puntos de control.

La evaluacin de un punto

en una superficie Bzier puede tambin ser

obtenida del algoritmo deCasteljau. Una superficie Bzier puede ser vista como
una familia de curvas Bzier. Para una

fija, la curva

es una curva

Bzier con los puntos de control:

Los cuatro puntos de control son cada uno otra curva Bzier. Consecuentemente
estos puntos pueden ser calculados a travs de cuatro aplicaciones del algoritmo
deCasteljau con

. Despus de haber obtenido los cuatro puntos de control

para la curva Bzier, se pueden calcular los puntos


aplicacin del algoritmo de deCasteljau con

, de otra

en la curva.

El siguiente cdigo muestra una superficie bicbica Bzier:


import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.geometry.*;
public class BezierSurface extends Shape3D{
public BezierSurface(Point3d[][] ctrlPts) {
int m = 17;
int n = 17;
Point3d[] pts = new Point3d[m*n];
int idx = 0;
Point3d[] p = new Point3d[4];
double du = 1.0/(m-1);
double dv = 1.0/(n-1);
double u = 0;

122

double v = 0;
for (int i = 0; i < m; i++) {
for (int k = 0; k < 4; k++) {
p[k] = deCasteljau(u, ctrlPts[k]);
}
v = 0;
for (int j = 0; j < n; j++) {
pts[idx++] = deCasteljau(v, p);
v += dv;
}
u += du;
}
int[] coords = new int[2*n*(m-1)];
idx = 0;
for (int i = 1; i < m; i++) {
for (int j = 0; j < n; j++) {
coords[idx++] = i*n + j;
coords[idx++] = (i-1)*n + j;
}
}
int[] stripCounts = new int[m-1];
for (int i = 0; i < m-1; i++) stripCounts[i] = 2*n;
GeometryInfo gi = new GeometryInfo(GeometryInfo.TRIANGLE_STRIP_ARRAY);
gi.setCoordinates(pts);
gi.setCoordinateIndices(coords);
gi.setStripCounts(stripCounts);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
this.setGeometry(gi.getGeometryArray());
}
Point3d deCasteljau(double t, Point3d[] p) {
Point3d[] pt = {new Point3d(p[0]),new Point3d(p[1]),new Point3d(p[2]), new Point3d(p[3])};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3-i; j++) {
pt[j].interpolate(pt[j+1], t);
}
}
return pt[0];
}
}

Programa 3.15: Cdigo que muestra una superficie bicbica Bzier.

El siguiente cdigo despliega una superfice Bzier generada aleatoriamente:


import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
public class TestBezierSurface extends Applet {
public static void main(String[] args) {
new MainFrame(new TestBezierSurface(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();

123

SimpleUniverse su = new SimpleUniverse(cv);


su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
// surface
Point3d[][] ctrlPts = new Point3d[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
ctrlPts[i][j] = new Point3d(2-i, 3*(Math.random()-0.5), j-2);
}
}
Shape3D shape = new BezierSurface(ctrlPts);
Appearance ap = new Appearance();
ap.setMaterial(new Material());
shape.setAppearance(ap);
Transform3D tr = new Transform3D();
tr.setScale(0.25);
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
tg.addChild(shape);
// rotation interpolator
Alpha alpha = new Alpha(-1, 10000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
// background and lights
Background background = new Background(1f, 1f, 1f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.red));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.lightGray),
new Point3f(1f,1f,1f), new Point3f(1f,0f,0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
}

Programa 3.16: Cdigo que muestra una superficie Bzier generada aleatoriamente.

Figura 3.24: Salida de la ejecucin del programa 3.16.

124

ANEXOS

125

Anexo 1. Preguntas y Ejercicios de Unidad 1.

Preguntas de Unidad 1:
1. Lista tres aplicaciones que utilicen grficos por computadora en 2D.
2. Nombra una aplicacin (que no sea un juego) que utilice grficos por
computadora en 3D.
3. Busca en internet y escribe una lista de pelculas que han aplicado la
graficacin por computadora.
4. Identifica los campos (graficacin por computadora, procesamiento de
imgenes, y visin por computadora) que se relacionan con las siguientes
aplicaciones:
a. Localizacin de puntos brillantes en una imagen de una mamografa.
b. Construir un modelo en 3D de un edificio a travs un conjunto de sus
imgenes.
c. Mostrar una simulacin del sistema solar con el sol y los planetas en
movimiento.
d. Reconocer una parte del cerebro en un escaneo por MRI y mostrar
un modelo en 3D del cerebro.
e. Utilizar computadoras para generar una escena de un choque
automovilstico.
f. Realizar una identificacin por computadora de una persona a partir
de su fotografa.
5. Busca en internet un ejemplo de un programa que utilice GKS.
6. Busca en internet un ejemplo de un programa que utilice PHIGS.
7. Compara OpenGL con Java 3D y haz una lista de ventajas para cada API.
8. Discute las ventajas y desventajas de incluir soporte grfico en una
plataforma de lenguaje estndar como Java.
9. Haz una lista de los componentes GUI ms importantes de AWT y
encuentra sus equivalentes (ms aproximados) en Swing.
10. Lee la documentacin de Java 3D y haz una lista de paquetes de Java en
Java 3D.

126

Ejercicios de Unidad 1:
1. Escribe un programa en Java (por consola) que llene un arreglo double con
100 nmeros aleatorios e imprima la media y la desviacin estndar.
2. Escribe un programa en AWT que dibuje un crculo en medio de la ventana.
3. Escribe un programa en Swing que dibuje un crculo en medio de la
ventana.
4. Escribe un programa que permita al usuario arrastrar un crculo relleno en
determinada posicin indicada por el mouse.
5. Escribe, compila y corre el programa en Java 2D presentado en la pgina
25.
6. Escribe, compila y corre el programa en Java 3D presentado en la pgina
26.

Anexo 2. Preguntas y Ejercicios de Unidad 2.

127

Preguntas de Unidad 2:
1. Cules son las diferencias entre transformaciones de objeto y
transformaciones de vista?
2. Grafica los siguientes puntos en un sistema de coordenadas 2D:
(1, 3), (-2, 1.5), (0,-2), (0, 0)
3. Encuentra las coordenadas de los vrtices del siguiente tringulo:

4. Escribe un cdigo en Java que dibuje una elipse de 80 de ancho y 100 de


alto centrado en (100, 300).
5. Encuentra el ngulo actual que abarca el siguiente arco:
new Arc2D.Float(0, 0, 100, 200, 0, 45);
6. Cul es la matriz de transformacin de una rotacin de 45 sobre el
origen?
7. Construye un objeto AffineTransform para una refleccin general sobre una
lnea que atraviesa el origen.
8. Es

posible

transformar

una

elipse

en

un

crculo

utilizando

transformaciones afines?
9. Es posible transformar un trapezoide a un cuadrado utilizando
transformaciones afines?
10. Cul es la inversa de una rotacin del un ngulo

sobre el origen?

11. Encuentra la transformacin afin que mapee un eje

a un eje

y uno

uno .
12. Encuentra la matriz de transformacin para la rotacin de un ngulo
sobre los puntos

13. Encuentra la matriz de transformacin para la refleccin sobre la lnea


.

128

14. Encuentra la matriz de transforacin para la refleccin sobre la lnea


.
15. Encuentra la matriz de transformacin para sesgar sobre el eje

con un

factor de 0.5.
16. Encuentra la matriz de transformacin para la composicin de rotacin de
sobre el origen y una refleccin sobre la lnea
17. Si los valores RGB y

de la fuente de un pixel son 0.5, 0.0, 0.8 y 0.4, y los

valores del pixel destino son 0.2, 1.0, 0.5 y 0.6, encuentra el valor RGB y el
valor de

para la composicin utilizando cada una de las reglas: SrcOver,

DstOver, Src, Dst, SrcOut y DstOut.


18. Si el color destino tiene un valor

de 1.0, cules reglas de composicin

no sern afectadas por el color de la fuente?


19. Encuentra la matriz de transformacin de la traslacin que mapea el punto
(3, -1, 2) a (0, 5, -1).
20. Encuentra la matriz de transformacin de una rotacin sobre el eje

por

30.
21. Encuentra la matriz de transformacin de la refleccin sobre el plano a
travs del origen con el vector normal (1, 1, 1).
22. Deriva la matriz de transformacin de la refleccin sobre el plano a travs
del origen con un vector normal

como se define a continuacin:

23. Calcula el producto del cuaternin:


24. Si

son dos vectores de unidad ortogonales,

encuentra la ecuacin que mapea


25. Una sesgacin de

al eje

al eje ; y

al el eje .

est definida por la matriz:

, deriva la

transformacin de composicin que realiza una sesgacin a

por los

Proporcionando los vectores ortogonales de unidad


factores

129

26. Encuentra la matriz de transformacin para la rotacin 3D representada por


el cuaternin:
27. Si
eje

es una rotacin de 30 sobre el eje

, describe la rotacin de composicin

una rotacin de 60 sobre el


en trminos de su eje y

ngulo.

Ejercicios de Unidad 2:
1. Escribe un programa que grafique las siguientes ecuaciones paramtricas:

2. Escribe un programa que grafique las siguientes ecuaciones paramtricas:

3. Escribe un programa que despliegue un cuadrado centrado en el origen y


que presente una rotacin de 45.
4. Escribe un programa que muestra un cuadro centrado en el origen con una
rotacin de 45, aplicando una AffineTransform a un objeto Rectangle2D.
5. Escribe un programa que despliegue una imagen espejo de la cadena
Hola 2D Nota: utiliza una refleccin.
6. Escribe un programa que realice una refleccin sobre la lnea

. El

programa deber dibujar un rectngulo original de 100 x 50 en (0, 100),


aplicando una refleccin al rectngulo y presentar la figura transformada en
un color diferente.
7. Escribe un programa que dibuje un texto circular alrededor del punto (300,
300). Nota: Utiliza el mtodo drawString para cada carcter y aplica una
rotacin repetidamente.
8. Escribe un programa que realice una escalacin de factor 3 sobre la lnea
. El programa deber dibujar un cuadrado original de 100 en (0, 0),
aplicando la escalacin al cuadrado y deber dibujar la figura transformada
en un color diferente. Nota: Descompone la transformacin para realizar
una escalacin estndar y dos rotaciones.

130

9. Utilizando una figura circular como trayectoria de recorte, escribe un


programa que dibuje una cadena de caracteres Java 2D con tamao de
fuente grande.
10. Escribe un programa que cargue una imagen y despliegue solo una regin
elptica de la misma. Nota: utiliza la trayectoria de recorte para realizar el
efecto.
11. Escribe un programa en 3D que despliegue dos tetraedros con una de las
caras de uno de sus tringulos en comn.
12. Escribe un programa que despliegue dos conos con sus vrtices
apuntndose uno con otro.
13. Escribe un programa que despliegue un cono con sus vrties apuntando en
la direccin (1, 1, 1).
14. Modifica el cdigo del programa de la pgina 68, para incluir una operacin
de sesgado

. El programa deber permitir al usuario especificar los

factores

15. Modifica el cdigo del programa de la pgina 68, para incluir una rotacin
con ngulos Euler.
16. Modifica el cdigo del programa de la pgina 74, para construir una matriz
de refleccin directamente de la siguiente frmula:

131

Anexo 3. Preguntas y Ejercicios de Unidad 3.

Preguntas de Unidad 3:
1. Construye un objeto PointArray para los vrtices de un cubo centrados en
el origen.
2. Construye un objeto LineArray para las orillas de un tetraedro.
3. Utiliza un objeto TriangleArray para representar un tetraedro.
4. Construye un objeto QuadArray para representar un cubo.
5. Construye un objeto LineStripArray para las orillas de un tetraedro
6. Construye un objeto TriangleStripArray para representar un tetraedro.
7. Construye un objeto TriangleFanArray para representar un tetraedro.
8. Utiliza un objeto IndexedQuadArray para representar un cubo.
9. Dibuja la figura correspondiente al siguiente objeto TriangleStripArray:
int[ ] stripVertexCounts = {5, 3};
TriangleStripArray tsa = new TriangleStripArray (8, GeometryArray.COORDINATES,
stripVertexCounts);
Point3f[ ] coords = new Point3f[8];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(0f, 1f, 0f);
cords[2]= new Point3f(0.5f, 0.866f, 0f);
cords[3]= new Point3f(1.5f, 0.866f, 0f);
cords[4]= new Point3f(1f, 1.73f, 0f);
cords[5]= new Point3f(0f, 1f, 0f);
cords[6]= new Point3f(1.5f, 0.866f, 0f);
cords[7]= new Point3f(2f, 0f, 0f);
tsa.setCoordinates(0, coords);

10. Dibuja la figura que corresponda al siguiente objeto TriangleFanArray:


int[ ] stripVertexCounts = {4, 4};
TriangleFanArray tfa = new TriangleFanArray (8, GeometryArray.COORDINATES,
stripVertexCounts);
Point3f[ ] coords = new Point3f[8];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(1f, 0f, 0f);
cords[2]= new Point3f(0.866f, 0.5f, 0f);
cords[3]= new Point3f(0.5f, 0.866f, 0f);
cords[4]= new Point3f(0f, 0f, 0f);
cords[5]= new Point3f(-1f, 0f, 0f);
cords[6]= new Point3f(-0.866f, -0.5f, 0f);
cords[7]= new Point3f(-0.5f, -0.866f, 0f);
tfa.setCoordinates(0, coords);

11. Dibuja

una

figura

que

corresponda

al

siguiente

objeto

de

IndexedTriangleStripArray:
int[ ] stripIndexCounts = {5, 3};

132

IndexedTriangleStripArray itsa = new IndexedTriangleStripArray (6,


GeometryArray.COORDINATES, 8, stripIndexCounts);
Point3f[ ] coords = new Point3f[6];
cords[0]= new Point3f(0f, 0f, 0f);
cords[1]= new Point3f(0f, 1f, 0f);
cords[2]= new Point3f(0.5f, 0.866f, 0f);
cords[3]= new Point3f(1.5f, 0.866f, 0f);
cords[4]= new Point3f(1f, 1.73f, 0f);
cords[5]= new Point3f(2f, 0f, 0f);
itsa.setCoordinates(0, coords);
int[ ] ndices = {0, 1, 2, 3, 4, 1, 3, 5};
itsa.setCoordinateIndices(0, indices);

12. Si una vista de frustum tiene un campo de vista de


y
vista.

NOTA:

, y los dos puntos

son sus dos lmites horizontales, encuentra el punto de


esta

es

la

transformacin

exacta

realizada

por

setNominalViewTransform().
13. Deriva la matriz de la proyeccin paralela sobre la direccin (1, 0, 1) en el
plano

14. Deriva la matriz de la proyeccin perspectiva con vrp en el origen y la placa


vista perpendicular al eje

centrado en (0, 0, 1).

15. Encuentra la matriz de proyeccin para la vista de volumen especificada


por la siguiente llamada al mtodo: frustum(-3, 3, -2, 2, 1, 10).
16. Encuentra la matriz de proyeccin de la vista de volumen especificada por
la siguiente llamada: frustum(-2, 2, -1, 1, 2, 4).
17. Encuentra la matriz de proyeccin de la vista de volumen especificada por
la siguiente llamada: perspective(Math.PI/3, 1.5, 1, 10).
18. Encuentra la matriz de proyeccin de la vista de volumen especificada por
la siguiente llamada: ortho(-3, 3, -2, 2, 1, 10).
19. Encuentra la matriz de proyeccin de la vista de volumen especificada por
la siguiente llamada: ortho(-2, 2, -1, 1, 2, 4).
20. Encuentra la matriz de vista al efectuar un cambio de direccin hacia arriba
de la misma a (1, 1, 0).
21. Encuentra la matriz de vista especificada por las siguientes llamadas:
Point3d eye= new Point3d(0, 0, 0);
Point3d look = new Point3d(0, 0, 1);
Vector3d up = new Vector3d(0, -1, 0);
lookAt(eye, look, up);

22. Encuentra la matriz de vista especificada por las siguientes llamadas:

133

Point3d eye= new Point3d(0, 0, -1);


Point3d look = new Point3d(0, 0, 0);
Vector3d up = new Vector3d(1, 0, 0);
lookAt(eye, look, up);

23. Dada una curva cbica B-spline definida con

puntos de control, cuntas

curvas Bzier pueden generarse de la conversin?


24. Existe un tipo de curvas B-spline que no imponen restricciones especiales
a los puntos finales de las mismas. Tanto el primero como ltimo segmento
son tratados de la misma manera, as como otros segmentos; es decir
utiliza la misma formula para la conversin a curvas Bzier en cada
segmento. Consecuentemente, los primeros y ltimos puntos de control, no
necesariamente necesitan ser interpolados por la curva. Encuentra la
formula de conversin para este tipo de cuarva B-spline.
25. Una curva cbica Bzier est definida por los siguientes puntos de control:
Utiliza un algoritmo de deCasteljau para evaluar los puntos de la curva en:
a.
b.
c.
26. Subdivide en dos las curvas Bzier definidas en la pregunta anterior,
utilizando el algoritmo deCasteljau en los puntos:
a.
b.
c.
27. Deriva la formula para la superficie normal de un bicubo Bzier en un punto
dado.

Ejercicios de Unidad 3:
1. El octaedro es uno de los cinco slidos platnicos. Tiene ocho caras en
forma de tringulos y seis vrtices:

134

Escribe un programa que implemente una clase de tipo Octahedron con su


Geometra desendiente.
2. Escribe un programa para la clase Octrahedron que muestre un octaedro
en forma de malla.

3. Escribe un programa que cree una rejilla/cuadrcula 3D de 4 x 4 x 4


utilizando la clase LineArray.
4. Escrique un programa que despliegue un frustum en el espacio virtual,
utilizando para ello un objeto IndexedQuadArray para definirlo con un
cuadro superior del tamao 1 x 1, un cuadro inferior de 2 x 2, y que
presente una altura de 1.
5. Escribe un programa en 3D que despliegue un objeto ColorCube en
rotacin utilizando un objeto SimpleUniverse. Modifica la vista de la
plataforma para mover ViewPlatform a (0, 0, 3).
6. Modifica el listado del programa de la pgina 97, para utilizarlo con una
vista de proyeccin paralela.

135

7. Escribe un programa que despliegue una esfera y la mueva cerca de la


vista hasta que se trunque parcialmente con el plano frontal. Utiliza para
ello un objeto SimpleUniverse.
8. Escribe un programa que examine la matriz generada por el mtodo lookAt
de la clase Transform3D. El programa deber permitir al usuario introducir
los parmetros para el mtodo e imprimir la matriz resultante.
9. Escribe un programa como el anterior pero en este caso utilizando los
mtodos: perspective, frustum y ortho.
10. Escribe un programa con vista de modo de compatibilidad. Utiliza una
proyeccin de perspectiva para el campo de vista

. Coloca la vista en

(0, 0, 1) viendo hacia abajo en el eje . Despliega un objeto de la clase


Axes definida en la pgina 67.
11. Escribe un programa con dos diferentes vistas. Una posicionada en (0, 0,
2) con vista hacia el eje negativo en

y con el eje

en posicin hacia

arriba. La otra vista estar posicionada en (0, 0, -2) viendo sobre el eje
con el eje negativo en

en direccin hacia arriba. Coloca un texto 3D en

rotacin cerca del origen.


12. Escribe un programa con las cuatro vistas de los diferentes campos de
vista. Todas las vistas estn posicionadas en (0, 0, 2) viendo hacia el eje
negativo

y con el eje

como direccin hacia arriba. Los campos de las

vistas estn establecidas a

,y

. Coloca un texto en 3D y

un objeto de la clase Axes (pgina 67) en la escena.


13. Escribe un programa que genere una figura que tenga un cuadrado y
cuatro objetos cilndricos. Utiliza primitivas predefinidas y transformaciones
para crearlo. Rota el objeto continuamente en la escena.
14. Escribe un programa que cree y despliegue una figura geomtrica que
est formada al rotar la siguiente figura sobre el eje .

136

15. Escribe un programa que implementa la curva B-spline definida en la


pregunta de unidad 24.
16. Escribe un programa que implemente una curva B-spline en 3D al convertir
una serie de curvas Bzier, similarmente a las curvas en 2D.
17. Escribe un programa que muestre un editor de superficie Bzier. El
programa deber desplegar los puntos de control de la superficie como
puntos cuadrados y permitir al usuario seleccionar y mover los puntos de
control con el mouse y actualizar la superficie acorde a los movimientos.

Anexo 4. ndice de figuras.

UNIDAD 1
Figura 1.1: Tareas principales de la graficacin por computadora:

modelando un mundo virtual y renderizandolo a una escena


Figura 1.2. Crculo creado al ejecutar el cdigo en ensamblador.

13

Figura 1.3. Crculo creado al ejecutar el cdigo en C.

16

Figura 1.4. Crculo creado al ejecutar el cdigo en FORTRAN.

18

Figura 1.5. Crculo creado al ejecutar el cdigo de OpenGL.

20

Figura 1.6. Esfera creada al ejecutar el cdigo de OpenGL.

21

Figura 1.7. Grfico creado al ejecutar el cdigo de Java2D.

26

Figura 1.8. Grfico creado al ejecutar el cdigo de Java3D.

28

UNIDAD 2
Figura 2.1 Un objeto grfico en 2D es procesado para su transformacin

31

y su vista.

137

Figura 2.2 Sistema de coordenadas en 2D con el ejes (x, y)

33

Figura 2.3 Lnea que pude ser representada por una ecuacin lineal.

33

Figura 2.4 Una elipse representada por una ecuacin cuadrtica.

34

Figura 2.5 Sistema de coordenadas de Java 2D, con el eje x

36

aumentando hacia la derecha y el eje y hacia abajo.


Figura 2.6 Una traslacin (3, -1)

37

Figura 2.7 Una rotacin sobre el origen

37

Figura 2.8 Una refleccin sobre una lnea diagonal.

38

Figura 2.9 Escalacin por los factores (1.5, 2).

38

Figura 2.10 Sesgar por el factor 1 sobre la lnea horizontal punteada.

39

Figura 2.11 Salida de la ejecucin del programa 2.1.

45

Figura 2.12 Salida de la ejecucin del programa 2.2.

48

Figura 2.13 Cuatro eventos diferentes de color que pueden ocurrir en el

50

modelo probabilstico de composicin.


Figura 2.14 Salida de la ejecucin del programa 2.3.

52

Figura 2.15 Salida de la ejecucin del programa 2.4.

54

Figura 2.16 Salida de la ejecucin del programa 2.6.

61

Figura 2.17 Salida de la ejecucin del programa 2.9.

71

Figura 2.18 Salida de la ejecucin del programa 2.10.

75

UNIDAD 3
Figura 3.1: Esfera representada por mallas de tringulos de diferentes

79

resoluciones.
Figura 3.2: Jerarqua de clases de Geometry.

79

Figura 3.3: Geometra de un PointArray.

80

Figura 3.4: Geometra de un LineArray.

81

Figura 3.5: Geometra de un TriangleArray.

82

Figura 3.6: Geometra de un QuadArray.

83

Figura 3.7: Representacin de un TriangleStripArray.

84

Figura 3.8: Representacin de un TriangleFanArray.

85

Figura 3.9: Salida de la ejecucin del programa 3.2.

88

Figura 3.10: Subclases de la clase Primitive.

88

Figura 3.11: Salida de ejecucin del programa 3.3.

90

138

Figura 3.12: Proyeccin paralela.

91

Figura 3.13: Proyeccin de perspectiva.

92

Figura 3.14: Ejemplo de proyeccin perspectiva.

93

Figura 3.15: Salida de la ejecucin del programa 3.4.

99

Figura 3.16: Salida de la ejecucin del programa 3.5.

102

Figura 3.17: Salida de la ejecucin del programa 3.6.

104

Figura 3.18: Construccin de un toro a travs de rotaciones.

107

Figura 3.19: Salida de la ejecucin del programa 3.9.

109

Figura 3.20: Salida de la ejecucin del programa 3.11.

112

Figura 3.21: Salida de la ejecucin del programa 3.12.

118

Figura 3.22: Algoritmo deCasteljau

119

Figura 3.23: Salida de la ejecucin del programa 3.14.

121

Figura 3.24: Salida de la ejecucin del programa 3.16.

124

Anexo 5. ndice de programas.

UNIDAD 1
Programa 1.1: Cdigo en ensamblador que muestra un crculo.

11

Programa 1.2: Cdigo en C que muestra un crculo.

14

Programa 1.3: Cdigo en FORTRAN que muestra un crculo.

17

Programa 1.4: Cdigo utilizando OpenGL que muestra un crculo.

19

Programa 1.5: Cdigo utilizando OpenGL que muestra una esfera 3D.

20

Programa 1.6: Cdigo utilizando JOGL que muestra una esfera 3D.

23

Programa 1.7: Cdigo utilizando Java2D que muestra un crculo y texto.

25

Programa 1.8: Cdigo utilizando Java3D que muestra un globo terrqueo

26

en rotacin y texto.

UNIDAD 2
Programa 2.1: Cdigo que muestra efectos de las transformaciones

42

afines.

139

Programa 2.2: Cdigo que aplica la composicin de transformaciones.

48

Programa 2.3: Objetos renderizados con las 12 reglas de composicin.

51

Programa 2.4: Cdigo que presenta un ejemplo de trayectoria de recorte.

53

Programa 2.5: Cdigo que proporciona una clase que despliega una

59

matriz.
Programa 2.6: Cdigo que proporciona una interface para visualizar una

59

matriz y realizar diversas operaciones sobre ella.


Programa 2.7: Cdigo que muestra la conversin de un cuaternin a los

66

ngulos Euler.
Programa 2.8: Cdigo que proporciona la clase que despliega un

67

conjunto de coordenadas.
Programa 2.9: Cdigo que muestra las caractersticas de la clase

68

Transform3D.
Programa 2.10: Cdigo que muestra la construccin de reflecciones.

74

UNIDAD 3
Programa 3.1: Cdigo que construye un tetraedro regular.

86

Programa 3.2: Cdigo que despliega un tetraedro en rotacin.

87

Programa 3.3: Cdigo que despliega las cuatro primitivas bsicas en

90

rotacin.
Programa 3.4: Cdigo que muestra un tetraedro y utiliza vistas en modo

97

de compatibilidad.
Programa 3.5: Cdigo que muestra un dodecaedro.

100

Programa 3.6: Cdigo que muestra un texto 3D en 4 vistas.

103

Programa 3.7: Cdigo que muestra un mtodo que toma un objeto 2D y

106

le aplica una extrusin.


Programa 3.8: Cdigo que muestra la construccin de un toro va dos

107

rotaciones diferentes.
Programa 3.9: Cdigo que despliega dos toros generados con

108

transformaciones.
Programa 3.10: Cdigo que despliega una flecha ilustrando la

110

combinacin de transformaciones.
Programa 3.11: Cdigo que despliega una figura en 3D.

110

140

Programa 3.12: Cdigo que muestra una curva B-spline.

115

Programa 3.13: Cdigo que muestra una curva Bzier con sus divisiones

120

recursivas.
Programa 3.14: Cdigo que despliega una curva Bzier.

120

Programa 3.15: Cdigo que muestra una superficie bicbica Bzier.

122

Programa 3.16: Cdigo que muestra una superficie Bzier generada

123

aleatoriamente.

Anexo 6. ndice de tablas.

UNIDAD 1
Tabla 1.1: Programacin grfica en diferentes niveles.

10

Tabla 1.2 Capas de los sistemas grficos.

22

UNIDAD 2
Tabla 2.1 Las 12 reglas de composicin Porter Duff

50

141

GLOSARIO

A
Algoritmo deCasteljau: mtodo para calcular un punto en una curva
Bzier a travs de una serie de interpolaciones lineales.
ngulos Euler: mtodo que especifica rotaciones 3D con tres rotaciones
sobre los ejes de las coordenadas principales.
API: Interface de Aplicacin del Programador. Una interface de software
estandarizada que especifica el uso de funcionalidades proporcionadas por
un paquete de software.
Avatar: identidad representada grficamente que adopta un usuario.
AWT: Abstract Window Toolkt. Un paquete grfico de Java existente desde
las primeras versions del API de Java.
Azimut: arco del horizonte medido entre un punto fijo y el crculo vertical
que pasa por el centro de un objeto en el cielo o en la tierra.

142

C
Centro de vista: una ubicacin centrada que define la direccin en donde
el ojo est posicionado.
Cuaternin: es una extensin de los nmeros reales, similar a la de los
nmeros complejos. Mientras que los nmeros complejos son una
extensin de los reales por la adicin de la unidad imaginaria , tal que
, los cuaterniones son una extensin generada de manera
anloga aadiendo las unidades imaginarias: , y
tal que

a los nmeros reales y

Curva Bzier: curva definida por una ecuacin paramtrica de una


combinacin de polinomios con puntos de control.
Curva B-spline: curva definida por una ecuacin paramtrica de un
conjunto de variables y combinacin de polinomios con una secuencia de
puntos de control.
Curva 3D Bzier: curva paramtrica de un polinomio 3D definida por un
conjunto de puntos de control.
E
Escalacin: transformacin geomtrica que escala las coordenadas por
factores constantes. La escalacin es uniforme si los tres factores de los
componentes

son los mismos.

Espacio de dispositivo: espacio de coordenadas utilizadas por un


dispositivo de salida especfico.
Espacio mundo: referencia comn de un espacio con coordenadas para
modelos grficos.
Espacio objeto: espacio de coordenadas locales asociadas con un objeto
individual.
Ecuacin paramtrica: conjunto de ecuaciones que expresan variables
coordinadas como funciones de parmetros.

F
FOV: campo de vista. Un ngulo para la porcin visible de una vista.

143

Frustum: es el volumen de visualizacin de una cmara en un punto


determinado, el cual est generado a partir de una matriz de proyeccin en
perspectiva. Tiene forma de pirmide con la punta recortada. Este volumen
de visualizacin est delimitado por seis planos: plano de recorte lejano,
plano de recorte cercano, plano superior, plano inferior, plano izquierdo y
plano derecho.

G
GKS: Sistema de Kernel Grfico (Graphics Kernel System). Una API de
estndar grfico.

J
JOGL: Un lenguaje de cubierta en Java para OpenGL.

M
Malla de polgono: conjunto de polgonos simples como los tringulos que
representan una aproximacin de una superficie.
Matriz de proyeccin: matriz que define un volumen de vista.
Matriz de transformacin 3D: matriz que representa una transformacin
proyectiva 3D.
Matriz de vista: matriz que define la ubicacin y orientacin de una vista
en un espacio virtual.
Modelado: el proceso de construir un modelo grfico.
Modelo de compatibilidad: un modo de vista especial de Java 3D que es
compatible con las vistas tradicionales de OpenGL.
Mundo virtual: modelo grfico construido en una computadora.

N
NURBS: B-spline no uniforme y racional.

144

OpenGL: Una API grfica popular derivada del GL (Graphics Library) de


Silicon Graphics. Tiene una interface de programacin tpicamente
asociada al lenguaje C.

P
PHIGS: Programmers Hierarchical Interactive Graphics System. Una API
grfica.
Plano frontal de recorte: el plano fontral de una vista frustum.
Plano posterior de recorte: plano posterior de una vista frustum.
Polinomio Bernstein: (base de Bernstein) un polinomio especial
frecuentemente utilizado en aproximacin.
POO: Programacin Orientada a Objetos. Un paradigma de ingeniera de
software que

visualiza a un programa como un sistema de objetos

interrelacionados.
Primitiva: objeto visual que puede ser utilizado para construir un modelo.
Procesamiento de imgenes: campo de la ingeniera elctrica y las
ciencias

de

la

computacin

para

estudiar

el

procesamiento

por

computadora de imgenes digitales.


Proyeccin de perspectiva: proyeccin en donde todos los proyectores
pasan a travs de un punto fijo.
Proyeccin paralela: proyeccin en donde todos los proyectores son
paralelos.
Punto: elemento bsico que representa una posicin en un espacio.

R
Refleccin: transformacin geomtrica que voltea los puntos sobre un
plano fijo.
Reglas Porter-Duff: mtodo que crea nuevas figuras geomtricas al
utilizar un conjunto de operaciones tales como unin e interseccin de las
reas de las figuras existentes.
Relacin de aspecto: es la proporcin de una imagen entre su anchura y
su altura.

145

Representacin de cuaterniones: mtodo que representa una rotacin


3D con un cuaternin.
Renderizado: proceso de construir una imagen de una escena de un
modelo grfico.
Rotacin: transformacin geomtrica que rota un punto alrededor de un
eje fijo por un ngulo constante.

S
Sesgacin:

transformacin

geomtrica

que

mueve

los

puntos

paralelamente a un plano.
Sistema de coordenadas: mtodo para asociar puntos geomtricos con
cantidades algebraicas de tuplas ordenadas por nmeros.
Slidos platnicos: representa los cinco poliedros regulares: tetraedro,
cubo, octaedro, dodecaedro e icosaedro.
Superficie Bzier: superficie de polinomio paramtrico definido por una
rejilla o cuadrcula de puntos de control.
Swing: paquete de grficos para Java relativamente nuevo y mejorado.

T
Toro: es la superficie de revolucin engendrada por una circunferencia que
gira alrededor de una recta fija de su plano, que no la corta. Proviene del
vocablo en latn torus, el cual significa "bulto", ya sea "volumen o tamao
de una cosa" o "elevacin de una superficie causada por una
protuberancia". Un toro slido es un objeto tridimensional construido
mediante el producto cartesiano de un disco y un crculo.
Transformacin afn: transformacin que preserva el paralelismo.
Transformacin

de

composicin:

combinacin

de

dos

ms

transformaciones para formar una nueva.


Transformacin proyectiva: transformacin geomtrica que preserva los
puntos, lneas y sus relaciones.
Traslacin: transformacin geomtrica que mueve todos los puntos por un
valor constante.

146

Trayectoria de recorte: figura que define una regin para limitar el


renderizado.
Tupla: es una secuencia ordenada de objetos, esto es, una lista con un
nmero limitado de objetos.

V
Vector: un elemento geomtrico para una cantidad direccional.
Visin por computadora: campo de la ingeniera y la computacin que
estudia la percepcin y reconstruccin de una escena de imgenes
capturadas.
Vista en direccin hacia arriba: direccin que es considerada hacia arriba
de la perspectiva del espectador.
Volumen de vista: porcin de un espacio virtual que presenta la visibilidad
de una vista.
VRP: punto de referencia, ojo o punto de vista. Es un punto que representa
la posicin del ojo o el centro de una proyeccin.

BIBLIOGRAFA
H. Sowizral, K.Rushforth, M. Deering, The Java 3D API Specification. (2nda Ed.)
(2000). Reading, EEUU: Addison-Wesley.
H. Zhang, D. Liang. Computer Graphics using JAVA 2D and 3D. (2007). Upper
Saddle River, EEUU: Pearson Prentice Hall.
J.Foley, A. Van Dam, S. Feiner, J.Hughs, R. Phillips. Introduction to Computer
Graphics. (1994). Reading, EEUU: Addison-Wesley.
L. Ammeraal. Computer Graphics for JAVA programmers. (1998). New York,
EEUU: Wiley.
R. Parent. Computer Animation Algorithms and Techniques. (2002). San
Francisco, EEUU: Morgan Kaufmann.
Enlaces de Internet:

147

http://opengl.org
http://jogl.dev.java.net
http://java.sun.com
http://java.sun.com/products/java-media/3D/index.jsp
http://j3d.org
https://java3d.dev.java.net/

148