You are on page 1of 98

PRIMITIVAS DE SALIDA

Curso de graficacin I

Contenido

Dibujo de puntos
Algoritmos comunes de trazo de rectas
Algoritmos comunes de trazo de crculos
Otras primitivas
Bibliotecas grficas en C y Java
Uso de primitivas de biblioteca
Principios de animacin
Mejora de la animacin

La pantalla grfica
0

Mxima x 1

x = 0, y = 0
0

Mxima y 1
x = Mxima x 1
y = Mxima y 1

Dibujo de puntos en C y Java


C
La funcin putpixel(int x, int y, int color) dibuja un
punto en la coordenada x,y con el color especificado.
Ejemplo: putpixel(50,25,7) dibuja un punto color gris en la
coordenada 50,25.

Java
En Java se dibuja en un objeto de la clase Graphics. No tiene una funcin
para dibujar puntos pero puede usarse:
Graphics g;
g.drawLine(50,25,50,25);

Ejemplo 1
#include <iostream>
#include <graphics.h>
using namespace std;
int main(int argc, char *argv[])
{
int i;
initwindow(400, 300);
for(i = 0; i< 1000; i++){
putpixel(rand()%400,rand()%300,rand()%15+1);
}
system("PAUSE");
closegraph();
return EXIT_SUCCESS;
}

Trazo de lneas rectas paralelas a


los ejes
La lnea recta es la ms fcil de dibujar
Las lneas rectas paralelas a los ejes se pueden trazar un un
simple lazo for.
El siguiente cdigo traza un lnea horizontal desde x a x+ancho.
for(i = x; i < x+ancho; i++)
putpixel(i,y,color);
De forma similar se traza un lnea vertical

Ejemplo
#include <iostream>
#include <graphics.h>
using namespace std;
void lineaH(int x1, int x2,int y, int color){
int dx;
dx = x2>x1?x2-x1:x1-x2;
for(int i=0;i<dx;i++)
putpixel(x1+i,y,color);
}
int main(int argc, char *argv[])
{
int i;
initwindow(400, 300);
for(i = 0; i< 1000; i++){
lineaH(rand()%100,rand()%300,rand()%300,rand()%15+1);
}
getch();
closegraph();
return EXIT_SUCCESS;
}

Tarea
Escriba funciones en C para dibujar a) una lnea vertical y b)
una lnea diagonal a 45 grados, utilizando la primitiva para
dibujar un punto.
Ponga los parmetros adecuados en cada caso.

Dibujo de Lneas Rectas


Una lnea recta debe dibujarse como una sucesin de pxeles.

Efecto de escalera que se produce cuando se genera una lnea


como una serie de pxeles.

Algoritmos para trazo de lneas


rectas
Algoritmo DDA, algoritmo incremental bsico
con aritmtica de punto flotante.
Algoritmo de Bresenham, algoritmo
incremental complejo con slo aritmtica
entera.

Algoritmo DDA
Ecuacin bsica de la recta

y m x b
m es la pendiente y b la interseccin con el eje y

y2 y1
m
x2 x1

b y1 m x1

Para cualquier intervalo x de x a lo largo de la recta,


se puede calcular el y correspondiente como:

y m x
Si la pendiente es positiva y menor que 1, se toman
variaciones de x iguales a 1 y se calcula y con:

yi 1 yi m
Las rectas con pendiente mayor que 1, se invierten
los papeles de x y de y.

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);
}
}

Algoritmo de lnea de Bresenham


Seccin de una pantalla
de despliegue donde se
desplegar un segmento
rectilneo, comenzando
desde la posicin (10,
10). Las posiciones de los
pixeles se representan por
las reas rectangulares
numeradas.

Trayectoria de la lnea especificada

13
12
11
10
9
10

11

12

13

14

Trayectoria de la lnea especificada

Seccin de una pantalla de


despliegue donde se
desplegar un segmento
rectilineo con pendiente
negativa, comenzando desde
la posicin (10, 12).

13
12
11
10
9
10

11

12

13

14

El siguiente pixel que se grafique en cada uno de estos


ejemplos ser aquel cuyo valor de y esta ms prximo a la
posicin real de y sobre la recta.

Seccin de una retcula de la


pantalla donde se desplegar
una lnea que pasar por:

x ,y
i

