primitivas de salida

98
PRIMITIVAS DE SALIDA Curso de graficación I

Upload: cachez

Post on 16-Jan-2016

86 views

Category:

Documents


0 download

DESCRIPTION

PRIMITIVAS DE SALIDA. Curso de graficación I. Contenido. Dibujo de puntos Algoritmos comunes de trazo de rectas Algoritmos comunes de trazo de círculos Otras primitivas Bibliotecas gráficas en C y Java Uso de primitivas de biblioteca Principios de animación Mejora de la animación. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: PRIMITIVAS DE SALIDA

PRIMITIVAS DE SALIDA

Curso de graficación I

Page 2: PRIMITIVAS DE SALIDA

Contenido

• Dibujo de puntos• Algoritmos comunes de trazo de rectas• Algoritmos comunes de trazo de círculos• Otras primitivas• Bibliotecas gráficas en C y Java• Uso de primitivas de biblioteca• Principios de animación• Mejora de la animación

Page 3: PRIMITIVAS DE SALIDA

La pantalla gráfica

x = 0, y = 0

0 Máxima x – 1

Máxima y – 1

0

x = Máxima x – 1

y = Máxima y – 1

Page 4: PRIMITIVAS DE SALIDA

Dibujo de puntos en C y JavaC

La función 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 función para dibujar puntos pero puede usarse:

Graphics g;

g.drawLine(50,25,50,25);

Page 5: PRIMITIVAS DE SALIDA

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

Page 6: PRIMITIVAS DE SALIDA

Trazo de líneas rectas paralelas a los ejes

La línea recta es la más fácil de dibujarLas líneas rectas paralelas a los ejes se pueden trazar un un simple lazo for.

El siguiente código traza un línea horizontal desde x a x+ancho.

for(i = x; i < x+ancho; i++) putpixel(i,y,color);

De forma similar se traza un línea vertical

Page 7: PRIMITIVAS DE SALIDA

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

Page 8: PRIMITIVAS DE SALIDA

Tarea

Escriba funciones en C para dibujar a) una línea vertical y b) una línea diagonal a 45 grados, utilizando la primitiva para dibujar un punto.

Ponga los parámetros adecuados en cada caso.

Page 9: PRIMITIVAS DE SALIDA

Una línea recta debe dibujarse como una sucesión de píxeles.

Efecto de escalera que se produce cuando se genera una línea

como una serie de píxeles.

Dibujo de Líneas Rectas

Page 10: PRIMITIVAS DE SALIDA

Algoritmos para trazo de líneas rectas

•Algoritmo DDA, algoritmo incremental básico con aritmética de punto flotante.

•Algoritmo de Bresenham, algoritmo incremental complejo con sólo aritmética entera.

Page 11: PRIMITIVAS DE SALIDA

Algoritmo DDA

Ecuación básica de la recta

y m x b

m es la pendiente y b la intersección con el eje y

my y

x x

2 1

2 111 xmyb

Page 12: PRIMITIVAS DE SALIDA

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:

y y mi i 1

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

Page 13: PRIMITIVAS DE SALIDA

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

Page 14: PRIMITIVAS DE SALIDA

Algoritmo de línea de Bresenham

9

10

11

12

13

10 11 12 13 14

Trayectoria de la línea especificadaSección de una pantalla de despliegue donde se desplegará un segmento rectilíneo, comenzando desde la posición (10, 10). Las posiciones de los pixeles se representan por las áreas rectangulares numeradas.

Page 15: PRIMITIVAS DE SALIDA

9

10

11

12

13

10 11 12 13 14

Trayectoria de la línea especificada

Sección de una pantalla de despliegue donde se desplegará un segmento rectilineo con pendiente negativa, comenzando desde la posición (10, 12).

El siguiente pixel que se grafique en cada uno de estos ejemplos será aquel cuyo valor de y esta más próximo a la posición real de y sobre la recta.

Page 16: PRIMITIVAS DE SALIDA

