Let the user draw and move polygons in C#

example

This example lets the user draw and move polygons. It builds on the example Let the user draw polygons in C#.

The program uses MouseDown, MouseMove, and MouseUp event handlers to let the user draw and interact with the polygons. You could write three complex event handlers to handle every situation. For example, the MouseMove event handler would take different actions depending on whether the user was:

  • Drawing a new polygon
  • Moving a polygon
  • Moving a polygon’s vertex
  • Doing nothing

To make the event handlers easier to understand, this program uses separate, simpler event handlers to handle different tasks:

  • picCanvas_MouseDown – Handles all mouse down events. Depending on what is under the mouse, this event handler:
    • Adds a new point to the new polygon.
    • Finishes drawing the new polygon (right button).
    • Starts moving a polygon’s corner point.
    • Starts moving a polygon.
    • Starts drawing a new polygon.
  • picCanvas_MouseMove_Drawing – Moves the next point for a new polygon.
  • picCanvas_MouseMove_MovingCorner – Moves a polygon’s corner.
  • picCanvas_MouseUp_MovingCorner – Stops moving a polygon’s corner.
  • picCanvas_MouseMove_MovingPolygon – Moves a polygon.
  • picCanvas_MouseUp_MovingPolygon – Stops moving a polygon.
  • picCanvas_MouseMove_NotDrawing – Sees what the mouse is over and changes the cursor accordingly.
  • picCanvas_Paint – Redraws the polygons and any new polygon.

The various event handlers add and remove other event handlers as necessary. For example, the following code snippet shows how the program starts moving a polygon when you press the mouse down over it.

...
else if (MouseIsOverPolygon(e.Location, out hit_polygon))
{
    // Start moving this polygon.
    picCanvas.MouseMove -= picCanvas_MouseMove_NotDrawing;
    picCanvas.MouseMove += picCanvas_MouseMove_MovingPolygon;
    picCanvas.MouseUp += picCanvas_MouseUp_MovingPolygon;

    // Remember the polygon.
    MovingPolygon = hit_polygon;

    // Remember the offset from the mouse
    // to the segment's first point.
    OffsetX = hit_polygon[0].X - e.X;
    OffsetY = hit_polygon[0].Y - e.Y;
}
else
...

This code first uses the MouseIsOverPolygon method to determine whether the mouse is over a polygon. If the mouse is over a polygon, that method returns true and returns the polygon through the output parameter hit_polygon.

If the mouse is over a polygon, the code removes the picCanvas_MouseMove_NotDrawing event handler that is used while not drawing. Then it installs the MouseMove and MouseUp event handlers that is uses while moving a polygon. It saves the polygon it will move and saves the offset between the mouse and the polygon’s first corner point. The newly installed event handlers do the rest.

The following code shows how the program moves a polygon.

// Move the selected polygon.
private void picCanvas_MouseMove_MovingPolygon(
    object sender, MouseEventArgs e)
{
    // See how far the first point will move.
    int new_x1 = e.X + OffsetX;
    int new_y1 = e.Y + OffsetY;

    int dx = new_x1 - MovingPolygon[0].X;
    int dy = new_y1 - MovingPolygon[0].Y;

    if (dx == 0 && dy == 0) return;

    // Move the polygon.
    for (int i = 0; i < MovingPolygon.Count; i++)
    {
        MovingPolygon[i] = new Point(
            MovingPolygon[i].X + dx,
            MovingPolygon[i].Y + dy);
    }

    // Redraw.
    picCanvas.Invalidate();
}

This code adds the original offset to the mouse’s current position to determine where the polygon’s first point should be now. It calculates the distance it must move that point from its current position and then adds that amount to each of the polygon’s points. The code finishes by redrawing.

The following code shows how the program stops moving a polygon when you release the mouse.

// Finish moving the selected polygon.
private void picCanvas_MouseUp_MovingPolygon(
    object sender, MouseEventArgs e)
{
    picCanvas.MouseMove += picCanvas_MouseMove_NotDrawing;
    picCanvas.MouseMove -= picCanvas_MouseMove_MovingPolygon;
    picCanvas.MouseUp -= picCanvas_MouseUp_MovingPolygon;
}

This code simply restores the original event handlers that should be used while not drawing or moving anything.

Moving a polygon vertex is similar to moving a polygon, with some minor differences. See the code for more details.

Creating polygons is similar to the method used by the previous example.


Download Example   Follow me on Twitter   RSS feed   Donate




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

13 Responses to Let the user draw and move polygons in C#

  1. Christina Lilja says:

    Thank you very much for sharing this code. It is part of what my users want. Besides being able to move the whole polygon and the vertices one by one, they also want to add a vertex. My problem is that I am just not able to figure out between which vertices the user is clicking, and wants to add the new vertex. If you have a solution to this problem, I would be so grateful.

  2. Pingback: Let the user draw polygons, move them, and add points to them in C# -

  3. müslüm says:

    howto in the area of ​​the polygon getPixel ? please help

  4. Isaac says:

    Please i need to get Final Polygon ( i mean after i fished draw my polygon ) points Array
    Please help?

    • RodStephens says:

      If you look in picCanvas_MouseDown, you’ll find this code:

      // Finish this polygon.
      if (NewPolygon.Count > 2) Polygons.Add(NewPolygon);

      This is where the program finishes creating the new polygon so it’s where you can get the new polygon’s points.

      NewPolygon is a List<Point>. You can just loop through its points to see what they are.

  5. RodStephens says:

    To remove all polygons you could use:

    Polygons.Clear();
    picCanvas.Refresh();

    To remove a single polygon, you would need to know which one and then use something like:

    Polygons.RemoveAt(1);
    picCanvas.Refresh();

Leave a Reply

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