De aqu se tiene que:

y m x i 1 b

y = mx + b

y +2
i
y +1
i
y

i
x

x +1 x +2
i
i

Definimos:

d1 y y i

m x i 1 b y i

d 2 y i 1 y

y i 1 m x i 1 b

la diferencia es

d 2 d1 2m x i 1 2 y i 2b 1

Definimos pi como:

pi x ( d1 d 2 )
2 y xi 2 x yi c
donde c es:

c 2y x 2b 1

Obtenemos pi+1 de pi como:

pi 1 2 y xi 1 2 x yi 1 c

Restando pi+1 y pi:

pi 1 pi 2y x i 1 x i 2x y i 1 y i

Simplificando:

pi 1 pi 2y 2x y i1 y i
El parmetro inicial es:

p1 2 y x

1. De como entrada los extremos de la lnea. 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 x = x2 - x1, y = y2 - y1 y p1 = 2 y - x. 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 2y

y en el segundo

pi 1 pi 2 y x

5. Repita hasta que x llegue a x2.

void BresLine(int x1,int y1,int x2,int y2,int


color){
int xerr,yerr,deltax,deltay,dist,incx,incy,i;
xerr = 0;
yerr = 0;
deltax = x2-x1;
deltay = y2-y1;
if(deltax>0)
Funcin en C para dibujar rectas
incx = 1;
cualquier pendiente.
else
if(deltax==0)
incx = 0;
else
incx = -1;
if(deltay>0)
incy = 1;
else
if(deltay==0)
incy = 0;
else
incy = -1;

con

deltax = abs(deltax);
deltay = abs(deltay);
if(deltax>deltay)
dist = deltax;
else
dist = deltay;
for(i = 0; i<=dist+1;i++){
putpixel(x1,y1,color);
xerr = xerr+deltax;
yerr = yerr+deltay;
if(xerr>dist){
xerr -= dist;
x1 += incx;
}
if(yerr>dist){
yerr -= dist;
y1 += incy;
}
}
}

Primitivas bsicas en C
Define el color de la pluma
void setcolor (int color);
Regresa el color de la pluma actual
int getcolor (void);
Pone color de fondo
void setbkcolor(int color);
Regresa el color de fondo actual
int getbkcolor(void);
Borra el puerto de visin actual
clearviewport (void);

Primitivas de lneas en C
Dibuja lnea entre (x1,y1) y (x2,y2)
void line (int x1, int y1, int x2, int y2);
Dibuja lnea relativa al cursor grfico
void linerel (int dx, int dy);
Dibuja lnea desde el cursor grfico a (x,y)
void lineto (int x, int y);
Mueve cursor grfico en forma relativa
void moverel (int dx, int dy);

Mueve cursor grfico en forma absoluta


void moveto (int x, int y);

Polgono con line


void poligono(int x, int y, int r,int c, int
x,y
n){
/*dibuja un polgono regular de n lados con
r
centro en x,y inscrito en un crculo de
n
radio r y de color c*/
float PI = 3.1415926535;
float a = PI/2-PI/n;
int x1 = (int)(x-r*cos(a));
x r cos(), y + r sin()
int y1 = (int)(y+r*sin(a));
putpixel(x,y,c);
setcolor(c);
for(int i = 2; i<=n+1;i++){
a = a+2*PI/n;
int x2 = (int)(x-r*cos(a));
int y2 = (int)(y+r*sin(a));
line(x1,y1,x2,y2);
x1 = x2;
y1 = y2;
}
}

Polgono con linerel


void poligono(int x,int y,int n, int
d,int color){
int x0=x,y0=y,x1=x,y1=y,k;
double a=0,da=2*3.14159265358979/n;
moveto(x0,y0);
for(k = 0;k <n-1 ;k++){
x,y
d
x1 = (int)(x1+d*cos(a));
y1 = (int)(y1+d*sin(a));
a = a+da;
lineto(x1,y1);
}
lineto(x0,y0);
}

Tarea
Escriba una funcin que dibuje una estrella de 5 picos. Ponga
como parmetros las coordenadas del centro, la distancia del
centro a uno de los picos y el color.
Ayuda: note que los picos son vrtices de un pentgono.
Distancia centro pico

x, y

Proyectos
Hacer las siguientes primitivas con funciones en C. Utilice las
primitivas de lnea de graphics.h.

