CAPÍTULO V: manejo de trazados

(uso de la clase GraphicsPath...)

 
Fecha: 04/Oct/2005 (04/10/2005)
Autor: Arbis Percy Reyes Paredes 
Email: bigpercynet@hotmail.com

http://percyreyes.blogspot.com  - http://netarticles-percyreyes.blogspot.com


captando la idea...

La idea de usar trazados es establecer, de cierta manera, un trabajo ordenado y delimitado usando GDI+. Todos los gráficos generados para aplicaciones se basan usando trazados, pues de esta manera se podrá definir la estructura de lo que se piensa representar, y así poder, cuantas veces quisiéramos, dibujar lo que habíamos diseñado. En otras palabras, trabajar con trazados es algo así como, definir una maqueta para representar nuestras estructuras gráficas, de esta manera definiremos una estructura de colección que estará compuesto por las formas geométricas que queramos dibujar. GDI+ nos proporciona una clase denominada GraphicsPath, la cual encapsula toda la estructura de formas que se pretende representar. GraphicsPath nos ayuda a establecer nuestro diseño de dibujo, la cual estará formado por componentes o trazados, es decir, esta clase encapsulará una colección de trazados a representar.

Bueno, ahora vale resaltar que un trazado puede estar formado, a su vez, por un número indeterminado subtrazados... además, un trazado o figura está formada por una secuencia de líneas y curvas conectadas o por una forma geométrica primitiva, donde el punto inicial de una figura es el primer punto de la secuencia de líneas y curvas conectadas y, el punto final es el último punto de la secuencia. Cuando añadimos y/o eliminamos trazados o formas a un GraphicsPath, el punto final de la forma se unirá con el punto inicial de la forma siguiente... resultando así una figura total formada por una secuencia de líneas y curvas.... en otras palabras, se obtendrá una figura formada por una colección de trazados. Use el método CloseFigure para cerrar de forma explícita una figura, este método cierra la figura actual con una línea desde el punto final hasta el punto inicial. Con la finalidad de realizar el relleno y el recorte, todas las figuras abiertas se cierran agregando una línea de su primer punto al último.

hablando acerca de la clase GraphicsPath...

Esta clase GraphicsPath nos proporciona mucho métodos que facilitarán todo este "rollo" al momento de trabajar con trazados. Un método importante en todo esto es StartFigure que nos ayuda a iniciar de manera explicita una nueva figura. Debemos tener en cuenta que u na nueva figura se inicia de forma implícita cuando se crea un trazado o se cierra una figura. Cuando se agrega al trazado una forma geométrica primitiva (rectángulos, elipses, círculos....), entonces se agrega una figura que contiene la forma geométrica y, además, inicia una nueva figura de forma implícita. En consecuencia, siempre hay una figura actual en el trazado. Cuando se agregan líneas y curvas a un trazado, se agrega una línea implícita como sea necesario para conectar el punto final de la figura actual con el punto inicial de las nuevas líneas y curvas para formar una secuencia de líneas y curvas conectadas.

no nos olvidemos de la funcionalidad de sus miembros (propiedades y métodos)...

GraphicsPath posee propiedades que podemos usar para establecer u obtener ciertas características al momento de realizar los trazados, como por ejm. la propiedad PathPoints que nos devuelve la matriz de puntos del trazado, la propiedad PathTypes  que devolverá los tipos de los puntos correspondientes de la matriz PathPoints. También podemos establecer la manera de rellenar el interior de la figuras que componen el objeto GraphicsPath, pues para esto haremos uso de la propiedad FillMode, la cual será definida mediante una enumeración FillMode, podemos definir un relleno de espirales(FillMode.Winding) o un modo de relleno alternativo o por default(FillMode.Alternate). Adicionalmente puede usar la propiedad PointCount para obtener el número de elementos de la matriz PathPoints, en otras palabras, esto nos devolverá la cantidad de puntos que forma parte del GraphicsPath.

