Erstellen eines Pfadverlaufs

Mit der PathGradientBrush-Klasse können Sie die Art und Weise anpassen, wie Sie eine Form mit schrittweisen Farben ausfüllen. Ein PathGradientBrush-Objekt weist einen Grenzpfad und einen Mittelpunkt auf. Sie können eine Farbe für den Mittelpunkt und eine andere Farbe für die Grenze angeben. Sie können auch separate Farben für jeden von mehreren Punkten entlang der Grenze angeben.

Note

In GDI+ ist ein Pfad eine Abfolge von Linien und Kurven, die von einem GraphicsPath-Objekt verwaltet werden. Weitere Informationen zu GDI+-Pfaden finden Sie unter Pfade und Erstellen und Zeichnungspfade.

 

Im folgenden Beispiel wird ein Ellipse mit einem Pfadfarbverlaufspinsel gefüllt. Die Mittelfarbe wird auf Blau festgelegt, und die Begrenzungsfarbe wird auf Aqua festgelegt.

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

Die folgende Abbildung zeigt die gefüllte Ellipse.

Abbildung einer Ellipse mit Verlaufsfüllung

Standardmäßig erstreckt sich ein Pfadfarbverlaufspinsel nicht über die Pfadbegrenzung hinaus. Wenn Sie den Pfadverlaufspinsel verwenden, um eine Form zu füllen, die über die Begrenzung des Pfades hinausgeht, wird der Bereich des Bildschirms außerhalb des Pfades nicht gefüllt. Die folgende Abbildung zeigt, was passiert, wenn Sie den Graphics::FillEllipse-Aufruf im vorhergehenden Code durch graphics.FillRectangle(&pthGrBrush, 0, 10, 200, 40) ersetzen.

Abbildung eines horizontalen Schnitts der vorherigen Ellipse

Angeben von Punkten auf der Grenze

Das folgende Beispiel erzeugt einen Pfadfarbverlaufspinsel aus einem sternförmigen Pfad. Der Code ruft die PathGradientBrush::SetCenterColor-Methode auf, um die Farbe am Mittelpunkt des Sterns auf Rot festzulegen. Anschließend ruft der Code die PathGradientBrush::SetSurroundColors-Methode auf, um verschiedene Farben (in der Farbenarray gespeichert) an den einzelnen Punkten im Punktarray anzugeben. Die letzte Codeanweisung füllt den sternförmigen Pfad mit dem Pfadfarbverlaufspinsel.

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

Die folgende Abbildung zeigt den gefüllten Stern.

Illustration, die einen fünfzackigen Stern zeigt, der sich von Rot in der Mitte zu verschiedenen Farben in jedem Punkt des Sterns füllt

Im folgenden Beispiel wird anhand eines Arrays von Punkten ein Pfadgradientpinsel erstellt. Jeder der fünf Punkte im Array wird eine Farbe zugewiesen. Wenn Sie die fünf Punkte durch gerade Linien verbinden würden, würden Sie ein fünfseitiges Polygon erhalten. Eine Farbe wird auch der Mitte (Mittelpunkt) dieses Polygons zugewiesen – in diesem Beispiel wird die Mitte (80, 75) auf Weiß festgelegt. Die letzte Codeanweisung im Beispiel füllt ein Rechteck mit dem Pfadverlaufspinsel.

Die Farbe, die zum Ausfüllen des Rechtecks verwendet wird, ist weiß bei (80, 75) und ändert sich schrittweise, während Sie sich von (80, 75) in Richtung der Punkte im Array bewegen. Wenn Sie z. B. von (80, 75) zu (0, 0) wechseln, ändert sich die Farbe allmählich von Weiß in Rot, und während Sie von (80, 75) bis (160, 0) wechseln, ändert sich die Farbe allmählich von Weiß zu Grün.

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

