Let the user draw and move line segments snapping their positions to a snap grid in C#

Draw and move line segments snapping to a grid

See the example Draw and move line segments in C# for basic information about the program. This example does the same thing, but lets you snap segments and end points to a grid.

When the drawing PictureBox is resized or when the “Snap To Grid” checkbox is checked or unchecked, the program calls the MakeBackgroundGrid method shown in the following code.

private void MakeBackgroundGrid()
{
    if (!chkSnapToGrid.Checked)
    {
        picCanvas.BackgroundImage = null;
    }
    else
    {
        Bitmap bm = new Bitmap(
            picCanvas.ClientSize.Width, 
            picCanvas.ClientSize.Height);
        for (int x = 0; x < picCanvas.ClientSize.Width;
            x += grid_gap)
        {
            for (int y = 0; y < picCanvas.ClientSize.Height;
                y += grid_gap)
            {
                bm.SetPixel(x, y, Color.Black);
            }
        }

        picCanvas.BackgroundImage = bm;
    }
}

If the checkbox is not checked, this method sets the picCanvas control’s background to null. Otherwise it makes a bitmap to fit the PictureBox, draws dots on it to show the grid, and sets the PictureBox‘s BackgroundImage property to the bitmap.

The other change to the program is how it handles new points. Whenever the program is about to do something with a point, it calls the following SnapToGrid method to snap that point’s coordinates to the grid (if appropriate).

// Snap to the nearest grid point.
private void SnapToGrid(ref int x, ref int y)
{
    if (!chkSnapToGrid.Checked) return;
    x = grid_gap * (int)Math.Round((double)x / grid_gap);
    y = grid_gap * (int)Math.Round((double)y / grid_gap);
}

This method rounds its x and y parameters to the nearest multiples of the grid’s size.

The following code shows an example of how the program uses the SnapToGrid method. This event handler executes when the user is moving a segment’s end point.

// We're moving an end point.
private void picCanvas_MouseMove_MovingEndPoint(
    object sender, MouseEventArgs e)
{
    // Move the point to its new location.
    int x = e.X + OffsetX;
    int y = e.Y + OffsetY;
    SnapToGrid(ref x, ref y);

    if (MovingStartEndPoint)
        Pt1[MovingSegment] = new Point(x, y);
    else
        Pt2[MovingSegment] = new Point(x, y);

    // Redraw.
    picCanvas.Invalidate();
}

The code gets the mouse’s X and Y coordinates and calls SnapToGrid to snap to the nearest grid location. It then updates the appropriate segment end point (start point or end point) and redraws the PictureBox.

See the previous example for more details.


Download Example   Follow me on Twitter   RSS feed   Donate




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

3 Responses to Let the user draw and move line segments snapping their positions to a snap grid in C#

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

  2. rata says:

    Hi and thanks for the example! How can I ctrl+click to select and move multiple lines segments at once (change position, not start/end points of the line)? I’ve tried moving them but I don’t know how to calculate position of the second selected line, it always snaps to the first selected line, since the mouse position starts at the first selected line.

    Thanks a lot!

    • RodStephens says:

      Sorry but this example can’t do that. It’s a bit more complicated. You need to make a list of selected objects. Then you need to provide mouse events to manage the list. For example, Shift+Click adds a point to the list, Ctrl+Click toggles a point, click-and-drag selects multiple points, Shift+click-and-drag adds multiple points, etc.

      Then when the user clicks-and-drags a selected point, the program needs to move them all.

Leave a Reply

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