Está en la página 1de 88

Universidad Nacional de Ingeniera g

Ingeniera g Mecnica M

Grficos en Visual C++


1

Para grficos (incluyendo texto) en Visual C++ Windows utiliza l i la interfaz t f G Graphics hi D Device i I Interfaz t f (GDI) lo l que llama ll al los gestores de dispositivo ya sea de video, impresora o trazadores de g grficos y ya establecidos.

Se tiene a la interfaz GDI que provee de la aplicacin y va al dispositivo

28/06/2011

Ing. Daniel Osorio Maldonado

Contexto de Dispositivo p

Windows no permite el acceso directo al hardware de visualizacin, lo hace utilizando un nivel de abstraccin denominado contexto de dispositivo (DC). Un contexto de dispositivo (DC) es una estructura de datos, mantenida internamente por el GDI que contiene los atributos bsicos p para g graficar o p poner un texto.

Visual C++.

Un ejemplo es el OnDraw en


La ventanita que se aprecia fue confeccionada en un SDI (Single ( g document) )

28/06/2011

Ing. Daniel Osorio Maldonado

Atributos del Contexto de Dispositivo p


Cuando

Windows crea un dispositivo asigna valores por omisin para todos los atributos. Para que una aplicacin pueda obtener o modificar cualquiera de estos atributos , la GDI proporciona las funciones que a continuacin se detallan.
28/06/2011 Ing. Daniel Osorio Maldonado 4

ATRIBUTOS Modo de conversin Origen O i de d ventana Tamao lgico de la ventana lgica

POR OMISION MODIFICAR M_MTEXT (0 0) (0,0) (1 1) (1,1) SetMapMode SetWindowOrg S tWi d O OffSetWindowOrg SetWindowExt SetMapMode

OBTENER GetMapMode G tWi d O GetWindowOrg GetWindowExp

Origen de la (0,0) superficie de la proyeccin p y Tamao de la superficie de proyeccin Pluma (1,1)

SetViewportOrg GetViewportOrg OffsetViewportOrg SetViewportExt SetMapMode SelecObject GetViewportExt

BLACK_PEN

SelecObject

28/06/2011

Ing. Daniel Osorio Maldonado

ATRIBUTOS Posicin actual de la pluma Pi Pincel l

POR OMISION (0,0)

MODIFICAR

OBTENER

MoveTo, LineTo, GetCurrentPosit ArcTO, PolylineTo ion S l Obj t SelecObject GetBrushOrg GetTextColor SelecObject SelecObject GetBkColor Get Co o GetBkMode
6

WHITE BRUSH SelecObject WHITE_BRUSH S l Obj t SetBrushOrg SetTextColor SelecObject SelecObject SetBkColor Set Co o SetBkMode

Origen del pincel (0,0) (0 0) Color de texto Fuente Mapa de bits Color Co o de fondo o do Modo de fondo
28/06/2011

Negro SISTEM_FONT Ninguno Blanco a co OPAQUE

Ing. Daniel Osorio Maldonado

ATRIBUTOS
Modo de dibujo Modo de ajuste Modo de relleno

POR OMISION MODIFICAR R2_copypen


SetROP2 BLACKONWHITE SetStrechBltMode ALTERNATE SetPolyFillMode

OBTENER
GetROP2 GetStrechBltMode GetPolyFillMode

Con estas funciones bsicas se puede graficar en pantalla de dispositivo as como en Visual C++

28/06/2011

Ing. Daniel Osorio Maldonado

Objetos GDI
La GDI de Windows emplea herramientas de dibujo, incluyendo plumas , pinceles tipos de letra, mapas bits, paleta de color y regiones, que se contempla en MFC. //DIBUJA Y RELLENA UNA ELIPSE DE COLOR AMARILLO CElipseView::OnPaint() { static DWORD dwColor[9]={RGB(0,0,0),RGB(255,0,0), RGB(0,255,0),RGB(0,0,255), RGB(255,255,0),RGB(255,0,255), ( ) ( ) RGB(0,255,255),RGB(128,128,128), ( ) ( ) RGB(255,255,255)}; POINT polylpts[4], polygpts[5]; int xcoord; CBrush n_brocha; n brocha; CBrush *v_brocha; CPen n_pincel; CPen *v v_pincel; pincel; n_pincel.CreatePen(PS_SOLID, 2,dwColor[3]); //n_pincel.CreatePen(PS_SOLID, ancho de la lnea de borde, dwColor [color de la lnea de borde]); v_pincel=dc.SelectObject(&n_pincel); i l d S l tObj t(& i l) n_brocha.CreateSolidBrush(dwColor[4]); //n_brocha.CreateSolidBrush(dwColor[color del relleno])

28/06/2011

Ing. Daniel Osorio Maldonado

v_brocha=dc.SelectObject(&n_brocha); dc.Ellipse(475,400,100,150);//los dos primeros dan las dimensiones de la elipse //superior ,los otros 2 dan la ubicacin de los puntos uno de la parte derecha //el otro de la parte izquierda dc.TextOut(220,265,"elipse",6); //visualiza textos dc.TextOut(posicin X, posicin Y, Texto ", numero de letras del texto); dc.SelectObject(v_brocha); //selecciona al objeto GDI y lo incorpora al dispositivo n_brocha.DeleteObject(); dc.SelectObject(v j ( _p pincel); ); n_pincel.DeleteObject();

28/06/2011

Ing. Daniel Osorio Maldonado

Asociacin de Colores

Windows utiliza un entero de 32 bits para representar un color. El byte menos especificativo es el color rojo el siguiente el verde,el siguiente el azul y el otro no se utiliza. utiliza

28/06/2011

Ing. Daniel Osorio Maldonado

10

Normalmente a este entero lo denominamos color RGB. L macro RGB d La de l la Wi Windows d convierte i t a estos colores a un color en conjunto como ...COLORREF color = RGB (0,250,0), este valor es para el verde. Cuando los 3 valores son cero (RGB (0,0,0)) el color es negro cuando los 3 valores son 250 (RGB(250,250,250)) es blanco.

28/06/2011

Ing. Daniel Osorio Maldonado

11

Color
Negro Azul Aguamarina Rojo Fucsia A Amarillo ill Blanco A lM Azul Marino i Verde V d A Verde Azul l Granate Prpura
28/06/2011

Nivel de Azul Nivel de Verde Nivel de Rojo


0 255 255 0 255 0 255 128 0 128 0 128 0 0 255 255 0 0 2 255 255 0 128 128 0 0
Ing. Daniel Osorio Maldonado

0 0 0 0 255 255 2 255 255 0 0 0 128 0


12

Verde intenso 0

Color Verde oliva Gris Gris Plata


Nivel de Azul 0 128 192

Nivel de Verde 128 128 192

Nivel de Rojo 128 128 192

Otros colores definidos por Windows son :


Color Verde claro Azul claro Marfil Nivel de Azul Nivel de Verde Nivel de Rojo 192 240 240 220 202 251 160
Ing. Daniel Osorio Maldonado

192 166 255 160


13

Gris mediano 164


28/06/2011

DIBUJAR EN VISUAL C++


Hasta ahora las unidades que se han empleado para dibujar han sido los pxeles, tambin denominadas id d de unidad d dispositivo. di ii Windows proporciona varios modos de proyeccin (tambin denominados modos de mapeado o modos de conversin) que se puede asociar con el dispositivo sobre el q que se esta dibujando. j Si queremos graficar una circunferencia podemos elegir como modo de proyeccin MM_LOMETRIC, ya que en este modo la unidad lgica tiene 0.1 mm, en vez de un pxel, pero habr de tener presente que en ste modo el eje Y aumenta hacia arriba; Cuando utilizamos el MM_TEXT aumenta hacia abajo.
Ing. Daniel Osorio Maldonado 14

28/06/2011

Con el SetWindowExt(540,900) se puede tener la relacin de las unidades de la ventana lgica. lgica Y con el SetViewportOrg(cx,-cy), y con el SetViewportExt(cx,cy), y el SetViewportOrg(cx/2,cy/2) la posicin de coordenadas. coordenadas

28/06/2011

Ing. Daniel Osorio Maldonado

15

Unidades de un sistema de coordenadas