xi

x +1i

x +2i

y +2i

y +1i

yi

y = mx + bSección de una retícula de la pantalla donde se desplegará una línea que pasará por:

De aquí se tiene que:

y m x bi 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 yi i,

Page 17: PRIMITIVAS DE SALIDA

la diferencia es

d d m x y bi i2 1 2 1 2 2 1

p x d d

y x x y ci

i i

( )1 2

2 2

Definimos pi como:

donde c es:

c y x b 2 2 1

p y x x y ci i i 1 1 12 2

Obtenemos pi+1 de pi como:

Page 18: PRIMITIVAS DE SALIDA

p p y x x x y yi i i i i i 1 1 12 2

Restando pi+1 y pi:

p p y x y yi i i i 1 12 2

Simplificando:

El parámetro inicial es:

p y x1 2

Page 19: PRIMITIVAS DE SALIDA

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

 y en el segundo

 5. Repita hasta que x llegue a x2.

p p yi i 1 2

p p y xi i 1 2

Page 20: PRIMITIVAS DE SALIDA

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;

Función en C para dibujar rectas con cualquier pendiente.

Page 21: PRIMITIVAS DE SALIDA

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

Page 22: PRIMITIVAS DE SALIDA

Primitivas básicas en CDefine 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 visión actual

clearviewport (void);

Page 23: PRIMITIVAS DE SALIDA

Primitivas de líneas en CDibuja línea entre (x1,y1) y (x2,y2)

void line (int x1, int y1, int x2, int y2);

Dibuja línea relativa al cursor gráfico

void linerel (int dx, int dy);

Dibuja línea desde el cursor gráfico a (x,y)

void lineto (int x, int y);

Mueve cursor gráfico en forma relativa

void moverel (int dx, int dy);

Mueve cursor gráfico en forma absoluta

void moveto (int x, int y);

Page 24: PRIMITIVAS DE SALIDA

Polígono con line

