Creación de un degradado de trazado

La clase PathGradientBrush le permite personalizar la forma en que rellena una forma con colores que cambian gradualmente. Un objeto PathGradientBrush tiene una ruta de acceso de límite y un punto central. Puede especificar un color para el punto central y otro color para el límite. También puede especificar colores independientes para cada uno de varios puntos a lo largo del límite.

Note

En GDI+, una ruta de acceso es una secuencia de líneas y curvas mantenidas por un objeto GraphicsPath . Para obtener más información sobre los trazados de GDI+, vea Trazados y Construcción y dibujo de trazados.

 

En el ejemplo siguiente se rellena una elipse con un pincel de degradado de trazado. El color central se establece en azul y el color del límite se establece en aqua.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

En la ilustración siguiente se muestra la elipse rellenada.

ilustración en la que se muestra una elipse con un relleno degradado

De forma predeterminada, un pincel de degradado de trazado no se extiende fuera del límite del trazado. Si usa el pincel de degradado de trazado para rellenar una forma que se extiende más allá del límite del trazado, el área de la pantalla situada fuera del trazado no se rellenará. En la ilustración siguiente se muestra lo que sucede si cambia la llamada Graphics::FillEllipse en el código anterior a graphics.FillRectangle(&pthGrBrush, 0, 10, 200, 40).

ilustración que muestra un segmento horizontal de la elipse anterior

Especificar puntos en el límite

En el ejemplo siguiente se construye un pincel de degradado de trazado a partir de un trazado con forma de estrella. El código llama al método PathGradientBrush::SetCenterColor para establecer el color en el centroide de la estrella en rojo. A continuación, el código llama al método PathGradientBrush::SetSurroundColors para especificar varios colores (almacenados en la matriz de colores ) en los puntos individuales de la matriz de puntos . La instrucción de código final rellena el trazado con forma de estrella con el pincel de degradado de trazado.

// Put the points of a polygon in an array.
Point points[] = {Point(75, 0),    Point(100, 50), 
                  Point(150, 50),  Point(112, 75),
                  Point(150, 150), Point(75, 100), 
                  Point(0, 150),   Point(37, 75), 
                  Point(0, 50),    Point(50, 50)};

// Use the array of points to construct a path.
GraphicsPath path;
path.AddLines(points, 10);

// Use the path to construct a path gradient brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to red.
pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));

// Set the colors of the points in the array.
Color colors[] = {Color(255, 0, 0, 0),   Color(255, 0, 255, 0),
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255), 
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0), 
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255),
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0)};

int count = 10;
pthGrBrush.SetSurroundColors(colors, &count);

// Fill the path with the path gradient brush.
graphics.FillPath(&pthGrBrush, &path);

En la siguiente ilustración se muestra la estrella rellenada.

ilustración que muestra una estrella de cinco puntas que se rellena de rojo en el centro a varios colores en cada punto de la estrella

En el ejemplo siguiente se crea un pincel de degradado de trazado basado en una matriz de puntos. Se asigna un color a cada uno de los cinco puntos de la matriz. Si fueras a conectar los cinco puntos por líneas rectas, obtendrías un polígono de cinco lados. También se asigna un color al centro (centroide) de ese polígono; en este ejemplo, el centro (80, 75) se establece en blanco. La instrucción de código final del ejemplo rellena un rectángulo con el pincel de degradado de trazado.

El color usado para rellenar el rectángulo es blanco en (80, 75) y cambia gradualmente a medida que se aleja (80, 75) hacia los puntos de la matriz. Por ejemplo, al pasar de (80, 75) a (0, 0), el color cambia gradualmente de blanco a rojo y a medida que se mueve de (80, 75) a (160, 0), el color cambia gradualmente de blanco a verde.

// Construct a path gradient brush based on an array of points.
PointF ptsF[] = {PointF(0.0f, 0.0f), 
                 PointF(160.0f, 0.0f), 
                 PointF(160.0f, 200.0f),
                 PointF(80.0f, 150.0f),
                 PointF(0.0f, 200.0f)};

PathGradientBrush pBrush(ptsF, 5);

