Beruflich Dokumente
Kultur Dokumente
Unidad II
Computación gráfica
Semana 8
Otras primitivas
Princípios de animación
Mejora de la animación
La pantalla gráfica
Máxima x – 1
Dibujo de puntos
x = 0, y = 0
Máxima y – 1
x = Máxima x – 1
y = Máxima y – 1
Dibujo de puntos en C y Java
C
Dibujo de puntos
Java
En Java se dibuja en un objeto de la clase Graphics. No tiene una función
para dibujar puntos pero puede usarse:
Graphics g;
g.drawLine(50,25,50,25);
Ejemplo 1
Dibujo de puntos
#include <iostream>
#include <graphics.h>
y2 y1
m b y1 m x1
x2 x1
Algoritmos comunes de trazos de líneas
Dy m Dx
yi 1 yi m
Las rectas con pendiente mayor que 1, se invierten
los papeles de x y de y.
Algoritmos comunes de trazos de líneas void dda(int x1,int y1,int x2,int y2,int color){
int dx,dy,steps,k;
float x_increment,y_increment,x,y;
dx = x2-x1;
dy = y2-y1;
if(abs(dx)>abs(dy))
steps = abs(dx);
else
steps = abs(dy);
if(steps==0)
steps = 1;
x_increment = (float)dx/steps;
y_increment = (float)dy/steps;
x = x1;
y = y1;
putpixel((int)x,(int)y,color);
for(k = 1;k <=steps ;k++){
x = x+x_increment;
y = y+y_increment;
putpixel((int)x,(int)y,color);
}
}
Algoritmos comunes de trazos de líneas
Algoritmo de línea de Bresenham
x , y
y +2
i
i i y +1
i
y
De aquí se tiene que: i
y m xi 1 b x
i
x +1 x +2
i i
Definimos:
d1 y yi d 2 y i 1 y
m xi 1 b y i y i 1 m x i 1 b
Algoritmos comunes de trazos de líneas
la diferencia es
d2 d1 2m xi 1 2 yi 2b 1
Definimos pi como:
pi Dx ( d1 d 2 )
2 Dy xi 2 Dx yi c
donde c es:
c 2Dy Dx 2b 1
Obtenemos pi+1 de pi como:
pi 1 2Dy xi 1 2Dx yi 1 c
Algoritmos comunes de trazos de líneas
Simplificando:
p1 2Dy Dx
Algoritmos comunes de trazos de líneas
1. De como entrada los extremos de la línea. Almacene el punto
del extremo izquierdo en (x1, y1) y el derecho en (x2, y2).
2. El primer punto que se selecciona para desplegar es el punto
del extremo izquierdo(x1, y1).
3. Calcule Dx = x2 - x1, Dy = y2 - y1 y p1 = 2 Dy - Dx. Si p1 = 0, el
siguiente punto será (x1 +1, y1), sino será (x1 +1, y1 +1).
4. Incremente x en 1. Se seleccionará yi o yi +1 dependiendo si pi
0 o pi 0. En el primer caso
pi 1 pi 2Dy
La ecuación de la circunferencia
en coordenadas rectangulares es x xc2 y yc 2 r2
y yc r 2 x xc
2
xc
Función en C
Algoritmos comunes para trazos de círculos
void PlotPoint(int xc, int yc, void CircleSimple(int xc, int yc, int
int x, int y,int c) r,int c){
{ int x,y;
putpixel(xc + x,yc + y,c); double yr;
putpixel(xc - x,yc + y,c); x = 0;
putpixel(xc + x,yc - y,c); y = r;
putpixel(xc - x,yc - y,c); yr = r;
putpixel(xc + y,yc + x,c); PlotPoint(xc,yc,x,y,c);
putpixel(xc - y,yc + x,c); /* se cicla hasta trazar todo un
putpixel(xc + y,yc - x,c); octante */
putpixel(xc - y,yc - x,c); while (x < yr){
} x = x + 1;
yr = sqrt(r*r-x*x);
y = (int)round(yr);
PlotPoint(xc,yc,x,y,c);
}
}
Círculo básico en Java
Algoritmos comunes para trazos de círculos
y
i
y -1
i
y -2
i
2 2 2
x + y = r
Una medida de la diferencia de coordenadas puede definirse
Algoritmos comunes para trazos de círculos
como:
d1 y i2 y 2
y
y i2 r 2 x i 1
2 i
y d
1
d
d 2 y y i 1
2 2
2 y - 1
i
r x i 1 y i 1
2 2 2
x + 1
i
pi d1 d 2
2 x i 1 y y i 1 2r 2
2 2 2
i
Algoritmos comunes para trazos de círculos
pi1 2 xi 1 1 y yi1 1 2r
2 2
2 2
i 1
Simplificando
p1 3 2r
1. Seleccione la primera posición como
x , y 0, r
Algoritmos comunes para trazos de círculos
1 1
pi 1 pi 4 xi 6
y en caso contrario
pi1 pi 4 xi yi 10
si pi+1 <0 el siguiente punto será(xi+2, yi+1). De lo contrario es (xi+2, yi+1 –
1). La coordenada y es yi+1=yi, si pi <0 o bien yi+1= yi–1 si pi 0.
4. Repita el paso 3 hasta que x y y sean iguales.
Algoritmos comunes para trazos de círculos
Algoritmo de punto medio para la
circunferencia
El método de trazo del punto medio de la circunferencia se basa en la
definición de la función circunferencia:
f circunferencia x, y x 2 y 2 r 2
x k 1 y k 1 2 r 2
2 2
x k 1 1 y k 1 1 2 r 2
2 2
o
pk 1 pk 2 xk 1 yk21 yk2 yk 1 yk 1
Dibuja un círculo
void circle (int x, int y, int r);
#include <iostream>
#include <graphics.h>
main(){
arccoordstype arco;
initwindow(300,300);
circle(100,100,50);
ellipse(200,100,45,270,50,100);
arc(200,200,0,135,50);
getarccoords(&arco);
cout << "x=" << arco.x << "\n";
cout << "y=" << arco.y << "\n";
cout << "xinicio=" << arco.xstart << "\n";
cout << "yinicio=" << arco.ystart << "\n";
cout << "xfin=" << arco.xend << "\n";
cout << "yfin=" << arco.yend << "\n";
getch();
return 0;
}
Rectángulos rellenos
int i;
for(i = 0; i<n; i++)
suma +=a[i];
for(i = 0; i<n; i++){
setfillstyle(1,i+1);
sector(x,y,(int)(ang/suma*360),(int)((ang+a[i])/suma*360),r,r);
ang += a[i];
}
}
main(){
float a[]={25.3,35.2,56.1,48.7,13.6};
initwindow(200,200);
pastel(5,a,100,100,60);
getch();
return 0;
}
Uso de primitivas de biblioteca
Primitivas de texto en C
Despliega una cadena de texto en la posición del CP
void outtext (char *textstring);
Despliega una cadena en la coordenada x,y
void outtextxy (int x, int y, char *textstring);
Define el tipo de justificación para el texto
void settextjustify (int horiz, int vert);
Define la fuente, dirección y el tamaño del texto
void settextstyle (int font, int direction, int
charsize);
Define el tamaño del texto
void setusercharsize (int multx, int divx, int multy,
int divy);
Regresa el alto de una cadena de texto
int textheight (char *textstring);
Regresa el ancho de una cadena de texto
int textwidth (char *textstring);
Uso de primitivas de biblioteca
Primitivas de texto en C cont.
Constantes de texto
Justificación vertical:
Justificación horizontal:
Fuentes:
std::ostringstream bgiout;
Igual a outtext:
outstream(std::ostringstream& out=bgiout);
Igual a outtextxy:
• Atributos de línea
• Atributos de relleno
• Atributos de caracteres
Uso de primitivas de biblioteca
Atributos de líneas
char pattern[] =
{0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00};
setfillpattern( pattern, 15 );
bar(200,200,300,300);
Uso de primitivas de biblioteca Funciones de manejo de
ventanas
Se pueden crear varias ventanas de despliegue. La
función initwindow(), regresa un entero que
permite identificar cada ventana.
Para establecer la ventana actual se utiliza
setcurrentwindow(int window);
Para determinar la ventana que está en uso se utiliza:
getcurrentwindow();
Uso de primitivas de biblioteca
Manejo de imágenes
Se pueden manipular áreas de la pantalla mediante las siguientes funciones:
imagesize( int left, int top, int right, int bottom ); - determina el tamaño en bytes de
una región de la ventana.
getimage( int left, int top, int right, int bottom, void *bitmap ); - lee una región
rectangular de la pantalla y almacena su contenido en la variable bitmap, se debe
reservar espacio para almacenar la imagen.
putimage( int left, int top, void *bitmap, int op ); - despliega la imagen previamente
almacenada en bitmap. op puede ser: COPY_PUT, XOR_PUT, OR_PUT, AND_PUT,
NOT_PUT
readimagefile(const char* filename=NULL, int left=0, int top=0, int
right=INT_MAX, int bottom=INT_MAX); - lee un archivo de imagen en cualquier
formato bmp, gif, jpg, ico, emf y wmf y lo muestra en el recuadro especificado.
writeimagefile(const char* filename=NULL,int left=0, int top=0, int
right=INT_MAX, int bottom=INT_MAX, bool active=true, HWND hwnd=NULL); -
Escribe el recuadro de la imagen en un archivo bmp.
Si el nombre del archivo es NULL se abre ventana de diálogo.
Uso de primitivas de biblioteca
Ejemplo de imágenes
while(true){
c = getch();
#include <graphics.h> if(c == '1') p =0;
if(c == '2') p =1;
main(){ if(c == '3') p =2;
initwindow(600,600); if(c == '4') p =3;
setactivepage(0); if(c == 27) return 0;
readimagefile("Creek.jpg",0,0,600,600); setvisualpage(p);
setactivepage(1); }
readimagefile("Desert Landscape.jpg",0,0,600,600); }
setactivepage(2);
readimagefile("Forest.jpg",0,0,600,600);
setactivepage(3);
readimagefile("Humpback Whale.jpg",0,0,600,600);
int p=0;
char c;
Uso de primitivas de biblioteca
Demo de getimage putimage
void PutImageDemo(void){
static int r = 20;
static int StartX = 100;
static int StartY = 50;
Dibujar
Esperar N ms
Borrar
Actualizar
Principios de animación
Animación #1
main(){
initwindow(400,300);
int x=rand()%400,y = rand()%50, vx = 5,vy = 5;
while(true){
setcolor(WHITE);
setfillstyle(1,WHITE); Dibujar
fillellipse(x,y,5,5);
delay(30);
setcolor(BLACK); Esperar N ms
setfillstyle(1,BLACK);
fillellipse(x,y,5,5);
}
x += vx; Borrar
y += vy;
if(x>400 || x<0) vx =-vx;
if(y>300 || y<0) vy =-vy; Actualizar
}
getch();
return 0;
}
Dibujo de un carro
(x – s, y – 2s)
Principios de animación
(x + s, y – 2s)
(x – 2s, y – s) (x + 2s, y – s)
(x – 3s, y – s)
(x + 3s, y – s)
(x, y) (x + 3s, y)
(x – 3s, y)
(x – 2s, y + s/3) (x + 2s, y + s/3)
Dibujo de un carro
Principios de animación
Borrar pantalla
Dibujar fondo
Dibujar
Esperar N ms
Actualizar
void carro(int x, int y, int size){
Principios de animación
moveto(x-3*size,y-(size));
linerel(size,0);
linerel(size,-size);
linerel(2*size,0);
linerel(size,size);
linerel(size,0);
linerel(0,size);
linerel(-6*size,0);
linerel(0,-size);
circle(x-2*size,y+size/2,2*size/3);
circle(x+2*size,y+size/2,2*size/3);
}
Principios de animación
void fondo(){
int x = 0;
int d[] = {30,60,50,80,30,30,50,30};
int h[] = {70,100,140,30,80,30,60,70};
for(int i=0;i<9; i++){
setfillstyle(1,i+3);
bar(x,200,x+d[i],200-h[i]);
x += d[i];
}
}
main(){
initwindow(400,400);
int x=0,d=3;
Principios de animación
char c;
while(true){
cleardevice();
setcolor(WHITE);
fondo();
carro(x,200,8);
delay(30);
x += d;
if(x <0 || x>400) d =-d;
if(kbhit()){
c = (char)getch();
switch(c){
case 27:return 0;
default: d =-d;
}
}
}
}
Principios de animación
Dibujo de un carro relleno
Se requiere usar
void carro(int x, int y, int size){
int p[16];
fillpoly para
setcolor(WHITE); rellenar el carro.
setfillstyle(SOLID_FILL,RED);
p[0] = x-3*size; p[1] = y-size;
p[2] = x-2*size; p[3] = y-size;
p[4] = x-size; p[5] = y-2*size; (x, y)
p[6] = x+size; p[7] = y-2*size;
p[8] = x+2*size; p[9] = y-size;
p[10] = x+3*size; p[11] = y-size;
p[12] = x+3*size; p[13] = y;
p[14] = x-3*size; p[15] = y;
fillpoly(8,p);
setcolor(BLACK);
setfillstyle(SOLID_FILL,BLACK);
fillellipse(x-2*size,y+size/3,2*size/3,2*size/3);
fillellipse(x+2*size,y+size/3,2*size/3,2*size/3);
}
Dibujo de edificios
Principios de animación
void fondo(){
int x = 0;
int d[] = {30,60,50,80,30,30,50,30};
int h[] = {70,100,140,30,80,30,60,70};
for(int i=0;i<9; i++){
setfillstyle(1,i+3);
bar(x,200,x+d[i],200-h[i]);
x += d[i];
}
}
Principios de animación
Fondo #1
while(true){
cleardevice();
setcolor(WHITE);
Borrar pantalla
fondo();
carro(x,200,8);
delay(30); Dibujar fondo
x += d;
if(x <0 || x>400) d =-d;
if(kbhit()){ Dibujar
c = (char)getch();
switch(c){
case 27:return 0; Esperar N ms
default: d =-d;
}
} Actualizar
}
Mejora de animación con un fondo
Mejora de la animación
Dibujar fondo
Dibujar
Esperar N ms
Borrar
Actualiza
Fondo #2
while(true){
Mejora de la animación
setcolor(WHITE);
fondo();
carro(x,200,8);
setcolor(BLACK);
delay(30);
carro(x,200,8);
x += d;
if(x <0 || x>400) d =-d;
if(kbhit()){
c = (char)getch();
switch(c){
case 27:return 0;
default: d =-d;
}
}
}
Doble buffer
Mejora de la animación
Poner página
activa y visible
Dibujar fondo
Dibujar
Intercambiar
páginas
Actualiza
while(true){
//dibuja en la página oculta
setvisualpage(1-p); Poner página
Mejora de la animación
initwindow(400,400);
setactivepage(1);
/* lee la imagen desde un archivo y la
dibuja en la pantalla invisible*/
readimagefile("PGS_img01.jpg",0,0,400,400);
size = imagesize(0, 0, 400, 400);
/* reserva memoria para la imagen */
img = malloc(size);
/* guarda le imagen en memoria */
getimage(0,0,400,400,img);
// fondo();
int x=0,d=6,p=0,size=10;
char c;
while(true){
setcolor(WHITE);
//dibuja en la página oculta
Mejora de la animación
setvisualpage(1-p);
setactivepage(p);
setbkcolor(WHITE);
cleardevice();
fondo();
carro(x,200,size);
delay(30);
swapbuffers( );
p = 1-p;
x += d;
if(x <0 || x>400) d =-d;
}
}
Técnicas de Realidad Virtual
Unidad II
Computación gráfica
Semana 8