Algoritmos de generacin de
circunferencias
La ecuacin de la circunferencia
en coordenadas rectangulares es

De sta se puede despejar y


como sigue:

x xc 2 y yc 2

r
yc

y yc r x xc
2

xc

r2

Funcin en C
void PlotPoint(int xc,
int x, int y,int c)
{
putpixel(xc + x,yc +
putpixel(xc - x,yc +
putpixel(xc + x,yc putpixel(xc - x,yc putpixel(xc + y,yc +
putpixel(xc - y,yc +
putpixel(xc + y,yc putpixel(xc - y,yc }

int yc, void CircleSimple(int xc, int yc,


int r,int c){
int x,y;
double yr;
y,c);
x = 0;
y,c);
y = r;
y,c);
yr = r;
y,c);
PlotPoint(xc,yc,x,y,c);
x,c);
/* se cicla hasta trazar todo un
x,c);
octante */
x,c);
while (x < yr){
x,c);
x = x + 1;
yr = sqrt(r*r-x*x);
y = (int)round(yr);
PlotPoint(xc,yc,x,y,c);
}
}

Crculo bsico en Java


void CircleSimple(Graphics g, int xc, int yc, int r){
int x,y;
double yr;
x = 0;
y = r;
yr = r;
PlotPoint(x,y);
/* se cicla hasta trazar todo un octante */
while (x < yr){
x = x + 1;
yr = Math.sqrt(r*r-x*x);
y = (int)Math.round(yr);
PlotPoint(x,y);
}
}

Algoritmo de circunferencia de
Bresenham
Se supone (xi, yi) la posicin ms prxima a la trayectoria, la
siguiente posicin es por tanto (xi+1, yi) o bien (xi+1, yi-1).
x
y

x +1 x +2
i
i

y -1
i
y -2
i
2
2
2
x + y = r

Una medida de la diferencia de coordenadas puede definirse


como:
d1 y i2 y 2
y i2 r 2 x i 1

d 2 y y i 1
2

y
i
y

r x i 1 y i 1
2

- 1

x + 1
i

Definiendo pi como la diferencia de d1 y d2 tenemos

pi d1 d 2
2 x i 1 y y i 1 2r 2
2

2
i

1
2

El valor de pi+1 es:

pi 1 2 x i 1 1 y
2

2
i 1

y i 1 1 2r
2

Simplificando

pi1 pi 4 x i 6 2 y i21 y i2 2 y i 1 y i
p1 se obtiene de (x1, y1) = (0, r)

p1 3 2 r

1. Seleccione la primera posicin como

x , y 0, r
1

2. Calcule el primer parmetro como

p1 3 2r
si pi <0, la siguiente posicin es (xi+1,

yi), si no es (xi+1, yi-1)

3. Incremente x en 1. Seleccione pi+1 si pi <0 como

pi 1 pi 4 xi 6
y en caso contrario

pi 1 pi 4 x i y i 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= yi1 si pi 0.


4. Repita el paso 3 hasta que x y y sean iguales.

Algoritmo de punto medio para


la circunferencia
El mtodo de trazo del punto medio de la circunferencia se basa en la
definicin de la funcin circunferencia:

f circunferencia x, y x 2 y 2 r 2

Un punto (x,y) arbitrario cumple con lo siguiente


0, si x , y est dentro de la circunferencia

f circunferencia x , y 0, si x , y est en la frontera de la circunferencia


0, si x , y est fuera de la circunferencia

Para decidir entre el punto (xk+1, yk) y (xk+1, yk-1) se utiliza la


frmula anterior evaluada en el punto medio entre los dos pixeles
pk f circunferencia x k 1, y k 1 2

x k 1 y k 1 2 r 2
2

Si pk<0 el punto est dentro de la circunferencia y el pixel (xk+1,


yk) es el ms prximo a la frontera. Sino, el punto est fuera y el
ms cercano es (xk+1, yk-1).
Obtendremos una expresin recursiva para el siguiente parmetro
de decisin cuando evaluamos la funcin de circunferencia en la
posicin xk +1 = xk +2.

pk f circunferencia x k 1 1, y k 1 1 2

x k 1 1 y k 1 1 2 r 2

pk 1 pk 2 x k 1 y k21 y k2 y k 1 y k 1

Si pk<0, el incremento es 2xk +1 + 1. Sino el incremento es 2xk


2yk +1 +1. Los valores xk +1 y yk +1 se pueden calcular con:

2 y k 1 2 y k 2
2 xk 1 2 xk 2
El valor inicial es:

5
p0 r
4

Punto medio en C
void CircleMidPoint(int xc, int yc, int r, int c){
int x, y, p;
x = 0;
y = r;
p = 1 - r;
PlotPoint(xc,yc,x,y,c);
/* se cicla hasta trazar todo un octante */
while (x < y){
x = x + 1;
if (p < 0)
p = p + 2*x + 1;
else {
y = y - 1;
p = p + 2*(x - y) + 1;
}
PlotPoint(xc,yc,x,y,c);
}
}

Punto medio en Java


void CircleMidPoint(Graphics g, int xc, int yc, int r){
int x, y, p;
x = 0;
y = r;
p = 1 - r;
PlotPoint(g,xc,yc,x,y);
/* se cicla hasta trazar todo un octante */
while (x < y){
x = x + 1;
if (p < 0)
p = p + 2*x + 1;
else {
y = y - 1;
p = p + 2*(x - y) + 1;
}
PlotPoint(g,xc,yc,x,y);
}
}

Crculos en C
Dibuja un crculo
void circle (int x, int y, int r);
Dibuja un arco de circulo
Void arc (int x,int y,int stangle,int endangle,int radius );
Dibuja una elipse
void ellipse(int x, int y, int stangle, int endangle, int
xradius, int yradius);
Regresa las coordenadas del ltimo arco dibujado
void getarccoords(struct arccoordstype *arccoords);
Estructura utilizada por getarccoords
struct arccoordstype { int x, y; int xstart, ystart, xend,
yend; };

#include <iostream>
#include <graphics.h>

Ejemplo

using namespace std;


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;
}