Las unidades L id d de d un sistema it de d coordenadas d d X-Y X Yd dependen d d del l modo de proyeccin empleado. Adems de MM_TEXT, , hay y cinco modos de proyeccin p y mtricos y dos personalizados, que podemos ver en la siguiente tabla.

Modo de proyeccin
MM_TEXT MM_TWIPS MM LOMERIC MM_LOMERIC MM_HIMETRIC
28/06/2011

Unidad lgica 1 Pixel 1 twip 0 1 mm 0.1 0.01 mm

X aumenta hacia Derecha Derecha Derecha Derecha

Y aumenta hacia abajo arriba arriba arriba


16

Ing. Daniel Osorio Maldonado

Modo de proyeccin
MM_LOENGLISH MM_TWIPS MM ISOTROPIC MM_ISOTROPIC

Unidad lgica
0.01 Pul 0.001 Pul arbitrario

X aumenta hacia
Derecha Derecha Seleccionable Seleccionable

Y aumenta hacia
arriba arriba Seleccionable Seleccionable

MM_ANISOTROPI arbitrario C

Para ajustar el sistema de coordenadas a uno de estos se debe llamar a la funcin miembro CDC::SetMapMode. Por ejemplo el GetClientRect no es una funcin GDI por lo t t seguir tanto i devolviendo d l i d l las coordenadas d d en pixeles. i l

28/06/2011

Ing. Daniel Osorio Maldonado

17

Modo de Proyeccin MM_TEXT


Dado por omisin, la unidad se mide en pixeles, X aumenta hacia la derecha e Y hacia abajo, la razn entre la pantalla lgica y la superficie de proyeccin es 1 , se puede variar el origen de coordenadas d d con l la f funcin: i

CDC::SetViewprtOrg o la funcin CDC::SetWindowOrg.


//Establecer la escala del sistema de coordenadas
es

dc.SetWindowExt(840,300); //nos da el nivel de ampliacin de la ventana que no


para pixeles

dc.SetViewportOrg(cx,-cy); //supuestamente lleva dc SetViewportExt(cx cy); dc.SetViewportExt(cx,-cy); dc.SetViewportOrg(cx/2,cy/2);//lleva el origen de


fsica y a la superficie de grafico

el origen al centro de la pantalla

coordenadas al centro de la pantalla

28/06/2011

Ing. Daniel Osorio Maldonado

18

DIBUJA LINEAS DE LOS EJES CORDENADOS