void poligono(int x, int y, int r,int c, int n){/*dibuja un polígono regular de n lados con centro en x,y inscrito en un círculo 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; }}

n

r

x,y

x – r cos(), y + r sin()

Page 25: PRIMITIVAS DE SALIDA

Polígono 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

Page 26: PRIMITIVAS DE SALIDA

Tarea

Escriba una función que dibuje una estrella de 5 picos. Ponga como parámetros las coordenadas del centro, la distancia del centro a uno de los picos y el color.

Ayuda: note que los picos son vértices de un pentágono.

x, y

Distancia centro pico

Page 27: PRIMITIVAS DE SALIDA

ProyectosHacer las siguientes primitivas con funciones en C. Utilice las primitivas de línea de graphics.h.

Page 28: PRIMITIVAS DE SALIDA

Algoritmos de generación de circunferencias

La ecuación de la circunferencia en coordenadas rectangulares es 222 rycyxcx

yc

xc

rDe ésta se puede despejar y como sigue:

y yc r x xc 2 2

Page 29: PRIMITIVAS DE SALIDA

Función en Cvoid 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); }}

Page 30: PRIMITIVAS DE SALIDA

Círculo básico 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);  }}

Page 31: PRIMITIVAS DE SALIDA

Algoritmo de circunferencia de Bresenham

Se supone (xi, yi) la posición más próxima a la trayectoria, la siguiente posición es por tanto (xi+1, yi) o bien (xi+1, yi-1).

xi

x + 1i

x + 2i

y - 2i

y - 1i

yi

x + y = r22 2

Page 32: PRIMITIVAS DE SALIDA

Una medida de la diferencia de coordenadas puede definirse como:

d y y

y r x

i

i i

12 2

2 2 21

d y y

r x y

i

i i

22 2

2 2 2

1

1 1

yi

y

y - 1i

d1

d2

x + 1i

Definiendo pi como la diferencia de d1 y d2 tenemos

p d d

x y y r

i

i i i

1 2

2 2 2 22 1 1 2

Page 33: PRIMITIVAS DE SALIDA

p x y y ri i i i 1

2

12

1

2 22 1 1 1 2

p p x y y y yi i i i i i i 1 12 2

14 6 2 2

El valor de pi+1 es:

Simplificando

p1 se obtiene de (x1, y1) = (0, r)

p r1 3 2

Page 34: PRIMITIVAS DE SALIDA

1. Seleccione la primera posición como

2. Calcule el primer parámetro como

si pi <0, la siguiente posición es (xi+1, yi), si no es (xi+1, yi-1)

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

y en caso contrario

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.

x y r1 1 0, ,

p r1 3 2

p p xi i i 1 4 6

p p x yi i i i 1 4 10

Page 35: PRIMITIVAS DE SALIDA

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:

222, ryxyxf nciacircunfere

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 circunferenciacircunferencia ,

, ,

, ,

, ,

0

0

0

Page 36: PRIMITIVAS DE SALIDA

p f x y

x y r

k circunferencia k k

k k

1 1 2

1 1 22 2 2

,

Para decidir entre el punto (xk+1, yk) y (xk+1, yk-1) se utiliza la fórmula anterior evaluada en el punto medio entre los dos pixeles

Si pk<0 el punto está dentro de la circunferencia y el pixel (xk+1, yk) es el más próximo a la frontera. Sino, el punto está fuera y el más cercano es (xk+1, yk-1).

Obtendremos una expresión recursiva para el siguiente parámetro de decisión cuando evaluamos la función de circunferencia en la posición xk +1 = xk +2.

Page 37: PRIMITIVAS DE SALIDA

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 yk k k k k k k 1 12 2

12 1 1

o

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 2 21x xk k 2 2 21y yk k

p r0

5

4

El valor inicial es:

Page 38: PRIMITIVAS DE SALIDA

Punto medio en Cvoid 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); }}

Page 39: PRIMITIVAS DE SALIDA

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

Page 40: PRIMITIVAS DE SALIDA

Círculos en CDibuja un círculo

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 getarccoordsstruct arccoordstype { int x, y; int xstart, ystart, xend, yend; };

Page 41: PRIMITIVAS DE SALIDA

#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

Page 42: PRIMITIVAS DE SALIDA

Dibujo de una compuerta andCentro de la compuerta: x, y

x – 2*tamanioy – 2*tamanio

x – 2*tamanioy + 2*tamanio

x +2 *tamanioy +2 *tamanio

x + 2*tamanioy – 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*tamanioy – tamanio

x – 2*tamanioy – tamanio

x + 4*tamanioy + tamanio

x + 2*tamanioy + tamanio

Page 43: PRIMITIVAS DE SALIDA

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

Page 44: PRIMITIVAS DE SALIDA

Dibujo de una compuerta orCentro de la compuerta: x, y

x – 2*tamanioy + 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*tamanioy +tamanio

x – 4*tamanioy – tamanio

x – 2*tamanioy – tamanio

x + 4*tamanioy + 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+1Radio de:2*tamanio de 270 a 360 grados.viewport(x,y,x+6*tamanio,y+2*tamanio)

x – 2*tamanioy – 2*tamanio

Page 45: PRIMITIVAS DE SALIDA

Función para dibujar compuerta orvoid 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);

Page 46: PRIMITIVAS DE SALIDA

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

Page 47: PRIMITIVAS DE SALIDA

Tarea1. Basándose 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 rectángulo como se muestra en la figura (las líneas punteadas no se dibujan). Defina una primitiva equivalente para dibujar una elipse en C utilizando la primitiva ellipse.

x, yw

h

Page 48: PRIMITIVAS DE SALIDA

Otras primitivas

Rectángulos rellenos: Los rectángulos rellenos pueden generarse fácilmente haciendo un barrido de líneas de rastreo desde la primera coordenada y a la segunda. El siguiente código 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);

}

Page 49: PRIMITIVAS DE SALIDA

Relleno de polígonos: el relleno opera calculando los tramos que se hallan entre la arista de la izquierda y la derecha del polígono. El algoritmo requiere conservar una lista ordenada respecto a y de las aristas activas en cada fase del proceso.

Recorte de círculos: Se puede recortar todo el círculo respecto a un rectángulo. Si el círculo lo intercepta, se divide en cuadrantes y se aplica la prueba de aceptación o rechazo trivial para cada uno. También se aceptar y rechazar a nivel de píxel..

Texto: el texto puede definirse mediante mapas de bits para cada conjunto de caracteres. Se dibuja usando la función CopyPixel del sistema.

Page 50: PRIMITIVAS DE SALIDA

Otras primitivas en Cvoid 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);

Page 51: PRIMITIVAS DE SALIDA

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

Page 52: PRIMITIVAS DE SALIDA

#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

Page 53: PRIMITIVAS DE SALIDA

Primitivas de texto en CDespliega 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);

Page 54: PRIMITIVAS DE SALIDA

Primitivas de texto en C cont.

Constantes de textoJustificación vertical:

LEFT_TEXT, CENTER_TEXT, RIGHT_TEXT

Justificación 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

Page 55: PRIMITIVAS DE SALIDA

Primitivas de texto en C cont.

Tipos

struct textsettingstype{ int font; // la fuente en uso int direction; // dirección del Texto int charsize; // tamaño del carácter int horiz; // justificación Horizontal int vert; // justificación Vertical};

void gettextsettings(struct textsettingstype *texttypeinfo);

Page 56: PRIMITIVAS DE SALIDA

Primitivas de texto en C cont.

Otras formas de desplegar texto

Flujo de salida gráfico:

std::ostringstream bgiout;

Igual a outtext:

outstream(std::ostringstream& out=bgiout);

Igual a outtextxy:

outstreamxy(int x, int y, std::ostringstream& out=bgiout);

Page 57: PRIMITIVAS DE SALIDA

Ejemplo

Demo justificación texto

Page 58: PRIMITIVAS DE SALIDA

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

Page 59: PRIMITIVAS DE SALIDA

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

Page 60: PRIMITIVAS DE SALIDA

TareaEscriba una función en C para dibujar un diagrama de barras de un conjunto de hasta 10 datos. Incluya como parámetro un arreglo de cadenas para las leyendas.

Escriba una función en C para dibujar un diagrama de pastel con sectores resaltados de un conjunto hasta de 10 datos. Incluya como parámetro un arreglo de cadenas para las leyendas.

Page 61: PRIMITIVAS DE SALIDA

TareaHaga una pequeña animación utilizando alguna de las técnicas revisadas.

Page 62: PRIMITIVAS DE SALIDA

Atributos de las primitivas en bgi

• Atributos de línea

• Atributos de relleno

• Atributos de caracteres

Page 63: PRIMITIVAS DE SALIDA

Atributos de líneas

En bgi existen tres atributos para las líneas

color

grosor

patrón

Page 64: PRIMITIVAS DE SALIDA

ColorEl 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 función COLOR(r, g, b) permite obtener cualquier color dados los valores las componentes de rojo, verde y azul.la función 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

Page 65: PRIMITIVAS DE SALIDA

Grosor y patrónExisten dos grosores de línea predefinidos, pero puede usarse cualquier valor:

NORM_WIDTH 1THICK_WIDTH 3

Los patrones de línea son:

SOLID_LINE, DOTTED_LINE, CENTER_LINE,

DASHED_LINE, USERBIT_LINE

La función:

setlinestyle(int linestyle,unsigned upattern,int thickness );

Establece el tipo de línea. El patrón 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.

Page 66: PRIMITIVAS DE SALIDA

Actividad

Defina los siguientes patrones de línea y dibuje algunas líneas con estos patrones:

Page 67: PRIMITIVAS DE SALIDA

Patrones de relleno de áreasPara 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 función setfillstyle(int pattern,int color) define el patrón de relleno y el color.El relleno definido por el usuario se establece con setfillpattern( char *upattern,int color) el patrón 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);

Page 68: PRIMITIVAS DE SALIDA

Actividad

Defina los siguientes patrones de línea y dibuje algunas figuras con estos patrones:

Page 69: PRIMITIVAS DE SALIDA

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

Page 70: PRIMITIVAS DE SALIDA

Actividad

Escriba un pequeño programa que cree dos ventanas y deibuje algunas primitivas en cada una de ellas.

Page 71: PRIMITIVAS DE SALIDA

Manejo de imágenesSe 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.

Page 72: PRIMITIVAS DE SALIDA

Ejemplo de imágenes#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); }}

Page 73: PRIMITIVAS DE SALIDA

Demo de getimage putimagevoid 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 );

Page 74: PRIMITIVAS DE SALIDA

/* 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);

Page 75: PRIMITIVAS DE SALIDA

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;

Page 76: PRIMITIVAS DE SALIDA

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

Page 77: PRIMITIVAS DE SALIDA

ActividadHaga un programa que lea dos imágenes 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

Page 78: PRIMITIVAS DE SALIDA

Animación simple

Una animación simple puede lograrse como sigue:

Dibujar

Esperar N ms

Borrar

Actualizar

Page 79: PRIMITIVAS DE SALIDA

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

Animación #1

Dibujar

Esperar N ms

Borrar

Actualizar}

Page 80: PRIMITIVAS DE SALIDA

Actividad

Haga una animación que mueva 5 objetos a distintas velocidades rebotando en la pantalla. Los objetos deben dibujarse en diferentes colores.

Los objetos podrían ser, por ejemplo un cuadro, un círculo hueco, un triángulo, etc.

Page 81: PRIMITIVAS DE SALIDA

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)

Page 82: PRIMITIVAS DE SALIDA

Dibujo de un carrovoid 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)

Page 83: PRIMITIVAS DE SALIDA

ActividadUsando la técnica anterior con linerel haga una función para dibujar alguna de las siguientes figuras.

La figura debe poder dibujarse de cualquier tamaño y en cualquier posición.

Page 84: PRIMITIVAS DE SALIDA

Animación con un fondo

Esperar N ms

Actualizar

Dibujar fondo

Dibujar

Borrar pantalla

Page 85: PRIMITIVAS DE SALIDA

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

Page 86: PRIMITIVAS DE SALIDA

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

Page 87: PRIMITIVAS DE SALIDA

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

Page 88: PRIMITIVAS DE SALIDA

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.

Page 89: PRIMITIVAS DE SALIDA

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

Page 90: PRIMITIVAS DE SALIDA

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

Page 91: PRIMITIVAS DE SALIDA

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

Page 92: PRIMITIVAS DE SALIDA

Mejora de animación con un fondo

Esperar N ms

Borrar

Actualiza

Dibujar fondo

Dibujar

Page 93: PRIMITIVAS DE SALIDA

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

Page 94: PRIMITIVAS DE SALIDA

Doble bufferEl 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 página visualsetactivepage(p); establece la página activaswapbuffers( ); intercambia la página visual y activaint getactivepage( ); obtiene la página activaint getvisualpage( ); obtiene la página visible

Page 95: PRIMITIVAS DE SALIDA

Animación con doble buffer

Poner páginaactiva y visible

Dibujar fondo

Dibujar

Intercambiarpáginas

Actualiza

Page 96: PRIMITIVAS DE SALIDA

while(true){ //dibuja en la página 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 páginaactiva y visible

Dibujar fondo

Dibujar

Intercambiarpáginas

Actualiza

Page 97: PRIMITIVAS DE SALIDA

Implementación en Cmain(){ 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;

Page 98: PRIMITIVAS DE SALIDA

while(true){ setcolor(WHITE); //dibuja en la página 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; }}