También podemos aprovechar los métodos de esta clase, entre ellos tenemos: AddArc,AddBezier, AddClosedCurve, AddBeziers, AddEllipse, AddCurve, AddLine, AddLines, AddPath, AddPolygon,AddPie, AddRectangle, AddRectangles , AddString .... la funcionalidad de cada método es fácil de deducir, pues por ejem., AddCurve agrega una curva al GraphicsPath, AddLine agrega una línea, AddRectangle agrega un rectángulo, AddString agrega un cadena formateada... y así puede usted deducir las demás funcionalidad de los otros métodos y aprovecharlos de la mejor manera.

no espere más...

Si usted desea revisar a más detalle sobre este tema, puede consultar la ayuda msdn online de Microsoft, además puede encontrar algunos ejemplos sencillos que le ayudarán a comprender mejor el tema...

ahora "quememos" algo de código...

Después de explicar la funcionalidad de esta clase GraphicsPath, vayamos con algunos ejemplillos para aclarar y despejar dudas.

Por ejem. analicemos este trozo de código.

Me.BackColor = Color.DarkBlue
'creamos el objeto GraphicsPath...
Dim gp As GraphicsPath = New GraphicsPath(FillMode.Alternate)
' agregando figuras al GraphicsPath...
gp.AddRectangle(New Rectangle(0, 0, Me.Width, Me.Height))
gp.AddEllipse(New Rectangle(0, 0, Me.Width, Me.Height))
'agregamos un forma de cadena...
gp.AddString("myform" & vbCrLf & "tiene" & vbCrLf & "esta forma", _
New Font("verdana", 10).FontFamily, FontStyle.Regular, 80, _
New PointF(120, 20), StringFormat.GenericTypographic)
'agregamos nuevamente el mismo rectángulo agregado 
'anteriormente, esto es para efectos de salida...
gp.AddRectangle(New Rectangle(0, 0, Me.Width, Me.Height))

Con el trozo de código anterior hemos podido definir la colección de figuras que pretendemos representar. Ahora haremos la representación de esta colección, ya sea dibujando la colección o rellenando la misma. Veamos cual sería el código adicional para dibujarlo:

 

'usamos el método DrawPath para dibujar el objeto GraphicsPath
Me.CreateGraphics.DrawPath(Pens.Red, gp)

...el código en ejecución devuelve lo siguiente:

 

Nota: "myform tiene esta forma", viene a ser un objeto string que más adelante usaremos con otros fines, por esta vez tan sólo  interesesa saber que este objeto ha sido dibujado como parte de la colección.

otro uso...

Otra versión a representar sería usando el método FillPath, rellenando, de esta manera, nuestro trazado. He aquí el código adicional.  

 

'usamos el método FillPath para rellenar el objeto GraphicsPath
 Me.CreateGraphics.FillPath(Brushes.Red, gp)

Esto es lo que obtendrá,

para no perder la costumbre, aquí otra forma de aplicar lo aprendido hasta el momento...

Existe otra manera, como seguramente muchas más, de usar nuestra estructura de colección, y es, usando la clase Region (esta clase es parte de otro artículo que será publicado más adelante), que no es más que usada para "cortar" una parte del Graphics usado como lienzo. Cuando aplicamos usemos el graphicspath como parámetro para la clase Region del Form, esta cortará nuestro Form conforme a la colección de trazados. Note que "myform tiene esta forma" a sido representado mediante un recorte en el form, más no es de color blanco como usted pudo haber imaginado inicialmente. Para corroborar esto, dirija el mouse sobre el texto, al hacerlo, verificará que obviamente, existe una perforación en el formulario que tiene la forma del texto... y nuestro formulario tiene la forma de una elipse.

 

   

'pues ahora, teniendo el diseño o estructura de colección... 
'lo usaremos para definir la forma de nuestro form.
Me.Region = New Region(gp)
 

De esta manera puede usted personalizar la forma del formulario, pero eso por ahora escapa el objetivo de este artículo. Volviendo a lo nuestro, para esta vez se ha representado al formulario dándole la forma de una elipse, y aplicándole una perforación de acuerdo al sello del texto, pero no olvide que todo es parte de una colección de trazados.

 

Usando otros miembros de la clase GraphicsPath... 

Ahora aprendamos a manejar algunas propiedades y métodos de esta clase GraphicsPath. Esta vez iremos de frente al "grano", explicando un ejemplo: En primer lugar observe la siguiente captura de imagen...

