Anda di halaman 1dari 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
x = 0, y = 0
0
Mxima x 1
Mxima y 1
0
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.
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.
Dibujo de Lneas Rectas
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
m
y y
x x
=

2 1
2 1
1 1
x m y b =
Para cualquier intervalo Ax de x a lo largo de la recta,
se puede calcular el Ay correspondiente como:
A A 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:
y y m
i i +
= +
1
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
9
10
11
12
13
10 11 12 13 14
Trayectoria de la lnea especificada
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.
9
10
11
12
13
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).
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.
x
i
x +1
i
x +2
i
y +2
i
y +1
i
y
i
y = mx + b
Seccin de una retcula de la
pantalla donde se desplegar
una lnea que pasar por:
De aqu se tiene que:
( )
y m x b
i
= + + 1
( )
d y y
m x b y
i
i i
1
1
=
= + +
( )
( )
d y y
y m x b
i
i i
2
1
1 1
= +
= + +
Definimos:
( )
x y
i i
,
la diferencia es
( )
d d m x y b
i i 2 1
2 1 2 2 1 = + +
p x d d
y x x y c
i
i i
=
= +
A
A A
( )
1 2
2 2
Definimos p
i
como:
donde c es:
( )
c y x b = + 2 2 1 A A
p y x x y c
i i i + + +
= +
1 1 1
2 2 A A
Obtenemos p
i+1
de p
i
como:
( ) ( )
p p y x x x y y
i i i i i i + + +
=
1 1 1
2 2 A A
Restando p
i+1
y p
i
:
( )
p p y x y y
i i i i + +
= +
1 1
2 2 A A
Simplificando:
El parmetro inicial es:
p y x
1
2 = A A
1. De como entrada los extremos de la lnea. Almacene el punto
del extremo izquierdo en (x
1
, y
1
) y el derecho en (x
2
, y
2
).
2. El primer punto que se selecciona para desplegar es el punto
del extremo izquierdo(x
1
, y
1
).
3. Calcule Ax = x
2
- x
1
, Ay = y
2
- y
1
y p
1
= 2 Ay - Ax. Si p
1
= 0, el
siguiente punto ser (x
1
+1, y
1
), sino ser (x
1
+1, y
1
+1).
4. Incremente x en 1. Se seleccionar y
i
o y
i
+1 dependiendo si p
i

< 0 o p
i
> 0. En el primer caso

y en el segundo

