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:

Solid Brushes

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 LearningPractical Learning: Introducing Brushes

  1. Start Microsoft Visual Studio
  2. Create a new Windows Forms App named AltairRealtors1
  3. In the Properties window, right-click Form1.cs and click Rename
  4. Type HouseSales (to get HouseSales.cs) and press Enter twice
  5. In the Toolbox, expand the Dialogs node, click ColorDialog and Click the form
  6. In the Properties Window, click (Name) and type dlgColor

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:

Solid Brushes

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:

Solid Brushes

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:

Solid Brushes

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:

Solid Brushes

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:

Solid Brushes

Practical LearningPractical Learning: Designing a Form

  1. Design the form as follows:

    Altair Realtors - House Sales Analysis

    Control Name Other Properties
    Label Label   Sales per Category _________________________________________________________ Font: Times New Roman, 12pt, style=Bold
    Label Label   Single Families  
    Label Label   Townhouses  
    Label Label   Condominiums  
    Label Label   Others  
    Button Button btnGenerateChart Generate Chart  
    TextBox TextBox txtSingleFamilies   TextAlign: Right
    TextBox TextBox txtTownhouses   TextAlign: Right
    TextBox TextBox txtCondominiums   TextAlign: Right
    TextBox TextBox txtOthers   TextAlign: Right
    PictureBox PictureBox pbxChart    
    Label Label   Legend Font: Times New Roman, 12pt, style=Bold
    Label Label     BackColor: Black
    AutoSize: False
    Label Label   Single Families  
    Label Label   Townhouses  
    PictureBox PictureBox pbxSingleFamilies   BackColor: Green
    BorderStyle: Fixed3D
    PictureBox PictureBox pbxTownhouses   BackColor: Red
    BorderStyle: Fixed3D
    Label Label   Condominiums  
    Label Label   Others  
    PictureBox PictureBox pbxCondominiums   BackColor: Blue
    BorderStyle: Fixed3D
    PictureBox PictureBox pbxOthers   BackColor: DeepSkyBlue
    BorderStyle: Fixed3D
    Button 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:

Geometric Shape - Pie

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:

Geometric Shape - Pie

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 LearningPractical Learning: Using Texture Brushes

  1. Double-click an unoccupied area of the form to generate its Load Event
  2. Return to the form and double-click the green picture box below the right Single Families label to generate its Click event
  3. Return to the form and double-click the red picture box below the right Townhouses label to generate its Click event
  4. Return to the form and double-click the blue picture box below the right Condominiums label
  5. Return to the form and double-click the deep sky blue picture box below the right Others label
  6. return to the form and click an unoccupied area of its body
  7. In the Properties window, click the Events button Events
  8. In the Events section of the Properties window, double-click the Paint field
  9. Return to the form and click the large picture box in the bottom-left side
  10. In the Events section of the Properties window, double-click Paint
  11. Return to the form and double-click the Generate Chart button
  12. Return to the form and double-click the Close button
  13. Change the document as follows:
    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();
            }
        }
    }
  14. To execute the application, on the main menu, click Debug and click Start Without Debugging:

    Altair Realtors - House Sales Analysis

  15. Enter the following values in the text boxes:
    Single Families: 9221298
    Townhouses:      4111813
    Condominiums:    2558803
    Others:          1600812

    Altair Realtors - House Sales Analysis

  16. Click the Generate Chart button:

    Altair Realtors - House Sales Analysis

  17. Change some colors and see the effects, then change the values and click the Generate Chart button:

    Altair Realtors - House Sales Analysis

  18. Close the form and return to your programming environment

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:

Geometric Shapes - A Closed Curve

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:

Geometric Shapes - A Closed Curve with a Tension

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:

Geometric Shapes - A Closed Curve with a Tension

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2010-2024, FunctionX Sunday 12 May 2024, 15:15 Next