I need help
I am working my thesis on developing a drawing application used especially for engineering (Civil Engineering) purpose.
The application should draw points, lines and any other shapes. I have tried to create a drawing grid and I am ok with it.
Problems in my code
The first problem is that when I zoom the picturebox the right and bottom edge of a grid is disturbed us you may see in my code. I have tried to correct but not effective.
The second problem is when I draw and zoom it the drawn line is running out of my scroll bar and can?t see it and also the drawn shape have no scale transformation.
The third problem is I want the picture box coordinate system to be at the center of my picture box and when I start to draw on it, the mouse should snap to my grid like for example when you work in AutoCAD when you put your mouse cursor on a point the cursor change to rectangle and I want that thing to happen.
The fourth problem is I have tried to code x and y axis symbols to be displayed at the center i.e. at 0,0 this is also not possible for me.
The fifth problem is I don?t have any idea how to change my scale from pixel to SI units (mm,cm,m) and how to code and where to code.
The sixth problem is I want my picture box to be large enough to draw long lines and my coordinate system to have positive and negative values.
Dear programmers/developers I am new to graphic programing and as you can see my problems are large. I am quite sure that you have understood my interest. Generally I want a drawing application which will draw lines points using mouse down, up, move and click events and when zoom in and out should zoom to the center.
Here below is my code
Option Strict On
Option Explicit On
Option Infer Off
Public Class drawingForm
' Drawing parameters.
Private m_GridX As Integer = 10
Private m_GridY As Integer = 10
' For drawing a new line.
Private m_Drawing As Boolean = False
Private m_X1 As Single
Private m_Y1 As Single
Private m_X2 As Single
Private m_Y2 As Single
' Existing lines.
Private m_Points1() As PointF = {}
Private m_Points2() As PointF = {}
' Options.
Private m_SnapToGrid As Boolean = False
' Pens.
Private m_PenOldLine As Pen = Pens.Black
Private m_PenNewLine As Pen = Pens.Red
Private zoom As Single = 0.1 'this is for a 1:1 scaling ratio that should be the starting value
'these are values i used for my testing, i don't know how you are getting these values
Private Sub drawingPictureBox_MouseEnter(ByVal sender As Object,
ByVal e As System.EventArgs) Handles drawingPictureBox.MouseEnter
drawingPictureBox.Focus()
End Sub
Private Sub drawingForm_Load(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load
m_SnapToGrid = mnuOptionsSnapToGrid.Checked
drawingPanel.BorderStyle = BorderStyle.Fixed3D
drawingPanel.ClientSize = New Size(1258, 698)
drawingPanel.AutoScroll = True
drawingPictureBox.Parent = drawingPanel
drawingPictureBox.Size = drawingPanel.ClientSize
drawingPictureBox.BorderStyle = BorderStyle.None
End Sub
Private Sub mnuOptionsSnapToGrid_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles mnuOptionsSnapToGrid.Click
m_SnapToGrid = Not m_SnapToGrid
mnuOptionsSnapToGrid.Checked = m_SnapToGrid
End Sub
Private Sub drawingPictureBox_MouseWheel(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseWheel
If e.Delta > 0 Then 'if delta is 120 wheel is scrolled up, if it is -120 wheel is scrolled down
zoom += 0.1F
Else
zoom -= 0.1F
End If
If zoom > 10.0 Then
zoom = 10
End If
If zoom < 1 Then
zoom = 1
End If
drawingPictureBox.Width = CInt(drawingPanel.Width * zoom) - 2
drawingPictureBox.Height = CInt(drawingPanel.Height * zoom) - 2
drawingPictureBox.Location = New Point(CInt((drawingPanel.Width / 2 - drawingPictureBox.Width / 2 + zoom)),
CInt((drawingPanel.Height / 2 - drawingPictureBox.Height / 2) + zoom))
drawingPictureBox.Refresh()
End Sub
Private Sub drawingPictureBox_Paint(ByVal sender As Object,
ByVal e As System.Windows.Forms.PaintEventArgs) Handles drawingPictureBox.Paint
Dim gridWidth As Integer = 10
With e.Graphics
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For y As Single = 0 To drawingPictureBox.Height - 1 Step (gridWidth * zoom)
.DrawLine(Pens.LightGray, 0, y, drawingPictureBox.Width, y)
Next
For x As Single = 0 To drawingPictureBox.Width - 1 Step (gridWidth * zoom)
.DrawLine(Pens.LightGray, x, 0, x, drawingPictureBox.Height)
Next
.TranslateTransform(CSng((drawingPictureBox.Width - 1) / 2),
CSng((drawingPictureBox.Height - 1) / 2))
.ScaleTransform(zoom, zoom)
'Drawing x,y coordinate symbol at (0,0)
Dim origin As New Point(CInt(drawingPictureBox.Width / 2),
CInt(drawingPictureBox.Height / 2))
Dim pt1 As New Point(origin.X, origin.Y - 50)
Dim pt2 As New Point(origin.X + 50, origin.Y)
Dim pen As New Pen(Color.BlueViolet, 6)
pen.StartCap = Drawing2D.LineCap.Round
pen.EndCap = Drawing2D.LineCap.ArrowAnchor
.DrawLine(pen, origin, pt1)
.DrawLine(pen, origin, pt2)
.ResetTransform()
' Draw existing lines.
For i As Integer = 0 To m_Points1.Length - 1
e.Graphics.DrawLine(m_PenOldLine, m_Points1(i), m_Points2(i))
Next i
' Draw the new line.
If m_Drawing Then
e.Graphics.DrawLine(m_PenNewLine, m_X1, m_Y1, m_X2, m_Y2)
End If
.ResetTransform()
End With
End Sub
Private Sub drawingPictureBox_MouseDown(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles drawingPictureBox.MouseDown
' Only on left mouse down.
If e.Button <> Windows.Forms.MouseButtons.Left Then Exit Sub
m_Drawing = True
' Start drawing.
m_X1 = e.X
m_Y1 = e.Y
SnapToGrid(CInt(m_X1), CInt(m_Y1))
m_X2 = m_X1
m_Y2 = m_Y1
drawingPictureBox.Invalidate()
End Sub
Private Sub drawingPictureBox_MouseMove(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseMove
m_X2 = e.X
m_Y2 = e.Y
SnapToGrid(CInt(m_X2), CInt(m_Y2))
' Redraw.
If m_Drawing Then drawingPictureBox.Invalidate()
End Sub
Private Sub drawingPictureBox_MouseUp(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseUp
If Not m_Drawing Then Exit Sub
m_Drawing = False
'Save the new line.
Dim new_index As Integer = m_Points1.Length
ReDim Preserve m_Points1(new_index)
ReDim Preserve m_Points2(new_index)
m_Points1(new_index) = New PointF(m_X1, m_Y1)
m_Points2(new_index) = New PointF(m_X2, m_Y2)
drawingPictureBox.Invalidate()
End Sub
' Snap the point to the nearest grid location.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As Integer)
' If grid snap is off, do nothing.
If Not m_SnapToGrid Then Exit Sub
Dim ix As Integer = CInt(X / m_GridX)
Dim iy As Integer = CInt(Y / m_GridY)
X = ix * m_GridX
Y = iy * m_GridY
End Sub
End Class
I am working my thesis on developing a drawing application used especially for engineering (Civil Engineering) purpose.
The application should draw points, lines and any other shapes. I have tried to create a drawing grid and I am ok with it.
Problems in my code
The first problem is that when I zoom the picturebox the right and bottom edge of a grid is disturbed us you may see in my code. I have tried to correct but not effective.
The second problem is when I draw and zoom it the drawn line is running out of my scroll bar and can?t see it and also the drawn shape have no scale transformation.
The third problem is I want the picture box coordinate system to be at the center of my picture box and when I start to draw on it, the mouse should snap to my grid like for example when you work in AutoCAD when you put your mouse cursor on a point the cursor change to rectangle and I want that thing to happen.
The fourth problem is I have tried to code x and y axis symbols to be displayed at the center i.e. at 0,0 this is also not possible for me.
The fifth problem is I don?t have any idea how to change my scale from pixel to SI units (mm,cm,m) and how to code and where to code.
The sixth problem is I want my picture box to be large enough to draw long lines and my coordinate system to have positive and negative values.
Dear programmers/developers I am new to graphic programing and as you can see my problems are large. I am quite sure that you have understood my interest. Generally I want a drawing application which will draw lines points using mouse down, up, move and click events and when zoom in and out should zoom to the center.
Here below is my code
Option Strict On
Option Explicit On
Option Infer Off
Public Class drawingForm
' Drawing parameters.
Private m_GridX As Integer = 10
Private m_GridY As Integer = 10
' For drawing a new line.
Private m_Drawing As Boolean = False
Private m_X1 As Single
Private m_Y1 As Single
Private m_X2 As Single
Private m_Y2 As Single
' Existing lines.
Private m_Points1() As PointF = {}
Private m_Points2() As PointF = {}
' Options.
Private m_SnapToGrid As Boolean = False
' Pens.
Private m_PenOldLine As Pen = Pens.Black
Private m_PenNewLine As Pen = Pens.Red
Private zoom As Single = 0.1 'this is for a 1:1 scaling ratio that should be the starting value
'these are values i used for my testing, i don't know how you are getting these values
Private Sub drawingPictureBox_MouseEnter(ByVal sender As Object,
ByVal e As System.EventArgs) Handles drawingPictureBox.MouseEnter
drawingPictureBox.Focus()
End Sub
Private Sub drawingForm_Load(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load
m_SnapToGrid = mnuOptionsSnapToGrid.Checked
drawingPanel.BorderStyle = BorderStyle.Fixed3D
drawingPanel.ClientSize = New Size(1258, 698)
drawingPanel.AutoScroll = True
drawingPictureBox.Parent = drawingPanel
drawingPictureBox.Size = drawingPanel.ClientSize
drawingPictureBox.BorderStyle = BorderStyle.None
End Sub
Private Sub mnuOptionsSnapToGrid_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles mnuOptionsSnapToGrid.Click
m_SnapToGrid = Not m_SnapToGrid
mnuOptionsSnapToGrid.Checked = m_SnapToGrid
End Sub
Private Sub drawingPictureBox_MouseWheel(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseWheel
If e.Delta > 0 Then 'if delta is 120 wheel is scrolled up, if it is -120 wheel is scrolled down
zoom += 0.1F
Else
zoom -= 0.1F
End If
If zoom > 10.0 Then
zoom = 10
End If
If zoom < 1 Then
zoom = 1
End If
drawingPictureBox.Width = CInt(drawingPanel.Width * zoom) - 2
drawingPictureBox.Height = CInt(drawingPanel.Height * zoom) - 2
drawingPictureBox.Location = New Point(CInt((drawingPanel.Width / 2 - drawingPictureBox.Width / 2 + zoom)),
CInt((drawingPanel.Height / 2 - drawingPictureBox.Height / 2) + zoom))
drawingPictureBox.Refresh()
End Sub
Private Sub drawingPictureBox_Paint(ByVal sender As Object,
ByVal e As System.Windows.Forms.PaintEventArgs) Handles drawingPictureBox.Paint
Dim gridWidth As Integer = 10
With e.Graphics
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For y As Single = 0 To drawingPictureBox.Height - 1 Step (gridWidth * zoom)
.DrawLine(Pens.LightGray, 0, y, drawingPictureBox.Width, y)
Next
For x As Single = 0 To drawingPictureBox.Width - 1 Step (gridWidth * zoom)
.DrawLine(Pens.LightGray, x, 0, x, drawingPictureBox.Height)
Next
.TranslateTransform(CSng((drawingPictureBox.Width - 1) / 2),
CSng((drawingPictureBox.Height - 1) / 2))
.ScaleTransform(zoom, zoom)
'Drawing x,y coordinate symbol at (0,0)
Dim origin As New Point(CInt(drawingPictureBox.Width / 2),
CInt(drawingPictureBox.Height / 2))
Dim pt1 As New Point(origin.X, origin.Y - 50)
Dim pt2 As New Point(origin.X + 50, origin.Y)
Dim pen As New Pen(Color.BlueViolet, 6)
pen.StartCap = Drawing2D.LineCap.Round
pen.EndCap = Drawing2D.LineCap.ArrowAnchor
.DrawLine(pen, origin, pt1)
.DrawLine(pen, origin, pt2)
.ResetTransform()
' Draw existing lines.
For i As Integer = 0 To m_Points1.Length - 1
e.Graphics.DrawLine(m_PenOldLine, m_Points1(i), m_Points2(i))
Next i
' Draw the new line.
If m_Drawing Then
e.Graphics.DrawLine(m_PenNewLine, m_X1, m_Y1, m_X2, m_Y2)
End If
.ResetTransform()
End With
End Sub
Private Sub drawingPictureBox_MouseDown(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles drawingPictureBox.MouseDown
' Only on left mouse down.
If e.Button <> Windows.Forms.MouseButtons.Left Then Exit Sub
m_Drawing = True
' Start drawing.
m_X1 = e.X
m_Y1 = e.Y
SnapToGrid(CInt(m_X1), CInt(m_Y1))
m_X2 = m_X1
m_Y2 = m_Y1
drawingPictureBox.Invalidate()
End Sub
Private Sub drawingPictureBox_MouseMove(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseMove
m_X2 = e.X
m_Y2 = e.Y
SnapToGrid(CInt(m_X2), CInt(m_Y2))
' Redraw.
If m_Drawing Then drawingPictureBox.Invalidate()
End Sub
Private Sub drawingPictureBox_MouseUp(ByVal sender As Object,
ByVal e As System.Windows.Forms.MouseEventArgs) Handles drawingPictureBox.MouseUp
If Not m_Drawing Then Exit Sub
m_Drawing = False
'Save the new line.
Dim new_index As Integer = m_Points1.Length
ReDim Preserve m_Points1(new_index)
ReDim Preserve m_Points2(new_index)
m_Points1(new_index) = New PointF(m_X1, m_Y1)
m_Points2(new_index) = New PointF(m_X2, m_Y2)
drawingPictureBox.Invalidate()
End Sub
' Snap the point to the nearest grid location.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As Integer)
' If grid snap is off, do nothing.
If Not m_SnapToGrid Then Exit Sub
Dim ix As Integer = CInt(X / m_GridX)
Dim iy As Integer = CInt(Y / m_GridY)
X = ix * m_GridX
Y = iy * m_GridY
End Sub
End Class