5. Repita hasta que x llegue a x
2
.
p p y
i i +
= +
1
2A
( ) p p y x
i i +
= +
1
2 A A
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)
incx = 1;
else
if(deltax==0)
incx = 0;
else
incx = -1;
if(deltay>0)
incy = 1;
else
if(deltay==0)
incy = 0;
else
incy = -1;
Funcin en C para dibujar rectas con
cualquier pendiente.
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 n){
/*dibuja un polgono regular de n lados con
centro en x,y inscrito en un crculo de
radio r y de color c*/
float PI = 3.1415926535;
float a = PI/2-PI/n;
int x1 = (int)(x-r*cos(a));
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;
}
}
o
o = t/n
r
x,y
x r cos(o), y + r sin(o)
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++){
x1 = (int)(x1+d*cos(a));
y1 = (int)(y1+d*sin(a));
a = a+da;
lineto(x1,y1);
}
lineto(x0,y0);
}
x,y d
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.
x, y
Distancia centro pico
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
( ) ( )
2
2 2
r yc y xc x = +
yc
xc
r
De sta se puede despejar y
como sigue:
( ) y yc r x xc =
2
2
Funcin en C
void PlotPoint(int xc, int yc,
int x, int y,int c)
{
putpixel(xc + x,yc + y,c);
putpixel(xc - x,yc + y,c);
putpixel(xc + x,yc - y,c);
putpixel(xc - x,yc - y,c);
putpixel(xc + y,yc + x,c);
putpixel(xc - y,yc + x,c);
putpixel(xc + y,yc - x,c);
putpixel(xc - y,yc - x,c);
}
void CircleSimple(int xc, int yc,
int r,int c){
int x,y;
double yr;
x = 0;
y = r;
yr = r;
PlotPoint(xc,yc,x,y,c);
/* se cicla hasta trazar todo un
octante */
while (x < yr){
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 (x
i
, y
i
) la posicin ms prxima a la trayectoria, la
siguiente posicin es por tanto (x
i
+1, y
i
) o bien (x
i
+1, y
i
-1).
x
i
x + 1
i
x + 2
i
y - 2
i
y - 1
i
y
i
x + y = r
2 2 2
Una medida de la diferencia de coordenadas puede definirse
como:
( )
d y y
y r x
i
i i
1
2 2
2 2
2
1
=
= + +
( )
( ) ( )
d y y
r x y
i
i i
2
2
2
2
2 2
1
1 1
=
= +
y
i
y
y - 1
i
d
1
d
2
x + 1
i
Definiendo p
i
como la diferencia de d
1
y d
2
tenemos
( ) ( )
p d d
x y y r
i
i i i
=
= + + +
1 2
2
2
2
2
2 1 1 2
( )
| |
( )
p x y y r
i i i i + + +
= + + + +
1
2
1
2
1
2
2
2 1 1 1 2
( ) ( )
p p x y y y y
i i i i i i i + + +
= + + +
1 1
2 2
1
4 6 2 2
El valor de p
i+1
es:
Simplificando
p
1
se obtiene de (x
1
, y
1
) = (0, r)
p r
1
3 2 =
1. Seleccione la primera posicin como

2. Calcule el primer parmetro como

si p
i
<0, la siguiente posicin es (x
i
+1, y
i
), si no es (x
i
+1, y
i
-1)
3. Incremente x en 1. Seleccione p
i+1
si p
i
<0 como

y en caso contrario

si p
i+1
<0 el siguiente punto ser(x
i
+2, y
i+1
). De lo contrario es (x
i
+2, y
i+1

1). La coordenada y es y
i+1
=y
i
, si p
i
<0 o bien y
i+1
= y
i
1 si p
i
> 0.
4. Repita el paso 3 hasta que x y y sean iguales.
( )
( ) x y r
1 1
0 , , =
p r
1
3 2 =
p p x
i i i +
= + +
1
4 6
( ) p p x y
i i i i +
= + +
1
4 10
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
:
( )
2 2 2
, r y x y x f
ncia circunfere
+ =
Un punto (x,y) arbitrario cumple con lo siguiente

( )
( )
( )
( )
f x y
si x y est dentro de la circunferencia
si x y est en la frontera de la circunferencia
si x y est fuera de la circunferencia
circunferencia
,
, ,
, ,
, ,
=
<
=
>

0
0
0
( )
( ) ( )
p f x y
x y r
k circunferencia k k
k k
= +
= + +
1 1 2
1 1 2
2 2
2
,
Para decidir entre el punto (x
k
+1, y
k
) y (x
k
+1, y
k
-1) se utiliza la
frmula anterior evaluada en el punto medio entre los dos pixeles
Si p
k
<0 el punto est dentro de la circunferencia y el pixel (x
k
+1,
y
k
) es el ms prximo a la frontera. Sino, el punto est fuera y el
ms cercano es (x
k
+1, y
k
-1).
Obtendremos una expresin recursiva para el siguiente parmetro
de decisin cuando evaluamos la funcin de circunferencia en la
posicin x
k
+1 = x
k
+2.
( )
( )
| |
( )
p f x y
x y r
k circunferencia k k
k k
= +
= + + +
+ +
+
1 1
2
1
2
2
1 1 2
1 1 1 2
,
( ) ( ) ( ) p p x y y y y
k k k k k k k + + +
= + + + +
1 1
2 2
1
2 1 1
o
Si p
k
<0, el incremento es 2x
k +1
+ 1. Sino el incremento es 2x
k

2y
k +1
+1. Los valores x
k +1
y y
k +1
se pueden calcular con:


2 2 2
1
x x
k k +
= +
2 2 2
1
y y
k k +
=
p r
0
5
4
=
El valor inicial es:
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>

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;
}
Ejemplo
Dibujo de una compuerta and
Centro de la compuerta: x, y
x 2*tamanio
y 2*tamanio
x 2*tamanio
y + 2*tamanio
x +2 *tamanio
y +2 *tamanio
x + 2*tamanio
y 2*tamanio
Arco con centro en: x + 2*tamanio, y
Radio de:2*tamanio de 0 a 90 grados.
Arco con centro en: x + 2*tamanio, y+1
Radio de:2*tamanio de 270 a 360 grados.
x + 4*tamanio, y
x + 6*tamanio, y
x 4*tamanio
y tamanio
x 2*tamanio
y tamanio
x + 4*tamanio
y + tamanio
x + 2*tamanio
y + 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
Centro de la compuerta: x, y
x 2*tamanio
y + 2*tamanio
x, y +2 *tamanio
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*cos(30), y
x + 4*tamanio*cos(30)+tamanio, y
x +2*tamanio
y +tamanio
x 4*tamanio
y tamanio
x 2*tamanio
y tamanio
x + 4*tamanio
y + tamanio
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)
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 2*tamanio
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
h
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
#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;
}
Ejemplo, diagrama de pastel
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
main(){
initwindow(400,300);
int x=rand()%400,y = rand()%50, vx = 5,vy = 5;
while(true){
setcolor(WHITE);
setfillstyle(1,WHITE);
fillellipse(x,y,5,5);
delay(30);
setcolor(BLACK);
setfillstyle(1,BLACK);
fillellipse(x,y,5,5);
x += vx;
y += vy;
if(x>400 || x<0) vx =-vx;
if(y>300 || y<0) vy =-vy;
}
getch();
return 0;
}
Animacin #1
Dibujar
Esperar N ms
Borrar
Actualizar
}
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, y)
(x 3s, y s)
(x 2s, y s)
(x s, y 2s)
(x + 2s, y s)
(x + 3s, y s)
(x + 3s, y)
(x 3s, y)
(x + s, y 2s)
(x 2s, y + s/3) (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
Esperar N ms
Actualizar
Dibujar fondo
Dibujar
Borrar pantalla
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
void carro(int x, int y, int size){
int p[16];
setcolor(WHITE);
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;
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);
}
(x, y)
Se requiere usar
fillpoly para
rellenar el carro.
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;
}
}
}
Esperar N ms
Actualizar
Dibujar fondo
Dibujar
Borrar pantalla
Mejora de animacin con un fondo
Esperar N ms
Borrar
Actualiza
Dibujar fondo
Dibujar
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;
}
}

Anda mungkin juga menyukai