Use base insets with custom end caps in C#

[end caps]

The example Draw lines with custom end caps in C# shows how to draw lines with custom end caps. For example, using those techniques you can draw lines with arrowheads or circles at the ends.

The coordinate system for drawing end caps has Y increasing in the direction of the line so, if you draw an end cap that uses a positive Y coordinate, the end cap sticks out beyond the line’s normal end point. If you don’t want it to, you can move the end cap’s shape back so it doesn’t use positive Y coordinate but then it may draw on top of the line itself. If the end cap should be a circle, rectangle, or other open shape, that may look strange.

You can fix this problem by using the CustomLineCap class’s BaseInset property. This value indicates the distance short by which the line should end, measured in line thicknesses as usual.

This example draws lines with a Pen that draws a circle around the line’s starting point and a dot at the line’s ending point. In the top of the picture above, the CustomLineCap objects don’t use BaseInset so the line extends into the center of the circle at the line’s beginning and extends until it touches the point at the line’s end.

After drawing the three upper lines, the program sets BaseInset to 2 for both end caps so the line stops just touching the circle at the beginning and with a small gap between the line and the point at the end.

The following code shows the program’s Paint event handler, which creates the Pen and draws the lines.

private void Form1_Paint(object sender, PaintEventArgs e)
{
   e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

   using (Pen the_pen = new Pen(Color.Blue, 5))
   {
      // Make a GraphicsPath to define the start cap.
      using (GraphicsPath start_path = new GraphicsPath())
      {
         start_path.AddEllipse(-2, -2, 4, 4);

         // Make the start cap.
         using (CustomLineCap start_cap =
            new CustomLineCap(null, start_path))
         {
            // Make a GraphicsPath to define the end cap.
            using (GraphicsPath end_path = new GraphicsPath())
            {
               end_path.AddEllipse(-0.5f, -0.5f, 1, 1);

               // Make the end cap.
               using (CustomLineCap end_cap =
                  new CustomLineCap(end_path, null))
               {
                  the_pen.CustomStartCap = start_cap;
                  the_pen.CustomEndCap = end_cap;

                  // Draw some lines without base insets.
                  the_pen.Color = Color.Green;
                  e.Graphics.DrawLine(the_pen, 20, 20, 125, 60);
                  the_pen.Color = Color.Orange;
                  e.Graphics.DrawLine(the_pen, 125, 60, 210, 30);
                  the_pen.Color = Color.Blue;
                  e.Graphics.DrawLine(the_pen, 210, 30, 300, 70);

                  // Translate and draw with insets.
                  e.Graphics.TranslateTransform(0, 50);
                  start_cap.BaseInset = 2;
                  end_cap.BaseInset = 2;
                  the_pen.CustomStartCap = start_cap;
                  the_pen.CustomEndCap = end_cap;

                  the_pen.Color = Color.Green;
                  e.Graphics.DrawLine(the_pen, 20, 20, 125, 60);
                  the_pen.Color = Color.Orange;
                  e.Graphics.DrawLine(the_pen, 125, 60, 210, 30);
                  the_pen.Color = Color.Blue;
                  e.Graphics.DrawLine(the_pen, 210, 30, 300, 70);
               }
            }
         }
      }
   }
}

The code creates the pen. It then makes a GraphicsPath to represent the pen’s starting cap. It adds a circle to the path and then uses the path to define the starting CustomLineCap.

The code then repeats those steps to create a custom end cap.

Next the program uses the pen to draw three connected line segments. You can see that the line draws into the starting circle and connects to the ending dot.

The program then sets the BaseInset properties to 2 for the custom end caps so the lines begin and end 2 line thicknesses short of their actual end points. The program then draws the line segments again so you can see the result of the new BaseInset values.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *