Let the user draw polygons, move them, and add points to them in C#

draw polygons, move them, and add points to them

This example lets the user draw polygons, move them, and add points to them. It’s an extension of the example Let the user draw and move polygons in C#. See that example for a description of most of this program’s code.

The previous version lets you click to create polygons. It also lets you click and drag to move polygon vertices or the polygons themselves. This example adds the ability to add new points to a polygon. If you move the mouse over a polygon’s edge, the program changes its cursor to an “add point” cursor (a little box with a plus sign in it). If you click, the program adds a new point to the polygon at that position.

Adding new points requires three main changes: detecting when the mouse is over a polygon’s edge, displaying the “add point” cursor, and adding the new point.

At design time, I added a resource containing the “add point” cursor as a bitmapped image. When the program starts, it uses the following code to use that image to create the “add point” cursor.

// The add point cursor.
private Cursor AddPointCursor;

// Create the add point cursor.
private void Form1_Load(object sender, EventArgs e)
    AddPointCursor = new Cursor(

This code simply gets the “add point” image, uses its GetHicon method to get a handle to the image as an icon, and then passes the handle to the Cursor class’s constructor.

When the program is not drawing a new polygon, the PictureBox‘s MouseMove event handler uses a series of if-else statements to determine where the mouse is and what kind of cursor the program should display. The following code shows how it displays the “add point” cursor.

else if (MouseIsOverEdge(mouse_pt, out hit_polygon,
    out hit_point, out hit_point2, out closest_point))
    new_cursor = AddPointCursor;

If the MouseIsOverEdge method determines that the mouse’s position is over a polygon’s edge, this code displays the new cursor. The following code shows the MouseIsOverEdge method. (This is where things start to get interesting.)

// See if the mouse is over a polygon's edge.
private bool MouseIsOverEdge(Point mouse_pt,
    out List hit_polygon, out int hit_pt1,
    out int hit_pt2, out Point closest_point)
    // Examine each polygon.
    // Examine them in reverse order to check those on top first.
    for (int pgon = Polygons.Count - 1; pgon >= 0; pgon--)
        List polygon = Polygons[pgon];

        // See if we're over one of the polygon's segments.
        for (int p1 = 0; p1 < polygon.Count; p1++)
            // Get the index of the polygon's next point.
            int p2 = (p1 + 1) % polygon.Count;

            // See if we're over the segment between these points.
            PointF closest;
            if (FindDistanceToSegmentSquared(mouse_pt,
                polygon[p1], polygon[p2], out closest) <
                // We're over this segment.
                hit_polygon = polygon;
                hit_pt1 = p1;
                hit_pt2 = p2;
                closest_point = Point.Round(closest);
                return true;

    hit_polygon = null;
    hit_pt1 = -1;
    hit_pt2 = -1;
    closest_point = new Point(0, 0);
    return false;

This method loops through the polygons. It loops through them in reverse order so they are considered from top to bottom. That way if the mouse is over multiple polygons’ edges, the program picks the polygon that is higher in the stacking order.

For each polygon, the program loops through the polygon’s points. For each point, it determines the index of the following point and calls the FindDistanceToSegmentSquared method to see if the mouse is within a given minimum distance of the segment between the two points. If it is, the MouseIsOverEdge method records the polygon and points and returns true.

If it finishes checking all of the polygons without finding an edge under the mouse, MouseIsOverEdge returns false.

See the example Find the shortest distance between a point and a line segment in C# to learn how the FindDistanceToSegmentSquared method works.

The last new part of the program is the code that creates the new point. When you click the mouse, the picCanvas_MouseDown event handler executes. If the program is drawing a new polygon, the code adds a new point to it. Otherwise the program uses the following code to determine whether it should add a new point to an existing polygon.

else if (MouseIsOverEdge(mouse_pt, out hit_polygon,
    out hit_point, out hit_point2, out closest_point))
    // Add a point.
    hit_polygon.Insert(hit_point + 1, closest_point);

If the MouseIsOverEdge method indicates that the mouse is over a polygon’s edge, the program inserts a new point in the polygon under the mouse. It adds the new point at the index 1 greater than the first point on the segment under the mouse. For example, suppose the mouse is above the segment connecting the points with indices 7 and 8. Then the program adds the new point at position 8 in the polygon’s list of points so it lies between the two existing points.

That’s all there is to the new “add point” feature. See the previous example for additional details.

Download Example   Follow me on Twitter   RSS feed   Donate

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

15 Responses to Let the user draw polygons, move them, and add points to them in C#

  1. Pingback: Draw and move polygons snapping them to a grid in C# -

  2. Pooja Shahane says:

    Thank you….it is very helpful….But I want to draw same polygon according to user’s input length of sides….means user should dynamically add length of sides in textboxes…accordingly polygon should add on picturebox…then user can move,resize and add points to it…

    • RodStephens says:

      I’m not sure what you mean. Do you mean the user enters points in a text box? You should be able to use the string class’s Split method to break the values into points and then use float.Parse to parse them.

  3. G√ľnter says:

    Thank you, Rod, very good code!
    I would like to save the polygons in a txt-file and open polygons from txt-files.
    txt-file structure like this:
    No. X1, y1, x2, y2 …. xn, yn, color, width, style …
    And it would be grate, to delete corners from polygons

    • RodStephens says:

      There are several ways you can save and restore drawings. You can do it as you say by writing and reading the point coordinates in a file. You could also look at serialization. See this post:

      Save and restore pictures drawn by the user in C#

      To delete a corner, you could make the program display a delete cursor when the mouse is over a corner. If the user clicks, remove that point from the polygon. You’ll probably want to delete the polygon, too, if it has fewer than 3 points left.

      Alternatively you could make a context menu and let the user right-click and select Add Point or Remove Point.

  4. joerock says:

    Dear sir, Example work excellent. btw, could you pls advise how to add ‘zoom’ and ‘pan’ to this example. Thanks..

  5. sidereal says:

    Dear Sir, thank you for this very helpful tutorial.

    Please help me with one thing:
    I need to draw polygon after applying Matrix to Graphics.Transform and do all the operations (draw polygon, find point, move point and polygon) from this tutorial in zoomin/zoomout mode.

    I tried your tutorial “Let the user zoom on a picture in C#”, but after zoomin it is not getting pointer location properly.


  6. Bill says:

    Would it be possible to see the length of each side and the number of degrees in each angle?

    • RodStephens says:

      I think that would be doable. At that point, I think the big question is, “What do you want it to look like?” For example:

      • When drawing the initial polygon, you could label the new edge with its length and its angle with the degrees as you move the mouse.
      • When you move a vertex, you could display the lengths of its adjacent sides and the new angle at the vertex. You could also display the other two nearest angles because they will also change.
      • When you move the mouse over an edge, getting ready to add a new vertex, you could label the two pieces of that edge with their lengths.

      I think you could do all of that, it would just be a matter of figuring out exactly what you want to do and then putting in the work. (Some of that sounds kind of fun so I’ll add it to my list of things to do when I have more time. Unfortunately that list is already pretty long.)

Comments are closed.