// An array of five points was used to construct the path gradient
// brush. Set the color of each point in that array.
Color colors[] = {Color(255, 255, 0, 0),  // (0, 0) red
                  Color(255, 0, 255, 0),  // (160, 0) green
                  Color(255, 0, 255, 0),  // (160, 200) green
                  Color(255, 0, 0, 255),  // (80, 150) blue
                  Color(255, 255, 0, 0)}; // (0, 200) red

int count = 5;
pBrush.SetSurroundColors(colors, &count);

// Set the center color to white.
pBrush.SetCenterColor(Color(255, 255, 255, 255));

// Use the path gradient brush to fill a rectangle.
graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

Tenga en cuenta que no hay ningún objeto GraphicsPath en el código anterior. El constructor PathGradientBrush determinado del ejemplo recibe un puntero a una matriz de puntos, pero no requiere un objeto GraphicsPath . Observe también que se usa el pincel de degradado de trazado para rellenar un rectángulo, no un trazado. El rectángulo es más grande que el trazado utilizado para definir el pincel, por lo que una parte del rectángulo no queda pintada por el pincel. En la ilustración siguiente se muestra el rectángulo (línea de puntos) y la parte del rectángulo que pinta el pincel de degradado de trazado.

ilustración que muestra un rectángulo limitado por una línea de puntos, parcialmente pintado por un degradado multicolor

Personalizar un degradado de trayectoria

Una manera de personalizar un pincel de degradado de trazado consiste en establecer sus escalas de foco. Las escalas de foco especifican una ruta de acceso interna que se encuentra dentro de la ruta de acceso principal. El color central se muestra en todas partes dentro de esa ruta interna en lugar de solo en el punto central. Para establecer las escalas de foco de un pincel de degradado de trazado, llame al método PathGradientBrush::SetFocusScales.

En el ejemplo siguiente se crea un pincel de degradado de trazado basado en un trazado elíptico. El código establece el color del límite en azul y el color central en aguamarina y, luego, usa el pincel de degradado de trazado para rellenar el trazado elíptico.

Después, el código establece las escalas de foco del pincel de degradado de trazado. La escala de foco x se establece en 0,3 y la escala de foco y se establece en 0,8. El código llama al método Graphics::TranslateTransform de un objeto Graphics para que la llamada posterior a Graphics::FillPath rellene una elipse que se encuentra a la derecha del primer elipse.

Para ver el efecto de las escalas de foco, imagine una pequeña elipse que comparte su centro con la elipse principal. La elipse pequeña (interior) es la elipse principal, escalada respecto de su centro horizontalmente por un factor de 0,3 y verticalmente por un factor de 0,8. A medida que se mueve del límite de la elipse exterior al límite de la elipse interior, el color cambia gradualmente de azul a aqua. A medida que se mueve del límite de la elipse interior al centro compartido, el color permanece aguamarina.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 200, 100);

// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetGammaCorrection(TRUE);

// Set the color along the entire boundary to blue.
Color color(Color(255, 0, 0, 255));
INT num = 1;
pthGrBrush.SetSurroundColors(&color, &num);

// Set the center color to aqua.
pthGrBrush.SetCenterColor(Color(255, 0, 255, 255));
 
// Use the path gradient brush to fill the ellipse. 
graphics.FillPath(&pthGrBrush, &path);

// Set the focus scales for the path gradient brush.
pthGrBrush.SetFocusScales(0.3f, 0.8f);

