Introduction to Filling a Shape
Introduction to Filling a Shape
Polygons
Filling Out a Polygon
As we know already, a polygon is a series of connected lines that form a closed shape. In previous lessons, we learned to draw empty polygons. To let you fill out a polygon with a color, the Graphics class provides an overloaded method named FillPolygon. One of the versions of this method uses the following syntax:
public void FillPolygon(System.Drawing.Brush brush, System.Drawing.Point[] points);
After the first argument that represents the brush, the second argument is an array of points. Here is an example of calling this method:
private void Exercise_Paint(object sender, PaintEventArgs e) { Graphics grapher = e.Graphics; Point[] pts = { new( 30, 100), new(380, 100), new(350, 40), new(548, 130), new(350, 220), new(380, 160), new( 30, 160) }; Pen penCurrent = new Pen(Brushes.Maroon, 6.426F); SolidBrush brush = new SolidBrush(Color.FromArgb(245, 175, 55)); grapher.FillPolygon(brush, pts); grapher.DrawPolygon(penCurrent, pts); }
This would produce:
If you want your points to use decimal numbers, the Graphics class provides another version of its FillPolygon() method. Its syntax is:
public void FillPolygon (System.Drawing.Brush brush, params System.Drawing.PointF[] points);
This version expects an array of PointF objects.
Practical Learning: Introducing Brushes
Filling Out a Rectangle
So far, for our introduction to brushes, we used the Graphics.FillRectangle() method to fill a rectangular object. In reality, the Graphics class provides various (four) versions of its FillRectangle() method. In the above examples, we used natural numbers for the arguments. If you want the values to use more precision, the Graphics class provides another version of the method whose syntax is:
public void FillRectangle(System.Drawing.Brush brush, float x, float y, float width, float height);
This time, provide the values with decimal numbers. Another technique is to provide the rectangle you want to fill. To support this, the Graphics class provides the following version of its FillRectangle() method:
public void FillRectangle (System.Drawing.Brush brush, System.Drawing.Rectangle rect);
This version takes a Rectangle object as argument. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { BackColor = Color.Navy; Pen penCurrent = new Pen(Brushes.Khaki, 6.668F); Rectangle rect = new(15, 22, 572, 182); Brush painter = Brushes.DarkSlateGray; e.Graphics.FillRectangle(painter, rect); e.Graphics.DrawRectangle(penCurrent, rect); }
This would produce:
The rectangle in the above example used natural numbers. If you want to use a rectangle with decimal values, the Graphics class provides another version of the FillRectangle()as method. Its syntax is:
public void FillRectangle(System.Drawing.Brush brush, System.Drawing.RectangleF rect);
This time too, provide the coordinates and the size of the rectangle with decimal values.
Filling a Series of Rectangles
You can draw a series of rectangles each with a location and size of your choice but paint them with the same color. To support this, the Graphics class is equipped with an overloaded method named FillRectangles. One of its versions uses the following syntax:
public void FillRectangles(System.Drawing.Brush brush, params System.Drawing.Rectangle[] rects);
This method expects an array of rectangles as argument. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { Graphics grapher = e.Graphics; Brush brush = new SolidBrush(Color.FromArgb(55, 125, 255)); Pen penBorder = new Pen(Color.DarkBlue, 6.624F); Rectangle[] rects = { new Rectangle(145, 20, 380, 100), new Rectangle(28, 140, 580, 65), new Rectangle(60, 240, 320, 125) }; grapher.FillRectangles(brush, rects); grapher.DrawRectangles(penBorder, rects); brush.Dispose(); }
This would produce:
Another version of the Graphics.DrawRectangles() method allows you to use decimal values on the rectangles of the array passed as argument. Its syntax is:
public void FillRectangles(System.Drawing.Brush brush, params System.Drawing.RectangleF[] rects);
Painting an Ellipse
An Ellipse in a Rectangle
We already saw how to draw an ellipse by its borders. To allow you to fill out an ellipse, the Graphics class is equipped with an overloaded method named FillEllipse method. Its syntax is:
public void FillEllipse (System.Drawing.Brush brush, System.Drawing.Rectangle rect);
This method takes a rectangle as argument. The compiler would then draw an ellipse within that rectangle. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { Pen pnMarker = new Pen(Brushes.DarkRed, 1.50F); Pen pnCorner = new Pen(Color.FromArgb(25, 175, 165), 2.252F); Brush painter = new SolidBrush(Color.FromKnownColor(KnownColor.Crimson)); Rectangle rect = new(40, 40, 555, 227); e.Graphics.FillEllipse(rect: rect, brush: painter); e.Graphics.DrawRectangle(rect: rect, pen: pnMarker); e.Graphics.DrawEllipse(pnCorner, rect.X - 10, rect.Y - 10, 20, 20); e.Graphics.DrawEllipse(pnCorner, rect.X + rect.Width - 10, rect.Y - 10, 20, 20); e.Graphics.DrawEllipse(pnCorner, rect.X - 10, rect.Y + rect.Height - 10, 20, 20); e.Graphics.DrawEllipse(pnCorner, rect.X + rect.Width - 10, rect.Y + rect.Height - 10, 20, 20); }
This would produce:
If you prefer an ellipse that uses decimal number, the .NET Framework provides another version of the Graphics.FillEllipse() method whose syntax is:
public void FillEllipse(System.Drawing.Brush brush, System.Drawing.RectangleF rect);
An Ellipse from Points
This method takes a RectangleF object as argument. As an alternative to the above two versions, you may prefer to define an ellipse from its top-left corner and its size. To support this, the Graphics class provides another version of its FillEllipse() method. Its syntax is:
public void FillEllipse (System.Drawing.Brush brush, int x, int y, int width, int height);
Here are examples that call this method:
private void Exercise_Paint(object sender, PaintEventArgs e) { Brush painter; using (painter = new SolidBrush(Color.FromKnownColor(KnownColor.Peru))) { Graphics graphing = e.Graphics; Pen pnMarker = new Pen(Brushes.Black, 2.55F); // Left Ear int x = 83, y = 140, width = 50, height = 120; painter = new SolidBrush(Color.FromKnownColor(KnownColor.Peru)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Right Ear x = 388; painter = new SolidBrush(Color.FromKnownColor(KnownColor.Peru)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Head Contour painter = new SolidBrush(Color.FromKnownColor(KnownColor.PeachPuff)); x = 120; y = 20; width = 285; height = 388; graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Left Eye x = 173; y = 140; width = 50; height = 30; painter = new SolidBrush(Color.FromKnownColor(KnownColor.SeaShell)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); x = 187; y = 148; width = 20; height = 15; painter = new SolidBrush(Color.FromKnownColor(KnownColor.DarkRed)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Right Eye x = 303; y = 140; width = 50; height = 30; painter = new SolidBrush(Color.FromKnownColor(KnownColor.SeaShell)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); x = 317; y = 148; width = 20; height = 15; painter = new SolidBrush(Color.FromKnownColor(KnownColor.DarkRed)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Nose x = 233; y = 140; width = 60; height = 140; painter = new SolidBrush(Color.FromKnownColor(KnownColor.BurlyWood)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); // Mouth x = 205; y = 300; width = 120; height = 40; painter = new SolidBrush(Color.FromKnownColor(KnownColor.Orange)); graphing.FillEllipse(painter, x, y, width, height); graphing.DrawEllipse(pnMarker, x, y, width, height); } }
This would produce:
Painting a Circle
We had already learned to draw a circle. To draw and fill a circle, call the Graphics.DrawEllipse() method where the width and the height of the enclosing rectangle are the same. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { Graphics grapher = e.Graphics; SolidBrush painter = new SolidBrush(Color.Green); int diameter = 200; Rectangle rect = new(20, 20, diameter, diameter); grapher.FillEllipse(painter, rect); painter = new SolidBrush(Color.Red); rect = new(220, 20, diameter, diameter); grapher.FillEllipse(painter, rect); painter = new SolidBrush(Color.Yellow); rect = new(420, 20, diameter, diameter); grapher.FillEllipse(painter, rect); painter = new SolidBrush(Color.FromArgb(55, 155, 215)); rect = new(120, 193, diameter, diameter); grapher.FillEllipse(painter, rect); painter = new SolidBrush(Color.FromArgb(235, 155, 105)); rect = new(320, 193, diameter, diameter); grapher.FillEllipse(painter, rect); painter.Dispose(); }
This would produce:
Practical Learning: Designing a Form
Control | Name | Other Properties | ||
Label | Sales per Category _________________________________________________________ | Font: Times New Roman, 12pt, style=Bold | ||
Label | Single Families | |||
Label | Townhouses | |||
Label | Condominiums | |||
Label | Others | |||
Button | btnGenerateChart | Generate Chart | ||
TextBox | txtSingleFamilies | TextAlign: Right | ||
TextBox | txtTownhouses | TextAlign: Right | ||
TextBox | txtCondominiums | TextAlign: Right | ||
TextBox | txtOthers | TextAlign: Right | ||
PictureBox | pbxChart | |||
Label | Legend | Font: Times New Roman, 12pt, style=Bold | ||
Label | BackColor: Black AutoSize: False |
|||
Label | Single Families | |||
Label | Townhouses | |||
PictureBox | pbxSingleFamilies | BackColor: Green BorderStyle: Fixed3D |
||
PictureBox | pbxTownhouses | BackColor: Red BorderStyle: Fixed3D |
||
Label | Condominiums | |||
Label | Others | |||
PictureBox | pbxCondominiums | BackColor: Blue BorderStyle: Fixed3D |
||
PictureBox | pbxOthers | BackColor: DeepSkyBlue BorderStyle: Fixed3D |
||
Button | btnClose | Close |
Painting a Fraction of an Ellipse
Painting a Pie
We already know that a pie is a closed fraction of an ellipse. If you want to draw a pie and paint it with a certain color, to let you perform that operation, the Graphics class is equipped with an overloaded method named FillPie. One of the versions uses the following syntax:
public void FillPie (System.Drawing.Brush brush, int x, int y, int width, int height, int startAngle, int sweepAngle);
When calling this method, pass a brush as its first argument. In turn, pass the coordinates of the top-left corner of the shape, a width, and a height of the shape in which to draw an ellipse. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { int topLeftX = 20; int topLeftY = 20; int width = 985; int height = 435; Pen pnContour = new Pen(Color.FromArgb(208, 39, 4), 12.885F); Brush brush = new SolidBrush(Color.BurlyWood); e.Graphics.FillPie(brush, topLeftX, topLeftY, width, height, 45, 255); e.Graphics.DrawPie(pnContour, topLeftX, topLeftY, width, height, 45, 255); brush.Dispose(); }
This would produce:
In the above version of the Graphics.FillPie() method, we used integral value. To let you use decimal values, the Graphics class provides the following syntax for another version of its FillPie() method:
public void FillPie(System.Drawing.Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle);
Instead of explicitely indicate t he origin and the size of the shape, you can specify a rectangle instead. To support this, the Graphics class is equipped with another version of its FillPie() method. Its syntax is:
public void FillPie(System.Drawing.Brush brush, System.Drawing.Rectangle rect, float startAngle, float sweepAngle);
This time, pass a rectangle as the second argument. Here is an example:
private void Exercise_Paint(object sender, PaintEventArgs e) { Rectangle rect = new(20, 20, 585, 245); Pen pnContour = new Pen(Color.FromArgb(20, 40, 4), 12.885F); Brush brush = new SolidBrush(Color.LightSeaGreen); e.Graphics.FillPie(brush, rect, 145, 255); e.Graphics.DrawPie(pnContour, rect, 145, 255); brush.Dispose(); }
This would produce:
If you want, you can draw a more precise pie that uses decimal values. To support this, the Graphics class provides another version of its FillPie() method. Its syntax is:
public void FillPie (System.Drawing.Brush brush, System.Drawing.RectangleF rect, float startAngle, float sweepAngle);
Practical Learning: Using Texture Brushes
namespace AltairRealtors1 { public partial class HouseSales : Form { float singleFamilies; float townhouses; float condominiums; float otherProperties; Brush? brushSingleFamilies; Brush? brushTownhouses; Brush? brushCondominiums; Brush? brushOthers; public HouseSales() { InitializeComponent(); } private void HouseSales_Load(object sender, EventArgs e) { brushOthers = new SolidBrush(pbxOthers.BackColor); brushTownhouses = new SolidBrush(pbxTownhouses.BackColor); brushCondominiums = new SolidBrush(pbxCondominiums.BackColor); brushSingleFamilies = new SolidBrush(pbxSingleFamilies.BackColor); } private void pbxSingleFamilies_Click(object sender, EventArgs e) { if (dlgColor.ShowDialog() == DialogResult.OK) { pbxSingleFamilies.BackColor = dlgColor.Color; brushSingleFamilies = new SolidBrush(dlgColor.Color); } } private void pbxTownhouses_Click(object sender, EventArgs e) { if (dlgColor.ShowDialog() == DialogResult.OK) { pbxTownhouses.BackColor = dlgColor.Color; brushTownhouses = new SolidBrush(dlgColor.Color); } } private void pbxCondominiums_Click(object sender, EventArgs e) { if (dlgColor.ShowDialog() == DialogResult.OK) { pbxCondominiums.BackColor = dlgColor.Color; brushCondominiums = new SolidBrush(dlgColor.Color); } } private void pbxOthers_Click(object sender, EventArgs e) { if (dlgColor.ShowDialog() == DialogResult.OK) { pbxOthers.BackColor = dlgColor.Color; brushOthers = new SolidBrush(dlgColor.Color); } } private void HouseSales_Paint(object sender, PaintEventArgs e) { Pen pnBorder = new Pen(Color.Black, 3.255F); Graphics grapher = pbxChart.CreateGraphics(); grapher.FillPie(brushSingleFamilies!, 20.00F, 20.00F, 750.00F, 650.00F, 0.00F, singleFamilies); grapher.FillPie(brushTownhouses!, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies, townhouses); grapher.FillPie(brushCondominiums!, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies + townhouses, condominiums); grapher.FillPie(brushOthers!, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies + townhouses + condominiums, otherProperties); grapher.DrawPie(pnBorder, 20.00F, 20.00F, 750.00F, 650.00F, 0.00F, singleFamilies); grapher.DrawPie(pnBorder, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies, townhouses); grapher.DrawPie(pnBorder, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies + townhouses, condominiums); grapher.DrawPie(pnBorder, 20.00F, 20.00F, 750.00F, 650.00F, singleFamilies + townhouses + condominiums, otherProperties); } private void pbxChart_Paint(object sender, PaintEventArgs e) { Invalidate(); } private void btnGenerateChart_Click(object sender, EventArgs e) { float singles = 0.00F; float towns = 0.00F; float condos = 0.00F; float others = 0.00F; float total; float percentSingleFamilies; float percentTownhouses; float percentCondos; float percentOthers; try { singles = float.Parse(txtSingleFamilies.Text); } catch (Exception ex) when (ex is FormatException fex) { MessageBox.Show("You must provide a valid amount of sales for the single family homes." + Environment.NewLine + "The error produced is: " + fex.Message, "Altair Realtors - House Sales Analysis", MessageBoxButtons.OK, MessageBoxIcon.Information); } try { towns = float.Parse(txtTownhouses.Text); } catch (Exception ex) when (ex is FormatException fex) { MessageBox.Show("Make sure you provide a valid value for the sales of the townhouses." + Environment.NewLine + "The error produced is: " + fex.Message, "Altair Realtors - House Sales Analysis", MessageBoxButtons.OK, MessageBoxIcon.Information); } try { condos = float.Parse(txtCondominiums.Text); } catch (Exception ex) when (ex is FormatException fex) { MessageBox.Show("Provide a valid amount of the sales of the condominiums." + Environment.NewLine + "The error produced is: " + fex.Message, "Altair Realtors - House Sales Analysis", MessageBoxButtons.OK, MessageBoxIcon.Information); } try { others = float.Parse(txtOthers.Text); } catch (Exception ex) when (ex is FormatException fex) { MessageBox.Show("The application needs a valid total value of the sales of the other types of properties." + Environment.NewLine + "The error produced is: " + fex.Message, "Altair Realtors - House Sales Analysis", MessageBoxButtons.OK, MessageBoxIcon.Information); } total = singles + towns + condos + others; percentSingleFamilies = (singles / total) * 100.00F; percentTownhouses = (towns / total) * 100.00F; percentCondos = (condos / total) * 100.00F; percentOthers = (others / total) * 100.00F; singleFamilies = (360 * percentSingleFamilies) / 100.00F; townhouses = (360 * percentTownhouses) / 100.00F; condominiums = (360 * percentCondos) / 100.00F; otherProperties = (360 * percentOthers) / 100.00F; pbxChart.Invalidate(); } private void btnClose_Click(object sender, EventArgs e) { Close(); } } }
Single Families: 9221298 Townhouses: 4111813 Condominiums: 2558803 Others: 1600812
Painting a Closed Curve
Introduction
If you are planning to draw a closed curve and want to fill it with a color of your choice, to assist you, the Graphics class provides an overloaded method named FillClosedCurve. One of its syntaxes is:
public void FillClosedCurve(System.Drawing.Brush brush, params System.Drawing.Point[] points);
Like its counterpart the Graphics.DrawClosedCurve() method, the above version of the Graphics.FillClosedCurve() method takes an array of points as argument. Here is an example of calling it:
private void Exercise_Paint(object sender, PaintEventArgs e) { Graphics graph = e.Graphics; Pen pnBlue = new(Color.Blue, 18.25f); Brush brPaint = new SolidBrush(Color.DeepSkyBlue); try { Point[] points = { new( 120, 550), new( 120, 80), new(375, 300), new(650, 80), new(650, 550) }; graph.DrawClosedCurve(pnBlue, points); graph.FillClosedCurve(brPaint, points); } finally { brPaint.Dispose(); } }
This would produce:
If you want your curve to use more precision by applying decimal numbers, the Graphics class provides another version of its FillClosedCurve() method. Its syntaxes is:
public void FillClosedCurve(System.Drawing.Brush brush, params System.Drawing.PointF[] points);
Applying a Filling Mode
When painting a shape, you can indicate to the compiler how it should fill the area. We already know that this aspect is controlled through a detail referred to as a filling mode. The Graphics.DrawClosedCurve() method supports this technique in the following version:
public void FillClosedCurve (System.Drawing.Brush brush, System.Drawing.Point[] points, System.Drawing.Drawing2D.FillMode fillmode);
If you want the closed curve to be drawn with decimal values, to assist you, the Graphics class provides the following version of the FillClosedCurve() method:
public void FillClosedCurve (System.Drawing.Brush brush, System.Drawing.PointF[] points, System.Drawing.Drawing2D.FillMode fillmode);
Applying a Tension to a Closed Curve
We already know that a tension allows you to decide how the bending sections of a curve must be dealt with. To support this, the Graphics class provides the following version of its FillClosedCurve() method:
public void FillClosedCurve(System.Drawing.Brush brush, System.Drawing.Point[] points, System.Drawing.Drawing2D.FillMode fillmode, float tension);
In this version of the Graphics.FillClosedCurve() method, a value for the tension is passed as the fourth argument. Here is an example:
using System.Drawing.Drawing2D;
namespace GraphicsAccessories
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Paint(object sender, PaintEventArgs e)
{
Graphics graph = e.Graphics;
Pen pnBlue = new(Color.Blue, 18.25f);
Pen pnRed = new(Color.Red, 2.625F);
Brush brPaint = new SolidBrush(Color.DeepSkyBlue);
try
{
Point[] points = { new( 120, 550),
new( 120, 80),
new(375, 300),
new(650, 80),
new(650, 550) };
graph.DrawClosedCurve(pnBlue, points, 0.825F, FillMode.Alternate);
graph.FillClosedCurve(brPaint, points, FillMode.Alternate, 0.825F);
}
finally
{
graph.Dispose();
}
}
}
}
This would produce:
Remember that the value of the tension should be a decimal number between 0.00 and 1.00 with 0.00 meaning no bending and 1.00 being a perfect bend. Therefore, if you want to draw straight lines on the closed curve, pass the tension as 0.00 or close to that balue. Here is an example:
using System.Drawing;
using System.Drawing.Drawing2D;
namespace GraphicsAccessories
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Paint(object sender, PaintEventArgs e)
{
Graphics graph = e.Graphics;
Pen pnBorder = new(Color.DarkRed, 18.25f);
Pen pnCorner = new(Color.Red, 2.625F);
Brush brPaint = new SolidBrush(Color.PapayaWhip);
try
{
Point[] points = { new( 120, 550),
new( 120, 80),
new(375, 300),
new(650, 80),
new(650, 550) };
graph.DrawClosedCurve(pnBorder, points, 0.000F, FillMode.Alternate);
graph.FillClosedCurve(brPaint, points, FillMode.Alternate, 0.000F);
graph.DrawEllipse(pnCorner, points[0].X - 25, points[0].Y - 25, 50, 50);
graph.DrawEllipse(pnCorner, points[1].X - 25, points[1].Y - 25, 50, 50);
graph.DrawEllipse(pnCorner, points[2].X - 25, points[2].Y - 25, 50, 50);
graph.DrawEllipse(pnCorner, points[3].X - 25, points[3].Y - 25, 50, 50);
graph.DrawEllipse(pnCorner, points[4].X - 25, points[4].Y - 25, 50, 50);
}
finally
{
graph.Dispose();
}
}
}
}
This would produce:
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2010-2024, FunctionX | Sunday 12 May 2024, 15:15 | Next |
|