Dibujo de una compuerta and


Centro de la compuerta: x, y
x 2*tamanio
y 2*tamanio

x + 2*tamanio
y 2*tamanio

x 4*tamanio
y tamanio

Arco con centro en: x + 2*tamanio, y


Radio de:2*tamanio de 0 a 90 grados.

x 2*tamanio
y tamanio

Arco con centro en: x + 2*tamanio, y+1


Radio de:2*tamanio de 270 a 360 grados.

x + 4*tamanio
y + tamanio

x + 6*tamanio, y

x + 2*tamanio
y + tamanio

x + 4*tamanio, y
x 2*tamanio
y + 2*tamanio

x +2 *tamanio
y +2 *tamanio

Dibujo de una compuerta and


void dibujaAnd(int x, int y, int size){
int x1 = x-2*size;
int y1 = y-2*size;
line(x1,y1,x1,y1+4*size);
line(x1,y1,x1+4*size,y1);
line(x1,y1+4*size,x1+4*size,y1+4*size);
line(x+4*size,y,x+5*size,y);
line(x-2*size,y+size,x-3*size,y+size);
line(x-2*size,y-size,x-3*size,y-size);
arc(x+2*size,y,0,90,2*size);
arc(x+2*size,y,270,360,2*size);
}

Dibujo de una compuerta or


Circulo con centro en: x-4*tqamanio, y
Radio de:4*tamanio.
viewport(x-2*tamanio,y-2*tamanio,
x+6*tamanio,y+2*tamanio)
x 2*tamanio
y 2*tamanio

Centro de la compuerta: x, y

x,y 2*tamanio
Arco con centro en: x, y+2*tamanio
Radio de:4*tamanio de 0 a 90 grados.
viewport(x,y-2*tamanio,x+6*tamanio,y)

x 4*tamanio
y tamanio
x 2*tamanio
y tamanio

Arco con centro en: x, y - 2*tamanio+1


Radio de:2*tamanio de 270 a 360 grados.
viewport(x,y,x+6*tamanio,y+2*tamanio)

x + 4*tamanio
y + tamanio

x + 4*tamanio*cos(30)+tamanio, y

x +2*tamanio
y +tamanio

x + 4*tamanio*cos(30), y
x 2*tamanio
y + 2*tamanio

x, y +2 *tamanio

Funcin para dibujar compuerta or


void dibujaOr(int x, int y, int size){
arccoordstype arco;
int x1 = x-2*size;
int y1 = y-2*size;
int xp,yp;
line(x1,y1,x1+2*size,y1);
line(x1,y1+4*size,x1+2*size,y1+4*size);
//arco superior delantero
setviewport(x,y-2*size,x+4*size,y,true);
arc(0,4*size,0,90,4*size);
//arco inferior delantero
setviewport(x,y,x+4*size,y+2*size+1,true);
arc(0,-2*size+1,270,360,4*size);
//arco trasero
setviewport(x-2*size,y-2*size,x,y+2*size,true);
xp = -(int)sqrt(4*size*4*size-4*size*size);
circle(xp,2*size,4*size);
setviewport(0,0,getmaxx(),getmaxy(),true);

//conexiones traseras
xp = x1+xp+(int)sqrt(4*size*4*size-size*size);
line(xp,y1+size,xp-size,y1+size);
line(xp,y1+3*size,xp-size,y1+3*size);
//conexione delantera
xp = x+(int)(4*size*cos(30*pi/180));
yp = y-2*size+(int)(4*size*sin(30*pi/180));
line(xp,yp,xp+size,yp);
}

Tarea
1. Basndose en las primitivas de compuertas and y or escriba
funciones para dibujar estas compuertas con diferentes
orientaciones: hacia arriba, hacia la izquierda y hacia abajo.
2. La primitiva drawOval(int x, int y, int w,
int h) de Java dibuja una elipse enmarcada en un rectngulo
como se muestra en la figura (las lneas punteadas no se
dibujan). Defina una primitiva equivalente para dibujar una
elipse en C utilizando la primitiva ellipse.
x, y
w

Otras primitivas
Rectngulos rellenos: Los rectngulos rellenos pueden
generarse fcilmente haciendo un barrido de lneas de rastreo
desde la primera coordenada y a la segunda. El siguiente
cdigo hace este trabajo:
void Rectangulo(int x1,int y1,int x2,int
y2){
int i;
for(i = y1;i<=y2; i++)
line(x1, i, x2, i);
}

Relleno de polgonos: el relleno opera calculando los tramos


que se hallan entre la arista de la izquierda y la derecha del
polgono. El algoritmo requiere conservar una lista ordenada
respecto a y de las aristas activas en cada fase del proceso.
Recorte de crculos: Se puede recortar todo el crculo respecto a
un rectngulo. Si el crculo lo intercepta, se divide en cuadrantes
y se aplica la prueba de aceptacin o rechazo trivial para cada
uno. Tambin se aceptar y rechazar a nivel de pxel..
Texto: el texto puede definirse mediante mapas de bits para cada
conjunto de caracteres. Se dibuja usando la funcin CopyPixel
del sistema.

Otras primitivas en C
void bar (int left, int top, int right, int bottom);
void bar3d (int left, int top, int right, int bottom,
int depth, int topflag);
void drawpoly (int numpoints, int *polypoints);
void fillellipse (int x, int y, int xradius, int
yradius);
void fillpoly (int numpoints, int *polypoints);
void floodfill (int x, int y, int border);
void pieslice (int x, int y, int stangle, int
endangle, int radius);
void rectangle (int left, int top, int right, int
bottom);
void sector (int x, int y, int stangle, int endangle,
int xradius, int yradius);
void setfillpattern (char *upattern, int color);
void setfillstyle (int pattern, int color);
void setlinestyle (int linestyle, unsigned upattern,
int thickness);

Algoritmo pastel
Algoritmo para dibujar un diagrama de pastel.
1. Iniciar ang = 0
2. Sum = suma de valores a representar
3. Para todos los valores hacer
4. Poner color del sector
5. Dibujar sector desde ang/suma*360 hasta
(ang + valor) /suma*360
6. Incrementar ang en valor
7. Fin para

Ejemplo, diagrama de pastel


#include <graphics.h>
void pastel(int n, float *a, int x, int y, int r){
float suma = 0,ang = 0;
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;
}

Primitivas de texto en C
Despliega una cadena de texto en la posicin 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 justificacin para el texto
void settextjustify (int horiz, int vert);
Define la fuente, direccin y el tamao del texto
void settextstyle (int font, int direction, int
charsize);
Define el tamao 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);

Primitivas de texto en C cont.