// Use the path gradient brush to fill the ellipse again.
// Show this filled ellipse to the right of the first filled ellipse.
graphics.TranslateTransform(220.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

En la ilustración siguiente se muestra la salida del código anterior. La elipse de la izquierda es aguamarina solo en el punto central. La elipse de la derecha es de color aguamarina completamente dentro del trazado interior.

ilustración que muestra dos elipses con un degradado de aguamarina a azul: la primera tiene muy poco aguamarina; la segunda tiene mucho más

Otra manera de personalizar un pincel de degradado de ruta es especificar una matriz de colores preestablecidos y una matriz de posiciones de interpolación.

En el ejemplo siguiente se crea un pincel de degradado de trazado basado en un triángulo. El código llama al método PathGradientBrush::SetInterpolationColors del pincel de degradado de ruta para especificar una matriz de colores de interpolación (verde oscuro, aqua, azul) y una matriz de posiciones de interpolación (0, 0,25, 1). A medida que se desplaza desde el borde del triángulo hasta el punto central, el color cambia gradualmente de verde oscuro a aguamarina y, a continuación, de aguamarina a azul. El cambio de verde oscuro a aqua se produce en el 25 por ciento de la distancia de verde oscuro a azul.

// Vertices of the triangle
Point points[] = {Point(100, 0), 
                  Point(200, 200), 
                  Point(0, 200)};

// No GraphicsPath object is created. The PathGradient
// brush is constructed directly from the array of points.
PathGradientBrush pthGrBrush(points, 3);

Color presetColors[] = {
   Color(255, 0, 128, 0),    // Dark green
   Color(255, 0, 255, 255),  // Aqua
   Color(255, 0, 0, 255)};   // Blue

REAL interpPositions[] = {
   0.0f,   // Dark green is at the boundary of the triangle.
   0.25f,  // Aqua is 25 percent of the way from the boundary
           // to the center point.
   1.0f};  // Blue is at the center point.
                  
pthGrBrush.SetInterpolationColors(presetColors, interpPositions, 3);

// Fill a rectangle that is larger than the triangle
// specified in the Point array. The portion of the
// rectangle outside the triangle will not be painted.
graphics.FillRectangle(&pthGrBrush, 0, 0, 200, 200);

En la ilustración siguiente se muestra la salida del código anterior.

ilustración en la que se muestra un triángulo que sombrea de azul en el centro, a aqua, a verde en los bordes

Establecer el punto central

De forma predeterminada, el punto central de un pincel de degradado de trazado se encuentra en el centroide del trazado utilizado para construir el pincel. Puede cambiar la ubicación del punto central llamando al método PathGradientBrush::SetCenterPoint de la clase PathGradientBrush .

En el ejemplo siguiente se crea un pincel de degradado de trazado basado en una elipse. El centro de la elipse está en (70, 35), pero el punto central del pincel de degradado de trazado se establece en (120, 40).

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the center point to a location that is not the centroid of the path.
pthGrBrush.SetCenterPoint(Point(120, 40));

// Set the color at the center point to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

En la ilustración siguiente se muestra la elipse rellenada y el punto central del pincel de degradado de trazado.

ilustración que muestra una elipse que se rellena de azul a aqua desde un punto central cerca de un extremo

Puede establecer el punto central de un pincel de degradado de trazado en una ubicación situada fuera del trazado que se usó para construir el pincel. En el código anterior, si reemplaza la llamada a PathGradientBrush::SetCenterPoint por pthGrBrush.SetCenterPoint(Point(145, 35)), obtendrá el siguiente resultado.

ilustración que muestra una elipse que se rellena de azul a aguamarina desde un punto central que está fuera del borde de la elipse

En la ilustración anterior, los puntos situados en el extremo derecho de la elipse no son azules puros (aunque están muy cerca). Los colores del degradado se colocan como si se hubiera permitido que el relleno alcanzara el punto (145, 35), el color habría alcanzado el azul puro (0, 0, 255). Pero el relleno nunca alcanza (145, 35) porque un pincel de degradado de trazado solo pinta dentro de su trazado.

Cómo se calcula el color del degradado de la trayectoria

Para cada píxel dentro del trazado, el pincel traza un rayo imaginario desde el punto central, a través del píxel, hasta el punto en que el rayo intersecta el contorno del trazado. El color de ese píxel se interpola linealmente entre el color central y el color del límite, en función de la posición del píxel a lo largo de ese rayo. En concreto, el factor de interpolación es la relación de la distancia desde el punto central hasta el píxel, dividido por la distancia total desde el punto central hasta la intersección del límite.

Cuando el punto central está fuera de la ruta de acceso, los píxeles del lado de la ruta de acceso más cercana al punto central tienen rayos cortos (porque el límite está cerca en esa dirección). Dado que estos píxeles están relativamente lejos a lo largo de sus rayos cortos, aparecen más cerca del color central. Los píxeles del lado lejano de la ruta tienen rayos largos y aparecen más cerca del color del límite. Esto explica por qué, en la ilustración anterior, el límite cerca del punto central externo muestra un color cerca del azul (el color central) en lugar de agua aqua (el color del límite).