Beachten Sie, dass im vorherigen Code kein GraphicsPath-Objekt vorhanden ist. Der bestimmte PathGradientBrush-Konstruktor im Beispiel empfängt einen Zeiger auf ein Array von Punkten, erfordert jedoch kein GraphicsPath-Objekt . Beachten Sie auch, dass der Pinsel für den Pfadverlauf zum Füllen eines Rechtecks und nicht eines Pfades verwendet wird. Das Rechteck ist größer als der Pfad, der zum Definieren des Pinsels verwendet wird, sodass ein Teil des Rechtecks nicht vom Pinsel gezeichnet wird. Die folgende Abbildung zeigt das Rechteck (gepunktete Linie) und den Teil des Rechtecks, der mit dem Pfadverlaufspinsel gezeichnet wurde.

Abbildung eines Rechtecks, das durch eine gepunktete Linie begrenzt ist, teilweise durch einen mehrfarbigen Farbverlauf gezeichnet

Anpassen eines Pfadverlaufs

Eine Möglichkeit, einen Pfadverlaufspinsel anzupassen, besteht darin, seine Fokusskala festzulegen. Die Fokusskalierung gibt einen inneren Pfad an, der sich innerhalb des Hauptpfads befindet. Die Mittelfarbe wird überall innerhalb dieses inneren Pfads und nicht nur am Mittelpunkt angezeigt. Um die Fokusskalen eines Pfadverlaufpinsels festzulegen, rufen Sie die PathGradientBrush::SetFocusScales-Methode auf.

Das folgende Beispiel erstellt einen Pfadfarbverlaufspinsel, der auf einem elliptischen Pfad basiert. Der Code legt die Begrenzungsfarbe auf Blau fest, legt die Mittelfarbe auf Aqua fest und verwendet dann den Pfadverlaufspinsel, um den elliptischen Pfad auszufüllen.

Als nächstes legt der Code die Fokus-Skalen des Pfadverlaufs-Pinsels fest. Die x-Fokusskala ist auf 0,3 festgelegt, und die y-Fokusskalierung wird auf 0,8 festgelegt. Der Code ruft die Graphics::TranslateTransform-Methode eines Graphics-Objekts auf, sodass der nachfolgende Aufruf von Graphics::FillPath eine Ellipse füllt, die sich rechts neben der ersten Ellipse befindet.

Um die Wirkung der Fokusskalen zu sehen, stellen Sie sich eine kleine Ellipse vor, die ihren Mittelpunkt mit der Hauptellipse teilt. Die kleine (innere) Ellipse ist die Hauptellipse, die horizontal mit einem Faktor von 0,3 und vertikal mit einem Faktor von 0,8 skaliert wurde (um ihr Zentrum). Während Sie von der Grenze der äußeren Ellipse zur Grenze der inneren Ellipse wechseln, ändert sich die Farbe allmählich von Blau in Aqua. Wenn Sie sich vom Rand der inneren Ellipse zum gemeinsamen Mittelpunkt bewegen, bleibt die Farbe aqua.

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

Die folgende Abbildung zeigt die Ausgabe des vorstehenden Codes. Die Ellipse links ist aqua nur am Mittelpunkt. Die Ellipse rechts ist innerhalb des inneren Pfads überall aqua.

Abbildung mit zwei Ellipsen, die von Aqua zu Blau verlaufen: die erste hat sehr wenig Aqua; die zweite hat viel mehr

Eine weitere Möglichkeit zum Anpassen eines Pfadverlaufpinsels besteht darin, ein Array von voreingestellten Farben und ein Array von Interpolationspositionen anzugeben.

Das folgende Beispiel erstellt einen Pfadfarbverlaufspinsel auf der Basis eines Dreiecks. Der Code ruft die PathGradientBrush::SetInterpolationColors-Methode des Pfadverlaufspinsels auf, um ein Array von Interpolationsfarben (Dunkelgrün, Aqua, Blau) und ein Array von Interpolationspositionen (0, 0,25, 1) anzugeben. Während Sie von der Grenze des Dreiecks zum Mittelpunkt wechseln, ändert sich die Farbe allmählich von Dunkelgrün zu Aqua und dann von Aqua zu Blau. Der Wechsel von Dunkelgrün zu Aqua erfolgt in 25 Prozent des Abstands von Dunkelgrün zu Blau.

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