Constantes de texto
Justificacin vertical:
LEFT_TEXT, CENTER_TEXT, RIGHT_TEXT
Justificacin horizontal:
BOTTOM_TEXT, VCENTER_TEXT, TOP_TEXT
Fuentes:
DEFAULT_FONT, TRIPLEX_FONT, SMALL_FONT,
SANS_SERIF_FONT, GOTHIC_FONT, SCRIPT_FONT,
SIMPLEX_FONT, TRIPLEX_SCR_FONT, COMPLEX_FONT,
EUROPEAN_FONT, BOLD_FONT

Primitivas de texto en C cont.


Tipos
struct textsettingstype
{
int font;
// la fuente en uso
int direction; // direccin del Texto
int charsize; // tamao del carcter
int horiz;
// justificacin Horizontal
int vert;
// justificacin Vertical
};
void gettextsettings(struct textsettingstype
*texttypeinfo);

Primitivas de texto en C cont.


Otras formas de desplegar texto
Flujo de salida grfico:
std::ostringstream bgiout;
Igual a outtext:
outstream(std::ostringstream& out=bgiout);
Igual a outtextxy:
outstreamxy(int x, int y, std::ostringstream&
out=bgiout);

Ejemplo

Demo justificacin texto

ejemplo
/* outtext example */
#include <graphics.h>
int main(void){
/* request autodetection */
int midx, midy;
/* initialize graphics and local variables */
initwindow(300,100);
midx = getmaxx() / 2;
midy = getmaxy() / 2;
/* move the CP to the center of the screen */
moveto(midx, midy);
/* output text starting at the CP */
outtext("This ");
outtext("is ");
outtext("a ");
outtext("test.");
/* clean up */
getch();
closegraph();
return 0;
}

/* settextstyle example */
#include <graphics.h>
/* the names of the text styles supported */
char *fname[] = { "DEFAULT font", "TRIPLEX font",
"SMALL font",
"SANS SERIF_font",
"GOTHIC_font",
"SCRIPT font",
"SIMPLEX font", "TRIPLEX SCRIPT font",
"COMPLEX font", "EUROPEAN font",
"BOLD font"};
int main(void){
/* request autodetection */
int style, midx, midy;
int size = 1;
/* initialize graphics and local variables */
initwindow(600,200);
midx = getmaxx() / 2;
midy = getmaxy() / 2;
settextjustify(CENTER_TEXT, CENTER_TEXT);
for (style=DEFAULT_FONT; style<=BOLD_FONT; style++) {
cleardevice();
if (style == TRIPLEX_FONT)
size = 4;
/* select the text style */
settextstyle(style, HORIZ_DIR, size);
/* output a message */
outtextxy(midx, midy, fname[style]);
getch();
}
closegraph();
return 0;
}

Tarea
Escriba una funcin en C para
dibujar un diagrama de barras de
un conjunto de hasta 10 datos.
Incluya como parmetro un
arreglo de cadenas para las
leyendas.

Escriba una funcin en C para


dibujar un diagrama de pastel con
sectores resaltados de un conjunto
hasta de 10 datos. Incluya como
parmetro un arreglo de cadenas
para las leyendas.

Tarea
Haga una pequea animacin utilizando alguna de las tcnicas
revisadas.

Atributos de las primitivas en bgi


Atributos de lnea
Atributos de relleno
Atributos de caracteres

Atributos de lneas
En bgi existen tres atributos para las lneas
color
grosor
patrn

Color
El color se establece con setcolor(int color).
Existen 16 colores predefinidos, del 0 al 15:
BLACK

BLUE

GREEN

CYAN

RED

MAGENTA

BROWN

LIGHTGRAY

DARKGRAY

LIGHTBLUE

LIGHTGREEN

LIGHTCYAN

LIGHTRED

LIGHTMAGENTA

YELLOW

WHITE

La funcin COLOR(r, g, b) permite obtener cualquier color dados los


valores las componentes de rojo, verde y azul.la funcin converttorgb(c)
convierte a RGB de Windows.
RED_VALUE(v) regresa el valor de rojo de un color
GREEN_VALUE(v) regresa el valor de verde de un color
BLUE_VALUE(v) regresa el valor de azul de un color
IS_BGI_COLOR(v) regresa verdadero si el color es BGI
IS_RGB_COLOR(v) regresa verdadero si el color es RGB

Grosor y patrn
Existen dos grosores de lnea predefinidos, pero puede usarse cualquier
valor:
NORM_WIDTH
1
THICK_WIDTH
3
Los patrones de lnea son:
SOLID_LINE, DOTTED_LINE, CENTER_LINE,
DASHED_LINE, USERBIT_LINE
La funcin:
setlinestyle(int linestyle,unsigned upattern,int
thickness );
Establece el tipo de lnea. El patrn definido por el usuario se establece
con el entero sin signo upattern, cada bit de este entero de 16 bits
especifica si se pinta o no un pixel.

Actividad
Defina los siguientes patrones de lnea y dibuje
algunas lneas con estos patrones:

Patrones de relleno de reas


Para relleno de reas existen los siguientes patrones predefinidos:
EMPTY_FILL, SOLID_FILL, LINE_FILL, LTSLASH_FILL,
SLASH_FILL, BKSLASH_FILL, LTBKSLASH_FILL,
HATCH_FILL,
XHATCH_FILL, INTERLEAVE_FILL, WIDE_DOT_FILL,
CLOSE_DOT_FILL, USER_FILL
La funcin setfillstyle(int pattern,int color) define el
patrn de relleno y el color.
El relleno definido por el usuario se establece con
setfillpattern( char *upattern,int color) el patrn de
8x8 se define mediante un arreglo de 8 caracteres. El siguiente ejemplo
rellena con corazoncitos:
char pattern[] =
{0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00};
setfillpattern( pattern, 15 );
bar(200,200,300,300);

Actividad
Defina los siguientes patrones de lnea y dibuje
algunas figuras con estos patrones:

Funciones de manejo de ventanas


Se pueden crear varias ventanas de despliegue. La
funcin 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();

Actividad
Escriba un pequeo programa que cree dos ventanas y
deibuje algunas primitivas en cada una de ellas.

Manejo de imgenes
Se pueden manipular reas de la pantalla mediante las siguientes funciones:
imagesize( int left, int top, int right, int bottom ); - determina el tamao en bytes de
una regin de la ventana.
getimage( int left, int top, int right, int bottom, void *bitmap ); - lee una regin
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 dilogo.

Ejemplo de imgenes
#include <graphics.h>
main(){
initwindow(600,600);
setactivepage(0);
readimagefile("Creek.jpg",0,0,600,600);
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;

while(true){
c = getch();
if(c == '1') p =0;
if(c == '2') p =1;
if(c == '3') p =2;
if(c == '4') p =3;
if(c == 27) return 0;
setvisualpage(p);
}
}

Demo de getimage putimage


void PutImageDemo(void){
static int r
= 20;
static int StartX = 100;
static int StartY = 50;
struct viewporttype vp;
int PauseTime, x, y, ulx, uly, lrx, lry, size, i, width, height, step;
void *Saucer;
int MaxX,MaxY;
MaxX = getmaxx();
MaxY = getmaxy();
outtextxy(getmaxx()/2,0, "GetImage / PutImage
Demonstration");
getviewsettings( &vp );

/* Draw Saucer */
setfillstyle(SOLID_FILL,getmaxcolor());
fillellipse(StartX, StartY, r, (r/3)+2);
ellipse(StartX, StartY-4, 190, 357, r, r/3);
line(StartX+7, StartY-6, StartX+10, StartY-12);
circle(StartX+10, StartY-12, 2);
line(StartX-7, StartY-6, StartX-10, StartY-12);
circle(StartX-10, StartY-12, 2);
getch();
/* Read saucer image */
ulx = StartX-(r+1);
uly = StartY-14;
lrx = StartX+(r+1);
lry = StartY+(r/3)+3;
width = lrx - ulx + 1;
height = lry - uly + 1;
size = imagesize(ulx, uly, lrx, lry);

Saucer = malloc(size);
getimage(ulx, uly, lrx, lry, Saucer);
putimage(ulx, uly, Saucer, XOR_PUT);
/* Plot some "stars" */
for ( i=0 ; i<5000; ++i )
putpixel(rand()%(MaxX), rand()%(MaxY), rand()%
( getmaxcolor()-1 )+1);
x = MaxX / 2;
y = MaxY / 2;
PauseTime = 70;

while ( !kbhit() ) {
putimage(x, y, Saucer, XOR_PUT);
/* draw image */
delay(PauseTime);
putimage(x, y, Saucer, XOR_PUT);
/* erase image */
step = rand()%( 2*r );
//mover
if ((step/2) % 2 != 0 ) step = -1 * step;
x = x + step;
step = rand()%( r );
if ((step/2) % 2 != 0 )
step = -1 * step;
y = y + step;
if (vp.left + x + width - 1 > vp.right) x = vp.right-vp.left-width + 1;
else if (x < 0) x = 0;
if (vp.top + y + height - 1 > vp.bottom) y = vp.bottom-vp.top-height + 1;
else if (y < 0) y = 0;
}
free( Saucer );
getch();
}

Actividad
Haga un programa que lea dos imgenes seleccionadas
por el usuario y las muestre en ventanas separadas.

Haga un programa que dibuje la siguiente figura y


copie y pegue 10 copias de la figura en posiciones
aleatorias de la pantalla.
Color rosa
r = 255, g = 170, b = 170

Animacin simple
Una animacin simple puede lograrse como sigue:

Dibujar
Esperar N ms
Borrar
Actualizar

Animacin #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);
Esperar N ms
setcolor(BLACK);
setfillstyle(1,BLACK);
fillellipse(x,y,5,5);
x += vx;
Borrar
y += vy;
if(x>400 || x<0) vx =-vx;
Actualizar
if(y>300 || y<0) vy =-vy;
}
getch();
return 0;
}

Actividad
Haga una animacin que mueva 5 objetos a distintas
velocidades rebotando en la pantalla. Los objetos
deben dibujarse en diferentes colores.
Los objetos podran ser, por ejemplo un cuadro, un
crculo hueco, un tringulo, etc.

Dibujo de un carro
(x s, y 2s)
(x 2s, y s)

(x + s, y 2s)
(x + 2s, y s)

(x 3s, y s)
(x + 3s, y s)

(x 3s, y)
(x 2s, y + s/3)

(x, y)

(x + 3s, y)
(x + 2s, y + s/3)

Dibujo de un carro
void carro(int x, int y, int size){
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);
}

(x, y)

Actividad
Usando la tcnica anterior con linerel haga una
funcin para dibujar alguna de las siguientes figuras.
La figura debe poder dibujarse de cualquier tamao y
en cualquier posicin.

Animacin con un fondo


Borrar pantalla
Dibujar fondo
Dibujar
Esperar N ms

Actualizar

void carro(int x, int y, int size){


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);
}

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;
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;
}
}
}
}

Dibujo de un carro relleno


Se requiere usar

void carro(int x, int y, int size){


fillpoly para
int p[16];
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;
(x, y)
p[4] = x-size;
p[5] = y-2*size;
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);
}

Actividad
Modifique la figura de la actividad anterior para que se
dibuje con un relleno.

Dibujo de edificios
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];
}
}

Fondo #1
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;
}
}
}

Borrar pantalla
Dibujar fondo
Dibujar
Esperar N ms

Actualizar

Mejora de animacin con un fondo


Dibujar fondo
Dibujar
Esperar N ms
Borrar
Actualiza

Fondo #2
while(true){
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
El doble buffer hace uso de dos ventanas de salida, una visible
y otra no visible. Las funciones en C son:
setvisualpage(int n); establece la pgina
visual
setactivepage(p); establece la pgina
activa
swapbuffers( ); intercambia la pgina
visual y activa
int getactivepage( ); obtiene la pgina
activa
int getvisualpage( ); obtiene la pgina
visible

Animacin con doble buffer


Poner pgina
activa y visible
Dibujar fondo
Dibujar
Intercambiar
pginas
Actualiza

while(true){
//dibuja en la pgina oculta
setvisualpage(1-p);
setactivepage(p);
cleardevice();
fondo();
carro(x,200,8);
delay(10);
swapbuffers( );
p = 1-p;
x += d;
if(x <0 || x>400) d =-d;
if(kbhit()){
c = (char)getch();
switch(c){
case 27:return 0;
default: d =-d;
}
}
}

Poner pgina
activa y visible
Dibujar fondo
Dibujar
Intercambiar
pginas
Actualiza

Implementacin en C
main(){
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 pgina oculta
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;
}
}

You might also like