void CGrafEjes2View::OnDraw(CDC* pDC) { CClientDC dc(this); dc.SetViewportOrg (300,300); static DWORD dwColor[9]={RGB(0,0,0),RGB(255,0,0), RGB(0,255,0),RGB(0,0,255), RGB(255,255,0),RGB(255,0,255), RGB(0,255,255),RGB(127,127,127), RGB(255,255,255)}; POINT polylpts[4], polygpts[5]; int xcoord; CBrush n_brocha; CBrush *v_brocha; CPen n_pincel; CPen *v_pincel; n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(0,-140);//punto inicial dc.LineTo(0,140);//punto final dc.TextOut(0,145,"Y",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]);//caractersticas de //las lneas de trazado v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(-100,0); //punto inicial dc.LineTo(300,0); //punto final dc.TextOut(305,0,"X",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); }
28/06/2011 Ing. Daniel Osorio Maldonado 19

28/06/2011

Ing. Daniel Osorio Maldonado

20

Modo de Proyecciones Metricas


Los modos L d de d proyeccin i MM_TEXT, MM TEXT MM MM_TWIPS, TWIPS MM_LOMERIC, MM_HIMETRIC y MM_LOENGLISH las unidades del eje j X e Y se expresan p en medidas fsicas idnticas para ambos.

28/06/2011

Ing. Daniel Osorio Maldonado

21

28/06/2011

Ing. Daniel Osorio Maldonado

22

Modos de Proyeccin Personalizados


Son los MM_ISOTROPIC, MM_ANISOTROPIC cuando se utiliza estos modos de proyeccin se puede cambiar tanto el origen de coordenadas como la razn, caractersticas que permiten cambiar el tamao de las figuras cuando se redimensionan las ventanas. El sistema de proyeccin MM_ISOTROPIC expresan las coordenadas x e y en unidades lgicas de tamao fsico idntico, en cambio MM ANISOTROPIC expresan las coordenadas x MM_ANISOTROPIC e y, en unidades lgicas de tamao fsico distinto.
Ing. Daniel Osorio Maldonado 23

28/06/2011

En el sistema MM_ISOTROPIC la razn de la pantalla fsica y la lgica es uno.


28/06/2011 Ing. Daniel Osorio Maldonado 24

En el sistema MM_ANISOTROPIC la razn de la pantalla pa a a fsica s ca y la a lgica g ca es d distinto s oau uno. o


Ing. Daniel Osorio Maldonado 25

28/06/2011

Con la funcin dc.SetMapMode(MM_ANISOTROPIC); la grafica de la cbica es al tope por el eje Y Y.

28/06/2011

Ing. Daniel Osorio Maldonado

26

Con la funcin dc.SetMapMode(MM_ISOTROPIC); la grafica de la cbica no se ajusta a la ventana de grafico.

28/06/2011

Ing. Daniel Osorio Maldonado

27

Creacin de una grafica en Visual C++


Paso 1: Seleccione File/New de la lista de opciones del menu,

aparecer un cuadro de dialogo que permitir iniciar un nuevo p y proyecto.

28/06/2011

Ing. Daniel Osorio Maldonado

28

Paso 2: Seleccione la opcin MFC AppWizard(exe). Seleccione las opciones que se muestran, y luego clic en OK

Marcar el radio botn el Single document luego click en Next>

28/06/2011

Ing. Daniel Osorio Maldonado

29

click en Next> en ambos

28/06/2011

Ing. Daniel Osorio Maldonado

30

click en Next> en ambos

28/06/2011

Ing. Daniel Osorio Maldonado

31

click en Next>

28/06/2011

Ing. Daniel Osorio Maldonado

32

La Clase Cview, derivada a partir de la clase CWnd, se utiliza p para crear la base de las clases de vistas definidas por el usuario. U vista Una i t actua t como un buffer entre el documento y el usuario, y es realmente un hijo de una ventana de marco. Presione Finish y luego Ok, en la ventana que aparece aparece.

28/06/2011

Ing. Daniel Osorio Maldonado

33

Paso 3
En esta aplicacin se incorporar al cdigo de la aplicacin una funcin OnPaint(), que q procesara los mensajes WM_PAINT. Seleccione CGraficoView en el cuadro de entrada de texto Class name En el cuadro de lista ObjectIDs, seleccione CGRAFICOSVIEW Seleccione el mensaje el mensaje WM_PAINT en el cuadro de mensajes, j , la funcin miembro ONPAINT() aparecer en la lista Member Functions, clic en OK
28/06/2011 Ing. Daniel Osorio Maldonado 34

Paso 4. Incorporese el siguiente codigo al descriptor del mensaje OnPaint( ). Haciendo clic en Edit Code de la clase Wizard y luego correr la aplicacin.

28/06/2011

Ing. Daniel Osorio Maldonado

35

Agregar g g la librera #include <math.h>

EJEMPLOS DE GRAFICAS

void CGRAFICADELARAIZView::OnPaint() { CPaintDC dc(this); static t ti DWORD d dwColor[9]={RGB(0,0,0), C l [9] {RGB(0 0 0) RGB(255,0,0), RGB(255 0 0) RGB(0 RGB(0,255,0), 255 0) RGB(0,0,255), RGB(255,255,0), RGB(255,0,255), RGB(0,255,255), RGB(127,127,127), RGB(255,255,255)}; CPen n_pincel; n pincel; CPen *v_pincel; CRect rect; GetClientRect(rect); int cx=(rect.right -rect.left); int cy=(rect.bottom-rect.top); dc SetMapMode(MM ANISOTROPIC); dc.SetMapMode(MM_ANISOTROPIC); //Establecer la escala del sistema de coordenadas dc.SetWindowExt(840,300); dc SetViewportOrg(cx cy); dc.SetViewportOrg(cx,-cy); dc.SetViewportExt(cx,-cy); dc.SetViewportOrg(cx/2,cy/2);

28/06/2011

Ing. Daniel Osorio Maldonado

36

//Dibujar curvas
float x,x2; for (x=0; x<300; x+=0.1)//valores de x a evaluar {x2=(8*pow(x,0.5));// dc.SetPixel(x,x2,RGB(0,0,255));//permite visualizar la grafica dc.TextOut(50,40,"RAIZ");//crea un texto dentro de la pantalla }
//DIBUJA LINEAS DE LOS EJES COORDENADOS

28/06/2011

n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(0,-140); dc.LineTo(0,140); dc.TextOut(0,145,"Y",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(-100,0); dc.LineTo(300,0); dc.TextOut(305,0,"X",1); dc.SelectObject(v j ( _p pincel); ) n_pincel.DeleteObject(); } Ing. Daniel Osorio Maldonado

37

Muestra el siguiente grafico

28/06/2011

Ing. Daniel Osorio Maldonado

38

void CGRAFICADELACUBICAView::OnPaint() {CPaintDC dc(this); // device context for painting static DWORD dwColor[9]={RGB(0 dwColor[9]={RGB(0,0,0), 0 0) RGB(255,0,0), RGB(255 0 0) RGB(0 RGB(0,255,0), 255 0) RGB(0,0,255), RGB(0 0 255) RGB(255,255,0), RGB(255,0,255), RGB(0,255,255), RGB(127,127,127), RGB(255,255,255)}; CPen n_pincel; CPen *v_pincel; CRect rect; GetClientRect(rect); int cx=(rect.right cx=(rect right -rect.left); -rect left); int cy=(rect.bottom-rect.top); dc.SetMapMode(MM_ANISOTROPIC); //Establecer la escala del sistema de coordenadas dc.SetWindowExt(840,300); dc.SetViewportOrg(cx,-cy); dc.SetViewportExt(cx,-cy); dc SetViewportOrg(cx/2 cy/2); dc.SetViewportOrg(cx/2,cy/2); //Dibujar curvas float x,x3; for (x=-395; x<395; x+=0.1) {x3=(0.0002*pow(x,3));// dc.SetPixel(x,x3,RGB(0,0,255)); dc.TextOut(50,40,"cubica");}

28/06/2011

Ing. Daniel Osorio Maldonado

39

//DIBUJA UNA LINEAS DE LOS EJES COORDENADOS n pincel CreatePen(PS SOLID 1 n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(0,-140); dc LineTo(0 140); dc.LineTo(0,140); dc.TextOut(0,145,"Y",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); i l D l t Obj t() n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(-100,0); dc.LineTo(100,0); ( , ); dc.TextOut(105,0,"X",1); dc.SelectObject(v_pincel); n pincel DeleteObject();} n_pincel.DeleteObject();}

28/06/2011

Ing. Daniel Osorio Maldonado

40

Muestra el siguiente grafico

28/06/2011

Ing. Daniel Osorio Maldonado

41

28/06/2011

void CGRAFICADELLOGARITMOView::OnPaint() {CPaintDC dc(this); static DWORD dwColor[9]={RGB(0,0,0),RGB(255,0,0), RGB(0,255,0), RGB(0,0,255),RGB(255,255,0), RGB(255,0,255), RGB(0,255,255), RGB(127,127,127), RGB(255,255,255)}; CPen n_pincel; n pincel; CPen *v_pincel; CRect rect; GetClientRect(rect); int cx=(rect.right -rect.left); int cy=(rect.bottom-rect.top); dc SetMapMode(MM ANISOTROPIC); dc.SetMapMode(MM_ANISOTROPIC); //Establecer la escala del sistema de coordenadas dc.SetWindowExt(840,300); d S tVi dc.SetViewportOrg(cx,-cy); tO ( ) dc.SetViewportExt(cx,-cy); dc.SetViewportOrg(cx/2,cy/2); //Dib j curvas //Dibujar float x,loga; for (x=0; x<300; x+=0.1) {l {loga=100*log(x*0.02); 100*l ( *0 02) dc.SetPixel(x,loga,RGB(0,0,255)); dc.TextOut(50,40,"LOGARITMO");}
Ing. Daniel Osorio Maldonado

42

//DIBUJA UNA LINEAS DE LOS EJES CORDENADOS


n_pincel.CreatePen(PS_SOLID, n pincel CreatePen(PS SOLID 1 1,dwColor[0]); dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(0,-140); d Li T (0 140) dc.LineTo(0,140); dc.TextOut(0,145,"Y",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); n_p pincel.CreatePen(PS ( _SOLID, , 1,dwColor[0]); , [ ]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(-100,0); dc LineTo(300 0); dc.LineTo(300,0); dc.TextOut(305,0,"X",1); dc.SelectObject(v_pincel); n pincel DeleteObject(); n_pincel.DeleteObject(); }

28/06/2011

Ing. Daniel Osorio Maldonado

43

Muestra el siguiente grafico

28/06/2011

Ing. Daniel Osorio Maldonado

44

void CGRAFICADELASECANTEView::OnPaint() {CPaintDC dc(this); static DWORD dwColor[9]={RGB(0,0,0),RGB(255,0,0), RGB(0,255,0), RGB(0,0,255), RGB(255,255,0),RGB(255,0,255), RGB(0,255,255), RGB(127,127,127),RGB(255,255,255)}; POINT polylpts[4], l l t [4] polygpts[5]; l t [5] CPen n_pincel; CPen *v_pincel; CRect rect; GetClientRect(rect); int cx=(rect.right ( g -rect.left); ) int cy=(rect.bottom-rect.top); dc.SetMapMode(MM_ANISOTROPIC); //Establecer la escala del sistema de coordenadas dc.SetWindowExt(1540,900); dc.SetViewportOrg(cx,-cy); dc SetViewportExt(cx -cy); dc.SetViewportExt(cx,-cy); dc.SetViewportOrg(cx/2,cy/2);

28/06/2011

Ing. Daniel Osorio Maldonado

45

//Dibujar curvas
float x, sec; for (x=-650; (x= 650; x<650; x+=0 x+=0.1) 1) {sec=(int)(1/cos((double)x/100)*100); dc.SetPixel(x,sec,RGB(255,0,0)); dc TextOut(150 140 "SECANTE");} dc.TextOut(150,140, SECANTE );} // DIBUJA UNA LINEAS DE LOS EJES CORDENADOS n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); _p j ( _p ) dc.MoveTo(0,-440); dc.LineTo(0,440); dc.TextOut(0,445,"Y",1); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); // DIBUJA UNA LINEAS DE LOS EJES CORDENADOS n_pincel.CreatePen(PS_SOLID, C ( S SO 1 1,dwColor[0]); C 0) v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(-650,0); d Li T (650 0) dc.LineTo(650,0); dc.TextOut(655,0,"X",1); dc.SelectObject(v_pincel); n pincel DeleteObject(); n_pincel.DeleteObject();
28/06/2011 Ing. Daniel Osorio Maldonado 46

Muestra el siguiente grafico

28/06/2011

Ing. Daniel Osorio Maldonado

47

void CGRAFICADELACOSECANTEView::OnPaint() {CPaintDC dc(this); static DWORD dwColor[9]={RGB(0,0,0), RGB(255,0,0), RGB(0,255,0), RGB(0,0,255), RGB(255 255 0) RGB(255,0,255), RGB(255,255,0), RGB(255 0 255) GB(0 GB(0,255,255),RGB(127,127,127), 255 255) RGB(127 127 127) RGB(255,255,255)}; POINT polylpts[4], polygpts[5]; CPen n_pincel; _p CPen *v_pincel; CRect rect; GetClientRect(rect); int cx=(rect.right cx=(rect right -rect.left); rect left); int cy=(rect.bottom-rect.top); dc.SetMapMode(MM_ANISOTROPIC); //Establecer la escala del sistema de coordenadas dc.SetWindowExt(1540,900); dc.SetViewportOrg(cx,-cy); dc.SetViewportExt(cx,-cy); dc SetViewportOrg(cx/2 cy/2); dc.SetViewportOrg(cx/2,cy/2); //Dibujar curvas float x, cosec ; for (x=-650; x<650; x+=0.1) {cosec=(int)(1/sin((double)x/100)*100);dc.SetPixel(x,cosec,RGB(255,0,0)); dc.TextOut(150,140,"COSECANTE");}

28/06/2011

Ing. Daniel Osorio Maldonado

48

//DIBUJA UNA LINEAS DE LOS EJES COORDENADOS


n_pincel.CreatePen(PS_SOLID, n pincel CreatePen(PS SOLID 1 1,dwColor[0]); dwColor[0]); v_pincel=dc.SelectObject(&n_pincel); dc.MoveTo(0,-440); dc LineTo(0 440); dc.LineTo(0,440); dc.TextOut(0,445,"Y",1); dc.SelectObject(v_pincel); n pincel DeleteObject(); n_pincel.DeleteObject(); n_pincel.CreatePen(PS_SOLID, 1,dwColor[0]); v pincel=dc.SelectObject(&n v_pincel dc.SelectObject(&n_pincel); pincel); dc.MoveTo(-650,0); dc.LineTo(650,0); dc.TextOut(655,0,"X",1); ( , , , ); dc.SelectObject(v_pincel); n_pincel.DeleteObject(); }

28/06/2011

Ing. Daniel Osorio Maldonado

49

Muestra el siguiente grafico

28/06/2011

Ing. Daniel Osorio Maldonado

50

GRAFICOS PERSISTENTES

Para que un grfico realizado con mtodos grficos (imgenes y texto) pueda ser reproducido automticamente siempre que la ventana que lo muestra reciba un mensaje WM_PAINT, la aplicacin debe conservar una copia del grfico en memoria. i De aqu el nombre de grficos persistentes. Windows enva el mensaje XM.PAINT XM PAINT cuando: Una ventana se construye por primera vez. Una ventana se superpone encima de otra. Una ventana se minimiza y despus se maximiza maximiza. Una ventana cambia de tamao. El cdigo de la aplicacin enva explcitamente el mensaje WM.PAINT. Dibujar algo sobre una ventana lleva implcito pintar antes el fondo:, por ejemplo, de blanco. Por esta causa, cuando una ventana reciba un mensaje j WM.PAINT si la funcin OnPaint o la funcin OnDraw no incluyen cdigo que dibuje algo, el contenido de la ventana se borrar.


28/06/2011

Ing. Daniel Osorio Maldonado

51

REPINTAR OBJETOS

Para explicar cmo puede proceder a repintar el contenido de una ventana ventana, vamos a realizar una aplicacin Repintar que muestre paso a paso cada una de las acciones que hay que ejecutar. Ejecute AppWizard y construya el esqueleto para una aplicacin SDI; deje seleccionadas l i d l las opciones i D ki t Docking toolbar, lb minal i l status t t bar b y Printing P i ti and d print preview por si ms adelante las necesitamos. Personalice la caja de dilogo Acerca de. Modifique la barra de mens de la aplicacin p p para q que incluya y un men Dibujar j con las rdenes Crculo y Texto, , en lugar del men Edzczon. Anteriormente hemos dibujado objetos, por ejemplo un crculo, llamando directamente a las funciones de la clase CDC. En programacin orientada a objetos lo coherente es utilizar tili ar objetos q que e se pinten a s mismos. Por esta razn vamos a escribir una clase base denominada CFigura de la cual se p puedan derivar otras clases q que representen p cada una de las figuras g concretas que deseemos dibujar. De esta forma ser fcil construir una coleccin con los objetos dibujados lo que facilitar enormemente el repintado de la ventana. Ejecute ClassWizard y aada la clase CFigura derivada de CDocument (recuerde que CDocument se deriva de CObject).

28/06/2011

Ing. Daniel Osorio Maldonado

52

Almacene la declaracin de la clase en el fichero RepintarDoc.h y la definicin en RepintarDoc.cpp. La funcionalidad de esta clase estar soportada p p por dos constructores, un destructor virtual, una funcin miembro pblica virtual AutoPintado, y por los datos miembro protegidos colorp tipo COLORREF, anchop y estilop de tipo int y colorb de tipo COLORREF

class Cfigura g : public CDocument. p { DECLARE_SERIAL(CFigura) public: //Constructores CFigura() {} //Cfigura(COLORREF,int,COLORREF); //Destructor virtual ~Cfigura(); //Funcion miembro virtual void AutoPintado(CDC*) const{} //Attributes protected: COLORREF colorp;//color pluma int anchop; p //ancho p pluma int estilop; //estilo pluma COLORRREF colorb //color pincel // };
28/06/2011 Ing. Daniel Osorio Maldonado 53

A continuacin escriba en el fichero repindoc.cpp la definicin de las funciones miembros; en nuestro caso, solo del constructor con parmetros. CFigura::CFigura(COLORREF ColorP ColorP, int AnchoP AnchoP, int EstiloR EstiloR, COLORREF ColorB) :colorp(Colorp),anchop(AnchoP),estilo(EstiloP),color(ColorB){ } El constructor con parmetros CFigura asigna los valores pasados como argumentos a los datos miembro del objeto que estamos creando. La funcin miembro AutoPintado ser redefinida en cada una de las clases derivadas de CFigura (una por cada fjgura que queramos dibujar). Como ejemplo ejemplo, vamos a disear las clases CElipse y CTexto para poder dibujar elipses y texto, respectivamente. Escriba estas clases en el fichero Repindoc.h class CElipse: public CFigura { DECLARE_SERIAL(CElipse) public: // Constructor C t t CElipse(int =0, int =0, /* coordenadas */ int = 0, int = 0, COLORREF = RGB(0,0,0); RGB(0 0 0); /* color pluma */ / / int = 1, int = PS_SOLID, COLORREF=RGB(255,255,255)): ( , , )) /* color pincel p */
28/06/2011 Ing. Daniel Osorio Maldonado 54

virtual ~CElipse(): // Destructor // Funciones miembro void AutoPintado( CDC * ) const; protected: int x1, v1, x2. y2: // coordenadas }: Los datos protegidos de la clase CElipse se corresponden con las coordenadas de la esquina superior izquierda y de la esquina inferior derecha del rectngulo circunscrito a la elipse. El constructor CElipse proporciona los valores por defecto para los datos protegidos de su clase y para los de la clase base. class CTexto :public CFigura { DECLARE SERIAL(CT t ) DECLARE_SERIAL(CTexto) public: // Constructor CTexto(int =0,int =0 int =0,int =0 int =0, =0 //coordenadas CString text=, //texto COLORREF =RGB(0,0,0), //color de texto COLORREF =RGB(255,255,255) ( , , ) //color fondo virtual ~CElipse(); //Destructor

28/06/2011

Ing. Daniel Osorio Maldonado

55

void AutoPintado(CDC*) ( ) const; ; //Funcin miembro protected: int x1,y1,y2; // coordenadas CString text; // texto };

Los datos protegidos de la clase CTexto se corresponden con las coordenadas donde debe comenzar el texto, y del texto. El constructor CTexto proporciona los valores por defecto para los datos de la clase base que afectan a esta clase de objetos. Cada uno de los objetos ser dibujado por su correspondiente funcion de AutoPintado. Con lo expuesto podr escribir la definicin de estas funciones, asi como las definiciones de los constructores y destructores de cada una de las clases, , en el archivo repindoc.cpp. p pp
28/06/2011 Ing. Daniel Osorio Maldonado 56

/////////////////////////////////////////////////////////////////////////////// /////////////////////////////

//CElipse IMPLEMENT SERIAL(CElipse CFigura 0) IMPLEMENT_SERIAL(CElipse,CFigura,0) CElipse:: CElipse(int X1,int Y1,int X2, int Y2, COLORREF ColorP, int anchop,int Estilop,COLORREF ColorB); X1(X1),y1(Y1),x2(X2),y2(Y2), CFigura(ColorP,EstiloP,ColorB) { } CElipse::~CElipse() { }

28/06/2011

Ing. Daniel Osorio Maldonado

57

void Celipse::AutoPintado(CDC* pDC) const; { CPen *MiPluma = new CPen(estilop anchop, colorp); CPen *PlumaAnterior = pDC->SelectObject(MiPluma); CB h *MiPi CBrush *MiPincel l = new CBrush(colorb); CB h( l b) CBrush *PincelAnterior = pDC->SelectObject(MiPincel ); pDC->Ellipse(x1, y1, x2, y2); pDC->SelectObject(PlumaAnterior) DC S l tObj t(Pl A t i ) pDC->SelectObject(PincelAnterior) // Eliminar los objetos GDI creados MiPl MiPluma->DeleteObject( D l t Obj t( ) ): Mi Pincel ->DeleteObject( ): delete MiPluma: delete MiPincel } /***************************************/ // CTexto

28/06/2011

Ing. Daniel Osorio Maldonado

58

IMPLEMENT_SERIAL( _ ( CTexto, CFigura, g 0 //esquema q numero) ) CTexto::CTexto(int X. int Y. CString Text, COLORREF ColorP, COLORREF ColorB) : x(X), ( ), y(Y), y( ), text(Text). ( ) CFigura(ColorP, g ( , 1, , PS SOLID, , ColorB) ) { } CTexto::~CTexto( ) { } void CTexto::AutoPintado( CDC *PDC ) const { p pDC->SetlextColor(colorp) ( p) pOC->SetBkColor(colorp) pDC->TextOut(x, y, text); }

28/06/2011

Ing. Daniel Osorio Maldonado

59

Una vez construidas las clases, dibujar una figura consiste en construir un objeto de la clase de figura y llamar a su funcin AutoPintado. Por ejemplo, j p el si-guiente g cdigo g p pinta un crculo; CElipseCir(-100, 100, 100, -100, RGB(255.215,D), 2); Cir.AutoPintado(&dc); El siguiente paso es construir una coleccin con los objetos que vayamos dibujando lo que facilitar enormemente el repintado de la ventana dibujando, ventana. Para referenciar la coleccin de objetos mencionada, aada a la clase CRepintarDoc el dato miembro pblico m_pListaFiguras. class CRepintarDoc p :p public CDocument { // //Attributes public: bli // Puntero a la coleccin de figuras COblist *m_pListafiguras: }; El dato m_pListaFiguras se ha declarado como un puntero a la clase CObArray que permite definir una lista para almacenar punteros a objetos de la clase CObject o de clases derivadas de CObject. Inicie el puntero m_pListaFiguras en el constructor CRepintarDoc y cuando la aplicacin finalice libere la memoria referenciada por l en el destructor de la clase. Para liberar la memoria ocupada por los elementos de la lista y por los objetos referenciados por stos, utilice la funcin DeleteContents

28/06/2011

Ing. Daniel Osorio Maldonado

60

CRepintarDoc; :CRepintarDoc() } //Asignar memoria para una coleccin de objetos (lista) m_pListaFiguras = new CObList; } CRepintarDoc: p :-CRepintarDoc() p () { delete a m_pListaFiguras; } /*U ili /*Utilizando d WizardBar, Wi dB aada d l la f funcin i DeleteContents D l C a la l clase l CR i CRepin-tarDoc D y edtela como se muestra a continuacin: */ Void CRepintarDoc::DeleteContents() { // Liberar la memoria ocupada por los objetos de la lista POSITION pos = a PlistaFiguras>GetHeadposition( ) while (pos !=NULL) delete m_PListaFiguras->GetNext(Pos): // Liberar la memoria ocupada por el obeto coleccin rn_pListaFiguras->RemoveA11 ( ): CD CDocument t::D DeleteContents l t C t t () }

28/06/2011

Ing. Daniel Osorio Maldonado

61

Aada la declaracin de la funcin DelteContents a la declaracin de la clase CRepintarDoc. Virtual void DeleteContents(); Cuando el usuario pulse la orden Circulo del menu Dibujar el objeto dibujado se aadir a la lista. Para construir un objeto de la clase Celipse tiene que invocar al constructor de la clase y pasar como argumentos las coordenadas de la esquina superior izquierda y de la esquina inferior derecha del rectangulo circunscrito a la elipse. elipse Observe en el constructor de la clase que el resto de los parmetros son opcionales.
28/06/2011 Ing. Daniel Osorio Maldonado 62

Finalmente el pintado del objeto lo haremos en la funcin OnDraw. Recuerde que OnDraw es llamada automticamente cuando en la cola de mensajes de la aplicacin se coloca un mensaje WM_PAINT lo que puede hacer ejecutando la funcin InvalidateRect

void id CR CRepintarliew::OnDibujarCirculo() i li O Dib j Ci l () { // Dibujar una circunferencia de radio 100 unidades CElipse *pCir = new CElipse(-100, 100, 100, -100, RGB(255,255,0), 2); // Aadir el objeto a la lista CRepintarDoc* p p pDoc = GetDocument () (): pDoc->mpListaFiguras->AddHead(pCir); // Dibujar InvalidateRect(NULL TRUE); // indirectamente llama a OnDraw InvalidateRect(NULL, }

Observe en la funcin anterior que el objeto de la clase CELipse se ha creado dinmicamente. Si se crea como un objeto local a la funcion, vea en la siguiente
28/06/2011 Ing. Daniel Osorio Maldonado 63

CElipse Cir = CElipse(-100, 100, 100, -100, RGB(255.255,0), 2); // Aadir el objeto a la lista CRepintarDoc* pDoc = GetDocument(); pDoc->m_pListaFiguras->AddHead(&Cir);

El objeto ser borrado automticamente al finalizar la funcin, con lo que el puntero almacenado en m_pListaFigura ser invlido (no apunta al objeto). Asimismo cuando el usuario pulse la orden Texto del men Dibujar, Asimismo, Dibujar el objeto dibujado se aadir tambin a la lista. Para construir un objeto de la clase CTexto tiene que invocar al constructor de la clase y pasar como argumentos las coordenadas donde quiera que comience el t t y el texto, l texto t t que desea d pintar. i t En el constructor de la clase vea que el resto de los parmetros son opcionales. Usando el mismo razonamiento, el nuevo objeto se puede crear dinmicamente. Es decir el pintado del objeto lo haremos en la funcin OnDraw. OnDraw

void CRepintarView::OnDibujartexto() { // Escribir E ibi t texto t CTexto *ptex = new CTexto( -15, 0, CString(Circulo)): // Aadir el objeto a la lista CRepintarDoc* pDoc = GetDocurnent(): pDoc->m_pListaFiguras->AddHead(pTex); D > Li t Fi >AddH d( T ) // Dibujar InvalidateRect(NULL, TRUE); // indirectamente llama a OnDraw }

28/06/2011

Ing. Daniel Osorio Maldonado

64

La funcin OnDraw se encarga de pintar la coleccin objetos. Para ello, primero establece el sistema de coordenadas y despus recorre la coleccin de objetos en el mismo orden en el que han sido creados invocando para cada uno de ellos su funcin AutoPintado correpondiente (polimorfismo). El resultado es el repintado de todos los objetos en el mismo orden que fueron creados.

void CRepintarView::OnDraw(CDC* pDC) { CRepintarDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc) // Tamao del rea de cliente CRect rect; GetClientRect( rect ); int cx = (rect.right - rect.left): int cy = (rect.bottom - rect.top); // Establecer la escala del sistema de coordenadas pDC >SetMapMode(MM ISOTROPIC); pDC->SetMapMode(MM_ISOTROPIC); // Tamao de la ventana pDC->SetWindowExt( 200. 200 ); // Tamao del rea de dibujo (ventana grfica) pDC >SetViewportExt( cx, pDC->SetViewportExt( cx -cy cy ) // Establecer el origen de coordenadas en el centro pDC->SetViewportOrg( cx/2, cy/2 ); // Dibujar POSITION pos = pDoc->m_pListaFiguras->GetTailPosition(); pDoc >m pListaFiguras >GetTailPosition(); while ( pos != NULL) ((CFigura *)(PDoc->m_ListaFiguras->GetPrev(Pos))->AutoPintado (PdC); }

28/06/2011

Ing. Daniel Osorio Maldonado

65

Si fuera el caso que a la aplicacin se le pidiera dibujar otras figuras diferentes y de distintos tamaos, se har necesario que se observe que cada vez que se aade una nueva figura a la coleccin, para pintarla hay que pintar todas ella. Cuando en realidad esto debiera ocurrir solamente cuando la ventana sea ocultada o redimensionada. Este problema se soluciona definiendo en la clase CRepintarView una variable m_bRepintarTodo de tipo BOOL que indique a OnDraw si tiene que repintar todas las figuras o solamente la ultima dibujada. dibujada
Class CRepintarView:public Cview { //................ //Attributes public: CRepintarDoc* GetDocument(); BOOL m_bRepintarTodo; //.......... // };

Inicialice esta variable en el constructor de la clase CRepintarView. CRepintarView El valor TRUE indicara que hay que repintar todo.
28/06/2011 Ing. Daniel Osorio Maldonado 66

Un valor FALSE indicara que hay que repintar solo la figura que acabamos de dibujar.
CRepintarView::CRepintarView() { m_bRepintadoTodo=TRUE;}

De lo expuesto e p e to debe modificar modifi l la f funcin n in OnDraw OnD a para p que q e ahora ho interrogue inte og e a la l variable m_bRepintadoTodo y para que deje dicha variable a valor TRUEN por si se oculta o redimensiona la ventana.
void CRepintarView::OnDraw(CDC* pDC) { // //.......... //Dibujar if(m_bRepintado){ POSITION pos=pDoc->m_pListaFiguras ->GetTailPosition(); while (pos !=NULL) ((CFigura*) (pDoc ->m_pListaFiguras ->GetPrev(pos))) ->Autopintado(pDC); } else ((CFigura *)(pDC )(pDC ->m >m_pListaFiguras pListaFiguras ->GetHead())) >GetHead())) ->Autopintado(pDC); >Autopintado(pDC); m_bRepintadoTodo=TRUE; }
28/06/2011 Ing. Daniel Osorio Maldonado 67

La variable m_bRepintarTodo slo debe de valer FALSE cuando pintemos una nueva figura. Por consiguiente hay la necesidad de modificar las funciones que llaman a OnDraw para pintar cada una de las figuras, como se indica a continuacin:
void CRepintarView::OnDibujarCirculo() { // ............ //Dibujar m_bRepintarTodo=FALSE: invalidateRect(NULL,FALSE); // indirectamente llama a OnDraw } void CRepintarView::OnDibujarTexto() { //........ //Dibujar m_bRepintarTodo=FALSE; InvalidateRect(NULL,FALSE); //indirectamente llama a OnDraw }
28/06/2011 Ing. Daniel Osorio Maldonado 68

Observar Ob en la l vista anterior el l valor l de d FALSE S del d l segundo d parmetro de InvalidateRect. La funcin InvalidateRect establece el rectngulo que hay que repintar repintar. Su sintaxis es:
Void InvalidateRect(LPCRECT lpRect,BOOL berase= TRUE);

El primer parmetro es un puntero a un objeto CRect que contiene las coordenadas del rectngulo g que q hay y que q repintar. p Un valor NULL indica que se repintara todo el rea de trabajo. El segundo parmetro es un BOOL que indica si el fondo del rea que hay que repintar tiene o no que ser borrado. Un valor TRUE (valor por defecto) indica que el fondo ser borrado y un valor FALSE indica que no ser borrado, lo que significa que lo que tengamos pintado no se borrar.

28/06/2011

Ing. Daniel Osorio Maldonado

69

DIBUJAR PUNTOS

Para dib P dibujar j un punto t en l la pantalla, t ll di disponemos d de l la funcin f i miembro i b SetPixel de la clase CDC. Esta funcin pone color al pxel de la posicin especificada por lo cul no se ve afectada por el ancho de la pluma pluma. Su sintaxis es la siguiente:
COLORREF SetPixel( int x, int y, COLORREF crColor); COLORREF SetPixel( POINT punto, COLORREF crColor);

Los argumentos x e y o el argumento punto indican las coordenadas del punto y crColor especifica el color utilizado para pintar el punto. Como ejemplo, dibuje en una ventana las curvas correspondientes a las funciones sin(x) y cos(x) para valores de x entre 0 y 6,3 radianes. Paralelamente, realice el mismo grafico en una caja de imagen. El resultado puede verlo en la figura siguiente.

28/06/2011

Ing. Daniel Osorio Maldonado

70

Para visualizar el ejercicio aada a la barra de mens un nuevo men Grficos con la orden Puntos. Abrir el editor de dilogos g y cree una p plantilla ( (IDD_DLG_PUNTOS) _ _ ) p para una nueva caja de dilogo titulada Grficos. Despus, ejecute ClassWizard y cree la clase CDlgGraficos asociada con esa plantilla de dilogo IDD_DLG_PUNTOS. Aada la declaracin de la clase al fichero RepntarVIew.h RepntarVIew h y la definicin al fichero RepintarView.cpp. Para pintar las curvas, aada a la clase CDlgGraficos la funcin miembro OnPaint, miembro de la clase CDLgGraficos, que se ejecute en respuesta al mensaje WM_PAINT que se produce cada vez que se pinta la ventana, ventana la funcin debe: Crear un sistema de coordenadas para valores de x entre 0 y 6,3 y para valores de y entre -1 y 1 (tamao de la ventana lgica expresado en centsimas: 630 x 200), de forma que los valores positivos queden por encima del eje x, lo que implica dar un valor negativo al parmetro cv de SetViewportExt. SetViewportExt Dibujar las curvas punto a punto, el siguiente es el procedimiento:

void CDlgGraficcs::OnPaint() { // Contexto de dispositivo para pintar CPaintDC ac (this): // Tamao del rea de trabajo CRect rect; GetClientRect( rect) ; int cx = (rect.right - rect.left); inc cy = (rect.bottom - rect.top);

28/06/2011

Ing. Daniel Osorio Maldonado

71

// Establecer la escala del sistema de coordenadas

dc. SetMapMode( MM_ANISOTROPIC):


// // Tamao ae la ventana lqica mx=6 .3*100, 7=2*100) Tamao de la superficie de proyeccin

dc.SetWindowExt;( 630, 200): dc. SetViewpor:Ext( cx, -cy)


// Establecer el origen lgico de coordenadas

dc Set ViewportOrg( 0, dc.Set.ViewportOrg( 0 cy/2 ):


//Dibujar curvas

int x. ycos. ysen; for ( x = 0; x <= 630; x += 5) { ycos = (int)(cos((double)x/100)*100, ysen = (int)(sin((double)x/100)*100) dc SetPixel(x ycos, dc.SetPixel(x ycos RGB(0,0,0)); RGB(0 0 0)); //coseno dc.SetPixel (x. ysen, RGB(255, 255, 255)) //seno
} }

La funcin OnPaint ser invocada cuando el usuario haga clic en la orden Puntos del men Grficos . Visualizando la ventana de dilogo Grficos. para ello, ejecute ClassWizard y aada a la clase CRepintarView la siguiente funcin:

void CRepintarView:;onGraficospuntos() { CDlgGraficos Dlg; // llama al constructor CD1gGraficos Dlg.DoModal ();}

28/06/2011

Ing. Daniel Osorio Maldonado

72

DIBUJAR LNEAS
La clase CDC de la biblioteca MFC proporciona varias funciones para dibujar lneas rectas y curvas Lneas rectas: BOOL LineTo( int x, int y); BOOL LineTo( POINT punto); Line To pinta una lnea desde la posicin actual de la pluma hasta el punto lgico especificado por los argumentos x e y, o por el argumento punto. Por defecto defecto, la posicin inicial de la pluma es el punto lgico (0 (0,0). 0) Puede establecer otro punto utilizando la funcin MoveTo. MoveTo y LineTo son las nicas funciones que modifican la posicin actual de la pluma. Esta posicin puede obtenerse por medio de la funcin CDC::GetCurrentposition CPoint GetCurrentposition() const; Lneas curvas: BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); BOOL Arc( LPCRECT lpRect, lpRect POINT ptInicio, ptInicio POINT ptFin; Arc pinta una lnea que se corresponde con un arco delimitado por los radios que pasan por los puntos (x3, y3) - (x4, y4), perteneciente a la elipse circunscrita en el rectngulo definido por la esquina superior izquierda (x1,y1]) y por la esquina inferior d derecha h (x2, 2 y2) 2). En el segundo formato de Arc el principio y el final de la lnea vienen dados por los puntos ptInicio y ptFin, y el rectngulo por un objeto CRect o RECT referenciado lpRect. El arco se pinta en sentido contrario a las agujas del reloj.

28/06/2011

Ing. Daniel Osorio Maldonado

73

Lneas quebradas:

BOOL Polyline y ( LPPOINT lpPuntos, p , int nPuntos); ); Polyline permite pintar una serie de lneas unidas entre s. El argumento lpPuntos representa un array con los puntos que se quieren conectar y el argumento nPuntos indica el nmero de puntos almacenados en el array. Aada a un menu Graficos el submenu Lineas con las ordenes Rectas, Curvas y Quebradas. A continuacin utilizando ClassWizard vincule a cada una de estas ordenes las funciones OnGraficosLineasRectas,OngraficosLineasCurvas OnGraficosLineasRectas OngraficosLineasCurvas y OngraficosLineasQuebradas, respectivamente. Cada una de estas funciones invocara a la funcin CDldGraficos::OnPaint para pintar el grafico deseado. Para saber que orden es la que se ha invocado a OnPaint aada a la CRepintarView el dato miembro m_uIOrdenMenuGraficos para que contenga el ID de la orden ejecutada.
Class CRepintarView : public Cview { //.................. //Atributes public: CRepintarDoc* GetDocument(); BOOL m_bRepintarTodo; bR i t T d UINT m_uIdOrdenMenuGraficos; // ........... }

28/06/2011

Ing. Daniel Osorio Maldonado

74

Para que la funcin OnPaint pueda acceder a m_uIdOrdenMenuGraficos necesita conocer un puntero a la vista vista. Para ello aada a la clase CDlgGraficos el dato miembro pView para que almacene un puntero a la vista.
Class CDlgGraficos: public Cdialog { private: //Puntero a la vista CrepintarView *pView; pView; //........ }

Cada vez que crea un objeto de la clase CDlgGraficos para visualizar una caja de dialogo con el fin de mostrar un grafico, pase como argumento al constructor de la clase clase, el puntero a la vista vista. Vea la funcin OnGraficosPuntos

28/06/2011

Ing. Daniel Osorio Maldonado

75

void CRepintarView::OnGraficosPuntos() { m_uIdOrdenMenuGraficos=ID_GRAFICOS_PUNTOS; CDlgGraficos Dlg(This); //llama al constructor CDlgGraficos Dlg.DoModal(); }

Asigne al dato miembro pView en el constructor CDlGraficos, el valor pParent pasado como argumento(referencia ala ventana padre de la caja de dialogo).
CDlgGraficos::CDlgGraficos(CWnd* pParent // NULL):CDialog(CDlgGraficos:: IDD,pParent) { pView=(CRepintarView*)pParent; }

De lo expuesto modifique entonces la funcin CDlgGraficos::OnPaint , tal como se aprecia en la siguiente vista.
28/06/2011 Ing. Daniel Osorio Maldonado 76

void CDGraficos::OnPaint() { //Contexto de dispositivo para pintar CPaintDC dc(this); //Tamao del rea de Trabajo CRect rect; GetClientRect(rect); int cx=(rect cx=(rect.rigth rigth rect.left); rect left); int cy =(rect.botton rect.top); //Establecer la escala del sistema de cooredenadas dc.MapMode(MM dc.MapMode(MM_ANISOTROPIC); ANISOTROPIC); //Dibujar int x,y; swicht(pView->m_uIdOrdenMenuGraficos) { Case ID_GRAFICOS_PUNTOS: //Tamao de la ventana(x=6.3*100,y=2*100) dc.SetWindowExt(630,200); //Tamao del rea de Dibujo(Ventana Grafica) dc.SetViewportExt(cx,-cy); 28/06/2011
Ing. Daniel Osorio Maldonado 77

//Establecer el origen de coordenadas dc.SetViewPortOrg(0,cy/2); int ycos,ysen; for(x=0,x<=630;x+=5) { y ycos=(int)(cos((double)x/100)*100); ( )( (( ) / ) ); ysen=(int)(sin ((double)x/100*100);//coseno dc.SetPixel(x,ycos,RGB(0,0,0);//seno break; Case ID_GRAFICOS_LINEAS_RECTAS; //. Break; Case ID_GRAFICOS_LINEAS_CURVAS; //.. break<; Case ID_GRAFICOS_LINEAS_QUEBRADAS // // break; } ///.. }
28/06/2011 Ing. Daniel Osorio Maldonado 78

menu Grficos, queremos que se pinte en el rea de trabajo de la ventana una rejilla que tenga entre lneas 50 unidades lgicas, empezando por la esquina inferior izquierda (punto lgico(0,0)). El cdigo siguiente pinta la rejilla con las caractersticas especificadas especificadas.
Void CRepintarView::OnGraficosLineasRectas(){ m_uIdOrdenMenuGraficos=ID_GRAFICOS_LINEAS_RECTAS; CDlgGraficos Dlg(this); Dlg.DoModal(); } Void CDlgGraficos::OnPaint() { // ........ swicht(pView->m_uIdOrdenMenuGraficos) { case ID_GRAFICOS_PUNTOS: // break;
28/06/2011 Ing. Daniel Osorio Maldonado 79

Al hacer clic en la orden Rectas(ID_GRAFICOS_LINEAS_RECTAS) del

case ID_GRAFICOS_LINEAS_RECTAS: //Tamao de la ventana dc.SetWindowExt(600,400); //Tamao del rea de Dibujo (Ventana Grafica) dc.SetViewportExt(cx,-cy); //Establecer el origen de coordenadas dc.SetViewportOrg(0,cy);//(0,0)=esquina inf.izq dc.DPtopLP(&rect); for(x=0;x<rect rigth for(x=0;x<rect.rigth

28/06/2011

Ing. Daniel Osorio Maldonado

80

Modos de dibujo
Para cambiar el estilo estilo, el ancho y el color de las lneas que dibuje dibuje, puede definir una pluma personalizada como vimos en el apartado Objetos GDIpero, piense cmo puede afectar lo que dibuja, si lo hace encima de un grfico existente. La funcin SetROP2 permite elegir entre 16 modos de dibujo dados por sus respectivos cdigos ROP. Los modos ms utilizados son los siguientes: Modo de dibujo Significado R2NOTCOPYPEN El pxel es el inverso al de la pluma. R2_NOT El pxel es el inverso al de la pantalla. Este modo es til siempre que no se conozca el color de fondo. R2XORPEN El pxel es el resultado de la operacin XQR entre e t e la ap pluma u a y la a pa pantalla. ta a R2NOTXORPEN Esta operacin es la inversa de XQR. R2NOp No dibuja; la salida permanece igual. R2COPYPEN El pxei es el mismo de la pluma. Es el valor que se toma por omisin.

28/06/2011

Ing. Daniel Osorio Maldonado

81

Una vez establecido uno de los diecisis modos posibles, Windows aplicar p la operacion p ROP sobre cada p pxel del p patrn utilizado y su correspondiente pxel del fondo, cada vez que se ejecute una funcin grfica. Por ejemplo, con XQR;
Pluma dibujando un pxel d l patrn del t utilizado tili d Destino. Un pixel existente i t t en la l pantalla t ll Pxel resultante en la l pantalla t ll

1111

XOR

0011

1100

COLOREAR FIGURAS
Una figura puede ser rellenada utilizando un pincel de un color slido o un pincel segn Un determinado patrn. Para crear un pincel de un color slido, vimos en el captulo 6 la funcin CreateSolidBrush En cambio, para crear un pincel que re-llene segn un determinado patrn, utilizaremos ili l la f funcin i miembro i b C Create-HatchBrush H hB h d de l la clase CBrush: BOOL CreateHatchBrush( int nEstilo, COLORREF crColor ); Los valores posibles para nEstilo se indican en la tabla siguiente. El parme-tro crColor es el color de las lneas que forman el patrn.

28/06/2011

Ing. Daniel Osorio Maldonado

82

ESTILO HS_HORIZONTAL HS:VERTICAL HS_BDIAGINAL HS FDIAGONAL HS_FDIAGONAL HS_CROSS HS_DIACGROSS

SIGNIFICADO Lneas horizontales Lneas verticales Diagonales ascendentes Di Diagonales l d descendentes d t Lneas verticales y horizontales cruzadas Diagonales cruzadas

ESTILOS DE LA PLUMA Cualquier pluma de ancho mayor de un pxel, independientemente de su estilo, centra su traza sobre el contorno que se desea dibujar dibujar, excepto para el estilo PS_INSIDEFRAME; en este caso, la traza se dibuja totalmente dentro del contor-no. Por ejemplo, la siguiente figura dibuja tres cuadrados de lado io unidades lgicas. El primer cuadrado esta dibujado con una pluma de ancho 20 y-estilo PS_JNSIDEFRAME; el segundo est dibujado con una pluma de ancho 1 y estilo PS_SOLJD; y el tercero con una pluma de ancho 20 y tambin de estilo PSSOLID. Observe que la traza de la pluma en el primer cuadrado est dentro del contorno (el contorno lo muestra la segunda figura) y que en el cuadrado ter-cero est centrada sobre el contorno. Para ver todos los estilos de plmas vea en la ayuda, el constructor CPen.
28/06/2011 Ing. Daniel Osorio Maldonado 83

DIBUJAR FIGURAS
La clase CDC de la biblioteca MIFC proporciona funciones para dibujar contornos de figuras rellenas de color que podemos clasificar as: Rectngulos: BOOL Rectangle (int xl, int y), int x2, int y2); BOOL Rectangle( LPCRECT lpRect); Rectangle pinta un rectngulo utilizando la pluma actual. El interior del rec-tngulo es coloreado l d utilizando tili d el l pincel i l actual. t l L Los argumentos t (x1, ( 1 y1) 1) y (x2. ( 2 y2) 2) se corresponden, respectivamente, con las coordenadas lgicas de las esquinas superior izquierda e inferior derecha del rectngulo. BOOL RoundRect ( int x1, int y y1, int x2, int y y2, int x3, int y y3); ) BOOL RoundRect (LPCRECT lpRect, POINT punto); RoundRect pinta un rectngulo con las esquinas redondeadas utilizando la pluma actual. El interior del rectngulo es coloreado utilizando el pincel ac-tual. Los argumentos (xl, (xl y1) y (x2, (x2 y2) se corresponden, corresponden respectivamente respectivamente, con las coordenadas lgicas de las esquinas superior izquierda e inferior dere-cha del rectngulo. Los argumentos x3 e y3 se corresponden, respectivamente, con las medidas (en unidades lgicas) de los dimetros X e Y de la elipse utili-zada para redondear las esquinas.

28/06/2011

Ing. Daniel Osorio Maldonado

84

Elipses: BOOL Elipse (int xl, int y1, int x2, int y2); BOOL Ellipse( Elli ( LPCRECT lpRect); l R t) Ellipse pinta una elipse utilizando la pluma actual. El interior de la elipse es coloreado utilizando el pincel actual. Los argumentos (x1, y1) y (x2, y2) se corresponden, respectivamente, con las coordenadas lgicas de las esquinas superior izquierda e i f i d inferior derecha h d del l rectngulo, t l que circunscribe i ib a l la elipse. li Polgonos: BOOL Polygon( LPPOINT lpPuntos, int nP untos); Polygon pinta un polgono de dos o ms vrtices utilizando la pluma actual actual. El interior del polgono es coloreado utilizando el pincel actual. El argumento lpPuntos apunta a un array de objetos CPoint o de estructuras POINT correspondientes a los vrtices del polgono (para cerrar el polgono no es nece-sario llegar de nuevo al punto de partida como ocurna con Polyline) Polyline), y nPuntoS indica el nmero de vrtices del polgono. BOOL PolyPolygofl( LPPOLNT lpPuntos, LPINT lpPuntosPoli, INIT Poligonos); PolyPolygon y yg p pinta dos o ms p polgonos g de dos o ms vrtices cada uno utili-zando la pluma actual. El interior de cada polgono es coloreado utilizando el pincel actual. El argumento lpPuntos apunta a un array de objetos CPoint o de estructuras POINT correspondientes a los puntos de los polgonos, lpPuntosPOli apunta a un array de enteros, cada uno de los cuales especifica el nm~JXLde puntos de cada polgono y nPoligonos. P li

28/06/2011

Ing. Daniel Osorio Maldonado

85

REGIONES
Una regin es un objeto GDI que describe un rea de la pantalla. Se forma combinando rectngulos, rectngulos elipses y polgonos polgonos. Una regin seleccionada para un contexto de dispositivo, se puede utilizar para dibujar o para recortar. Utilizndola para recortar, restringe el dibujo a una parte especfica del rea de cliente. L regiones Las i pueden d ser creadas d utilizando tili d l las f funciones i miembro i b d de l la clase l CR CRgn. El tipo ms simple de regin describe un rectngulo y la funcin para crearla puede ser alguna de las siguientes: BOOL createRectRgn( int x1, int y1, int x2, int y2); BOOL createRetRgnIndirect( LPCRECT lpRect); BOOL CreateRoundRgnIndirect( int x1, int y1, int x2, int y2, int x3, int y3); Tambin es posible crear regiones elpticas: BOOL CreateEllipticRgn( int x1, int y1, int x2, int y1); BOOL CreateEllipticRgnIndirect( LPCRECT lpRect); Tambin se pueden crear regiones poligonales: BOOL CreatePolygonRgn( LPPOINT lpPuntos, int nPuntos,int nModoRelleno); BOOL CreatePolyPolygonRgn( LPPOINT lpPuntos, lpPuntos LPINT lpPuntosPoli, lpPuntosPoli int nPoligonos, int nModoRelleno);

28/06/2011

Ing. Daniel Osorio Maldonado

86

Las regiones se expresan siempre en coordenadas de dispositivo. Las regiones vistas desde las MFC son objetos GDI que se pueden alterar con las funciones miembro CombineRgfl y OffsetRgn. int OffsetRgn(int x, x int y); int OffsetRgn( POINT punto); La funcin OffsetRgn desplaza la regin almacenada en el objeto CRgn, x unidades sobre el eje X e y unidades sobre el eje Y. int CombineRgn( CRgn* pRgn1, CRgn* pRgn2, int nModoCombinar); La funcin CombineRgn crea una nueva regin combinando dos regiones existentes. El parmetro nModo Combinar indica cmo se combinan las dos re-giones:

ModoCombinar
RGN_AND RGN_COPY RGN_DJFF RGN_OR RGN XOR
28/06/2011

La nueva regin es: Interseccin de las dos regiones Copia la regin 2 en la regin 1 Toda la regin 1 que no est en la regin 2 Unin de las dos regiones Unin menos interseccin de las dos regiones
Ing. Daniel Osorio Maldonado 87

El valor devuelto por la funcin CombineRgn especifica el tipo de regin resultante. Este valor puede ser uno de los siguientes: Valor devuelto La nueva regin: COMPLEXREGION Tiene bordes solapados (se trata de una combinacin de rectngulos, elipses o polgonos) ERROR No se cre NULLREGION Est vaca NULREGION VACIA SIMPLEREGION No tiene bordes solapados (se trata de un rectngulo, elipse o polgono simple) Para recuperar las coordenadas del rectngulo que contiene la regin almacenada en el objeto CRgn, utilice la funcin: int GetRgnBox( LPRECT lpRect) const; Para saber si un punto dado pertnece a la regin almacenada en un objeto CR CRgn, utilice tili l la f funcin: i BOOL PtlnRegion( int x, int y) const; BOOL PtlnRegion( POINT punto) const; Para saber si cualquier parte de un rectngulo dado pertenece a la regin almacenada en un objeto CRgn. utilice la funcin: BOOL RectlnRegion( LPCRECT lpRect) const; Una vez que la regin ha sido creada, se pueden utilizar las siguientes funciones de l clase la l CDC con los l propsitos it que se enuncian i a continuacin: ti i FillRgn FillR

28/06/2011

Ing. Daniel Osorio Maldonado

88

También podría gustarte