Die folgende Abbildung zeigt die Ausgabe des vorangehenden Codes.

Abbildung eines Dreiecks mit einem Farbverlauf von Blau in der Mitte über Aqua bis Grün an den Rändern

Festlegen des Mittelpunkts

Standardmäßig befindet sich der Mittelpunkt eines Pfadfarbverlaufspinsels im Mittelpunkt des Pfads, der zum Erstellen des Pinsels verwendet wurde. Sie können die Position des Mittelpunkts ändern, indem Sie die PathGradientBrush::SetCenterPoint-Methode der PathGradientBrush-Klasse aufrufen.

Das folgende Beispiel erstellt einen Pfadfarbverlaufspinsel, der auf einer Ellipse basiert. Der Mittelpunkt der Ellipse liegt bei (70, 35), aber der Mittelpunkt des Pfadfarbverlaufspinsels ist auf (120, 40) festgelegt.

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

Die folgende Abbildung zeigt die gefüllte Ellipse und den Mittelpunkt des Pinsels mit dem Pfadverlauf.

Illustration einer Ellipse, die sich von einem Mittelpunkt in der Nähe eines Endes von blau nach aqua füllt

Sie können den Mittelpunkt eines Pfadfarbverlaufspinsels auf eine Position außerhalb des Pfads festlegen, der zum Erstellen des Pinsels verwendet wurde. Wenn Sie den Aufruf von PathGradientBrush::SetCenterPoint durch pthGrBrush.SetCenterPoint(Point(145, 35))den vorherigen Code ersetzen, erhalten Sie das folgende Ergebnis.

Abbildung einer Ellipse, die von Blau bis Aqua von einem Mittelpunkt aus füllt, der sich außerhalb des Rands der Ellipse befindet

In der vorstehenden Abbildung sind die Punkte ganz rechts der Ellipse nicht rein blau (obwohl sie sehr nahe sind). Die Farben im Farbverlauf sind so positioniert, als hätte die Füllung den Punkt (145, 35) erreichen dürfen; die Farbe hätte dort reines Blau (0, 0, 255) erreicht. Aber die Füllung erreicht nie (145, 35), weil ein Pfadfarbverlaufspinsel nur innerhalb seines Pfads zeichnet.

Wie die Verlaufsfarbe eines Pfads berechnet wird

Für jedes Pixel innerhalb des Pfads projiziert der Pinsel einen imaginären Strahl vom Mittelpunkt aus durch das Pixel bis zu dem Punkt, an dem der Strahl auf die Begrenzung des Pfads trifft. Die Farbe an diesem Pixel wird dann linear zwischen der Mittelfarbe und der Begrenzungsfarbe basierend auf der Position des Pixels entlang dieses Strahls interpoliert. Insbesondere ist der Interpolationsfaktor das Verhältnis des Abstands vom Mittelpunkt zum Pixel, dividiert durch den Gesamtabstand vom Mittelpunkt zum Grenzkreuz.

Wenn sich der Mittelpunkt außerhalb des Pfads befindet, weisen Pixel auf der Seite des Pfads, die dem Mittelpunkt am nächsten sind, kurze Strahlen auf (da sich die Grenze in dieser Richtung in der Nähe befindet). Da diese Pixel relativ weit entlang ihrer kurzen Strahlen liegen, erscheinen sie näher an der Mittelfarbe. Pixel auf der fernen Seite des Pfads weisen lange Strahlen auf und erscheinen näher an der Begrenzungsfarbe. Dies erklärt, warum in der vorstehenden Abbildung die Grenze in der Nähe des externen Mittelpunkts eine Farbe in der Nähe von Blau (der Mittelfarbe) anstelle von Aqua (der Begrenzungsfarbe) anzeigt.