...usted verá que todos los puntos que forman parte del trazado han sido representados o hecho realidad en una figura que tiene la forma de una ícono de tránsito. Bueno, usando la propiedad PathPoints hemos podido recuperar la colección de puntos que forman nuestra figura. La figura de tránsito ha sido dibujada y rellenada usando los métodos DrawPath y FillPath, tanto el fondo, el contorno y el texto ha sido tratado mediante una lógica de trazado partitiva, es decir, después de agregar un trazado base (de color rojo) al GraphicsPath, lo representamos en nuestro lienzo, luego añadimos el otro trazado (me refiero al contorno o borde de color negro), hacemos la representación de éste, y por último hacemos un add del texto "STOP" al GraphicsPath, rellenándolo de color blanco. Tenga en cuenta el orden en que esto ha sido dibujado y/o rellenado, ya que si usted modifica este orden, observará otros resultados, la cuales seguramente le "comerán" un poco la cabeza, je, je, je... pero por ser esto un ejemplo sencillo, no creo que tenga problemas la momento de probar este código haciendo experimentos con él. El código fuente es el que sigue a continuación.

NOTA Desde luego existen otras cosillas relacionadas a este tema, las cuales no explico en este artículo, por motivos de didáctica y por supuesto, evitando meterle confusiones en la cabeza. En su debido momento haré hincapié de otros métodos de la clase GraphicsPath como parte de otros artículos. No olvide que esto es algo así como un curso de GDI+, y teniendo en cuenta esto, creo que debemos tomarlo todo con calma. Pero si usted es de aquellos que tiene mucha curiosidad por saber más de estos métodos, visite la ayuda online msdn.

Ahora sí, esto es el source code in Microsoft Visual Basic .NET. (no soy bueno en inglés... pero allí trato de mejorar por lo menos en la sintaxis, je, je, je...)... revíselo.

Public Sub DibujarIconoSTOP()
    Me.lstMatrizPuntos.Items.Clear()

    'creando el Graphics...
    Dim myGraphics As Graphics = Me.PictureBox1.CreateGraphics

    'ahora, creamos la referencia al PictureBox1...
    Dim p As PictureBox = Me.PictureBox1

    'puntos que servirán para representar dibujar la forma
    Dim myPoints() As Point = New Point() { _
    New Point(80, 0), New Point(0, 80), _
    New Point(0, 220), New Point(80, 300), _
    New Point(220, 300), New Point(300, 220), _
    New Point(300, 80), New Point(220, 0)}

    'creamos el GraphicsPath en modo alternativo....
    Dim myGraphicsPath As New GraphicsPath(FillMode.Alternate)

    'tenga en cuenta el orden de agregado de cada figura....

    'add la base de color rojo..
    myGraphicsPath.AddPolygon(myPoints)
    myGraphics.FillPath(New SolidBrush(Color.Red), myGraphicsPath)

    'add el contorno de color negro...
    myGraphicsPath.AddPolygon(myPoints)
    myGraphics.DrawPath(New Pen(Color.Black, 3), myGraphicsPath)

    'add el texto "STOP"...
    myGraphicsPath.AddString("STOP", FontFamily.GenericSansSerif, FontStyle.Regular, 100, _
    New PointF(0, 80), StringFormat.GenericDefault)
    myGraphics.FillPath(New SolidBrush(Color.White), myGraphicsPath)

    'obtenemos la matriz de puntos del trazado...
    Dim puntos As PointF() = myGraphicsPath.PathPoints
    Dim punto As PointF

    'visualizamos las coordenadas de cada punto...
    For Each punto In puntos
        Me.lstMatrizPuntos.Items.Add(punto.ToString)
    Next

    'visualizamos la cantidad de puntos..
    Me.txtTotalPuntos.Text = myGraphicsPath.PointCount.ToString + " Puntos"
End Sub

Hemos terminado, y sólo me queda decirle que investigue más al respecto. Esfuércese por ser feliz, y desde luego no pierda la mirada a este mundo fascinante de la programación.

MÇP - P€®©¥ R€¥€$™

Saludos desde Trujillo - Perú.

Por favor, califica este artículo en PanoramaBox, así me animarás a continuar colaborando contigo...


ir al índice del Guille