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

See the example Let the user draw line segments, and then drag the segments or their end points 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. If the checkbox is checked, this method 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.

// Give the PictureBox a grid background.
private void picCanvas_Resize(object sender, EventArgs e)
{
MakeBackgroundGrid();
}
private void chkSnapToGrid_CheckedChanged(object sender, EventArgs e)
{
MakeBackgroundGrid();
}
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;
}
}

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 SnapToGrid method to snap that point's coordinates to the grid (if appropriate). For example, the following code shows how the program updates the second point for a new segment that the user is drawing.

// Save the new point.
int x = e.X;
int y = e.Y;
SnapToGrid(ref x, ref y);
NewPt2 = new Point(x, y);

The following code shows the SnapToGrid method. It simply rounds the X and Y coordinates to the nearest multiples of the grid's size.

// 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);
}

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.