|
|
Title | Let the user move a polygon's points with grab handles, snapping the points to a grid in VB .NET |
Keywords | polygon, grab handles, snap to, grid, draw, drag |
Categories | Graphics, VB.NET |
|
|
Use mouse event handlers to let the user drag points. When this program's PictureBox resizes, the program builds a bitmap named m_BackgroundBitmap that fits the PictureBox and that contains the positioning grid. When the user drags a point, the program uses this bitmap to erase the polygon and redraw the grid. It then draws the grid with its newly moved point.
The key to snapping points to the positioning grid is the SnapToGrid routine. It snaps a point to the nearest grid point. The program uses this routine to snap the point being dragged to the grid in the MouseMove event handler.
|
|
Private Const GRID_SPACING As Integer = 10
' The grab handle we are dragging. This is
' -1 when we are not dragging any handle.
Private m_DraggingHandle As Integer = -1
' The data points.
Private m_Points() As Point
Private Const HANDLE_WIDTH As Integer = 6
Private Const HANDLE_HALF_WIDTH As Integer = HANDLE_WIDTH \ _
2
' A bitmap containing the grid.
Private m_BackgroundBitmap As Bitmap
' Create some initial point data.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
' Make room.
ReDim m_Points(4)
' Set initial points.
m_Points(0).X = 67 : m_Points(0).Y = 189
m_Points(1).X = 62 : m_Points(1).Y = 111
m_Points(2).X = 123 : m_Points(2).Y = 100
m_Points(3).X = 190 : m_Points(3).Y = 183
m_Points(4).X = 130 : m_Points(4).Y = 214
For i As Integer = 0 To 4
SnapToGrid(m_Points(i).X, m_Points(i).Y)
Next i
End Sub
' Draw the polygon.
Private Sub DrawPolygon(ByVal gr As Graphics)
' Draw the grid.
gr.DrawImage(m_BackgroundBitmap, 0, 0)
' Draw the polygon.
gr.DrawPolygon(Pens.Black, m_Points)
' Draw grab handles as white squares with
' black edges.
Dim rectangles() As Rectangle
ReDim rectangles(m_Points.GetUpperBound(0))
For i As Integer = 0 To m_Points.GetUpperBound(0)
With rectangles(i)
.X = m_Points(i).X - HANDLE_HALF_WIDTH
.Y = m_Points(i).Y - HANDLE_HALF_WIDTH
.Width = HANDLE_WIDTH
.Height = HANDLE_WIDTH
End With
Next i
gr.FillRectangles(Brushes.White, rectangles)
gr.DrawRectangles(Pens.Black, rectangles)
End Sub
Private Sub picCanvas_Paint(ByVal sender As Object, ByVal e _
As System.Windows.Forms.PaintEventArgs) Handles _
picCanvas.Paint
DrawPolygon(e.Graphics)
End Sub
' See if we are over a grab handle.
Private Sub picCanvas_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
picCanvas.MouseDown
Dim dx As Single
Dim dy As Single
For i As Integer = 0 To m_Points.GetUpperBound(0)
If Abs(m_Points(i).X - e.X) < HANDLE_HALF_WIDTH And _
_
Abs(m_Points(i).Y - e.Y) < HANDLE_HALF_WIDTH _
Then
' We are over this grab handle.
' Start dragging.
m_DraggingHandle = i
picCanvas.Cursor = Cursors.Cross
Exit For
End If
Next i
End Sub
' Move the drag handle.
Private Sub picCanvas_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
picCanvas.MouseMove
' Do nothing if we are not dragging.
If m_DraggingHandle = -1 Then Exit Sub
' Move the handle.
m_Points(m_DraggingHandle).X = e.X
m_Points(m_DraggingHandle).Y = e.Y
SnapToGrid( _
m_Points(m_DraggingHandle).X, _
m_Points(m_DraggingHandle).Y)
' Redraw.
DrawPolygon(picCanvas.CreateGraphics())
End Sub
' Stop dragging.
Private Sub picCanvas_MouseUp(ByVal sender As Object, ByVal _
e As System.Windows.Forms.MouseEventArgs) Handles _
picCanvas.MouseUp
picCanvas.Cursor = Cursors.Default
m_DraggingHandle = -1
End Sub
' Snap the point to the grid.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As _
Integer)
X = GRID_SPACING * CInt(X / GRID_SPACING)
Y = GRID_SPACING * CInt(Y / GRID_SPACING)
End Sub
' Draw the positioning grid.
Private Sub DrawGrid(ByVal bm As Bitmap)
For Y As Integer = 0 To picCanvas.ClientSize.Height - 1 _
Step GRID_SPACING
For X As Integer = 0 To picCanvas.ClientSize.Width _
- 1 Step GRID_SPACING
bm.SetPixel(X, Y, Color.Black)
Next X
Next Y
End Sub
' Make the background grid bitmap.
Private Sub picCanvas_Resize(ByVal sender As Object, ByVal _
e As System.EventArgs) Handles picCanvas.Resize
m_BackgroundBitmap = New _
Bitmap(picCanvas.ClientSize.Width, _
picCanvas.ClientSize.Height)
' Clear it.
Dim gr As Graphics = _
Graphics.FromImage(m_BackgroundBitmap)
gr.Clear(picCanvas.BackColor)
' Draw the grid.
For Y As Integer = 0 To m_BackgroundBitmap.Height - 1 _
Step GRID_SPACING
For X As Integer = 0 To m_BackgroundBitmap.Width - _
1 Step GRID_SPACING
m_BackgroundBitmap.SetPixel(X, Y, Color.Black)
Next X
Next Y
End Sub
|
|
For more information on graphics programming in Visual Basic 6, see my book Visual Basic Graphics Programming.
|
|
|
|
|
|