none
How to draw by mouse a Polygon of any shape (snap to grid or not snap to grid) (the snap maybe off and the snap maybe on) and the distance between snaps are input data as well as the distance between grids are input data. RRS feed

  • Question

  • Hello Dear,

    How to draw by mouse a Polygon of any shape (snap to grid or not snap to grid) (the snap maybe off and the snap maybe on) and the distance between snaps are input data as well as the distance between grids are input data.

    Also the maximum value of X axis is input, the maximum value of Y axis is input, the minimum value of X axis is input and the minimum value of Y axis is input (drawing area are input).

    In addition to the above the Form shall be full screen size (form.windowstate = formwindowstate.Maximize).

    The pen mouse shall attach to last point drawn until closed the Polygon.

    Closing the Polygon shall be by press enter by the key borad.

    The grids maybe off and maybe on.

    I back to previous thread  https://social.msdn.microsoft.com/Forums/en-US/0e94d3d1-1de0-4e1d-a6f2-84cb51df7316/how-i-can-draw-grid-lines-on-picture-box-and-then-draw-by-mouse-lines-between-grids-snap-at?forum=vbgeneral

    but I find difficulties to solve the difference between previous thread and this thread.

    Kind Regards,


    Hany Metry


    • Edited by Hany Metry Wednesday, October 2, 2019 2:50 PM The pen mouse shall attach to last point drawn until closed the Polygon. Closing the Polygon shall be by press enter by the key borad.
    Wednesday, October 2, 2019 2:39 PM

Answers

  • Hany,

    This is the last one of these. You need to learn it and debug it and modify it for your desires.

    Sometimes I am interested or have an example. However, most of the time you will have to make the questions a simple one question thing or you wont get many responses from me unless I already have an example made.

    It took me over 40 years to get here. I dont give that away.

    :)

    PS in the example click the right mouse button to reset the tool.

    The example makes the controls just cut and paste the code into an empty form. Change the form name as required.

    'version 3 example with multitools 'positive y axis

    Imports System.Drawing.Imaging Public Class Form3 Private WithEvents Picturebox1 As New PictureBox With {.Parent = Me, .BackColor = Color.White} Private WithEvents LineCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(20, 10), .Size = New Size(60, 32), .Text = "Line", .Appearance = Appearance.Button, .BackColor = Color.AntiqueWhite, .TextAlign = ContentAlignment.MiddleCenter, .Name = "Line"} Private WithEvents LineMultiCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(90, 10), .Size = New Size(60, 32), .Text = "MultiLine", .Appearance = Appearance.Button, .BackColor = Color.AntiqueWhite, .TextAlign = ContentAlignment.MiddleCenter, .Name = "LineMulti"} Private WithEvents SnapCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(200, 10), .Text = "Snap"} Private SelectedTool As String Public Class Shape Public pt1 As PointF Public pt2 As PointF Public color As Color = Color.Red Public Sub Draw(g As Graphics, yOffset1 As Single) Using p As New Pen(color, g.VisibleClipBounds.Width / 100) g.DrawLine(p, pt1.X, yOffset1 - pt1.Y, pt2.X, yOffset1 - pt2.Y) 'g.DrawLine(p, pt1, pt2) End Using End Sub End Class Private Shapes As New List(Of Shape) Private ScaleWidth As Single = 100 Private Yoffset As Single 'Private Corner As New Point(-ScaleWidth / 2, -ScaleWidth / 2) Private Corner As New Point(0, 0) Private GridStep As Single = 20 Private SnapStep As Single = 10 Private MouseDownPt, MouseMovePt As PointF Private MouseStatus As Integer = 0 Private ToolCbCancel As Boolean = False Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load ClientSize = New Size(400, 300) DoubleBuffered = True Text = "Line drawing Example" BackColor = Color.BurlyWood LineCb.FlatAppearance.CheckedBackColor = Color.White LineMultiCb.FlatAppearance.CheckedBackColor = Color.White LineCb.Checked = True 'draw initial view Form2_Resize(0, Nothing) End Sub Private Sub Form2_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim border As Integer = 20 Picturebox1.Location = New Point(border, 50) Picturebox1.Size = New Size(ClientSize.Width - (2 * border), ClientSize.Height - (50 + border)) Yoffset = ScaleWidth * (Picturebox1.ClientSize.Height / Picturebox1.ClientSize.Width) Picturebox1.Invalidate() End Sub Private Sub Picturebox1_MouseDown(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseDown Dim pt As PointF = GetScalePtFromClientPt(e.Location) Select Case SelectedTool Case "LineMulti" 'for multiline dont need to set mouse down If MouseStatus = 0 Then MouseDownPt = pt Case Else MouseDownPt = pt End Select MouseMovePt = MouseDownPt MouseStatus = 1 If e.Button = MouseButtons.Right Then MouseStatus = 0 Picturebox1.Invalidate() End Sub Private Sub Picturebox1_MouseMove(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseMove Select Case MouseStatus Case 1 Dim pt As PointF = GetScalePtFromClientPt(e.Location) MouseMovePt = SnapToGrid(pt) Picturebox1.Invalidate() End Select End Sub Private Sub Picturebox1_MouseUp(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseUp If e.Button = MouseButtons.Right Then MouseStatus = 0 Else Select Case MouseStatus Case 1 Dim pt As PointF = GetScalePtFromClientPt(e.Location) MouseMovePt = SnapToGrid(pt) Dim shp As New Shape shp.pt1 = MouseDownPt shp.pt2 = MouseMovePt shp.color = Color.Red Shapes.Add(shp) MouseStatus = 0 Select Case SelectedTool Case "LineMulti" 'for multiline repeat last point as new second point MouseStatus = 1 MouseDownPt = shp.pt2 End Select End Select End If Picturebox1.Invalidate() End Sub Private Sub Picturebox1_Paint(sender As Object, e As PaintEventArgs) Handles Picturebox1.Paint With e.Graphics .ResetTransform() .Clear(Color.White) .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias Dim sf As Single = CSng(Picturebox1.ClientSize.Width / ScaleWidth) .ScaleTransform(sf, sf) .TranslateTransform(-Corner.X, Corner.Y) 'draw origin .DrawLine(Pens.Green, -5, Yoffset - 0, 5, Yoffset - 0) .DrawLine(Pens.Green, 0, Yoffset - (-5), 0, Yoffset - 5) DrawGrid(e.Graphics) For Each shp As Shape In Shapes shp.Draw(e.Graphics, Yoffset) Next Select Case MouseStatus Case 1 'draw line tracer .DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt.X, Yoffset - MouseDownPt.Y, MouseMovePt.X, Yoffset - MouseMovePt.Y) '.DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt, MouseMovePt) End Select End With End Sub Private Sub DrawGrid(g As Graphics) 'setup drawing corners etc Dim x1 As Single = RoundToIncrement(Corner.X - GridStep, CInt(GridStep)) Dim y1 As Single = RoundToIncrement(Corner.Y - GridStep, CInt(GridStep)) Dim sw As Single = CSng(ScaleWidth + (2 * GridStep)) Dim pxlSize As Double = ScaleWidth / Picturebox1.ClientSize.Width With g Using pg As New Pen(Color.DarkGray, CSng(pxlSize / 6)), f As New Font("arial", CSng(11 * pxlSize)), br As New SolidBrush(Color.DimGray) For x As Single = x1 To CSng(x1 + sw) Step GridStep .DrawLine(pg, x, Yoffset - y1, x, Yoffset - CSng(y1 + sw)) .DrawString(x.ToString, f, br, x, Yoffset - (-Corner.Y)) Next For y As Single = y1 To CSng(y1 + sw) Step GridStep .DrawLine(pg, x1, Yoffset - y, CSng(x1 + sw), Yoffset - y) .DrawString(y.ToString, f, br, Corner.X, Yoffset - y) Next End Using End With End Sub Private Function SnapToGrid(thispt As PointF) As PointF Dim x, y As Single If SnapCb.Checked Then x = CInt(thispt.X / SnapStep) * SnapStep y = CInt(thispt.Y / SnapStep) * SnapStep Else x = thispt.X y = thispt.Y End If Return New PointF(x, y) End Function Private Function RoundToIncrement(theValue As Double, roundIncrement As Integer) As Integer 'ie value = 1433 roundinc = 100 returns 1400 Return CInt((CDbl(theValue) + (0.5 * roundIncrement)) / roundIncrement) * roundIncrement End Function Private Function GetScalePtFromClientPt(pt As PointF) As PointF 'convert screen pixels to scale drawing coords Dim sf As Double = Picturebox1.ClientSize.Width / ScaleWidth Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (Yoffset - pt.Y / sf))) End Function Private Sub Tools_CheckedChanged(sender As Object, e As EventArgs) Handles _ LineCb.CheckedChanged, LineMultiCb.CheckedChanged If ToolCbCancel = False Then ToolCbCancel = True Select Case DirectCast(sender, CheckBox).Name Case "Line" If LineCb.Checked = True Then SelectedTool = "Line" LineMultiCb.Checked = False End If Case "LineMulti" SelectedTool = "LineMulti" If LineMultiCb.Checked = True Then LineCb.Checked = False End Select End If ToolCbCancel = False MouseStatus = 0 End Sub End Class




    Wednesday, October 2, 2019 5:16 PM

All replies

  • Hi

    As you are well aware, you get a lot of good help in this forum. However, it would seem that you want everyone here to create all your code for you. You say you are having difficulty in solving the differences between the previous thread and this one - but you show NO CODE.

    Tommy put a lot of time and effort into providing you with the latge part of your question. You should show here what attempts you have made to adjust it to your needs. I would say that the changes you would need to make to Tommy's code are very small - just a flag to indicate snap on/off, key handler for close path.


    Regards Les, Livingston, Scotland

    Wednesday, October 2, 2019 3:11 PM
  • Hi

    As you are well aware, you get a lot of good help in this forum. However, it would seem that you want everyone here to create all your code for you. You say you are having difficulty in solving the differences between the previous thread and this one - but you show NO CODE.

    Tommy put a lot of time and effort into providing you with the latge part of your question. You should show here what attempts you have made to adjust it to your needs. I would say that the changes you would need to make to Tommy's code are very small - just a flag to indicate snap on/off, key handler for close path.


    Regards Les, Livingston, Scotland

    Thank you for trying to help me but I am still very very beginner with respect to Microsoft staff but lets try to solve for me window state is maximized and draw a Polygon (instead of line) with the mouse line attach to last point draw until closed the polygon by pressing enter by key board.

    Kind Regards,


    Hany Metry

    Wednesday, October 2, 2019 3:18 PM
  • Hi

    As you are well aware, you get a lot of good help in this forum. However, it would seem that you want everyone here to create all your code for you. You say you are having difficulty in solving the differences between the previous thread and this one - but you show NO CODE.

    Tommy put a lot of time and effort into providing you with the latge part of your question. You should show here what attempts you have made to adjust it to your needs. I would say that the changes you would need to make to Tommy's code are very small - just a flag to indicate snap on/off, key handler for close path.


    Regards Les, Livingston, Scotland

    Imports System.Drawing.Imaging
    Public Class Form1
        Public Class Shape
            Public pt1 As PointF
            Public pt2 As PointF
            Public color As Color = color.Red
    
            Public Sub Draw(g As Graphics, yOffset1 As Single)
    
                Using p As New Pen(color, g.VisibleClipBounds.Width / 100)
                    g.DrawLine(p, pt1.X, yOffset1 - pt1.Y, pt2.X, yOffset1 - pt2.Y)
                    'g.DrawLine(p, pt1, pt2)
                End Using
            End Sub
        End Class
    
        Private Shapes As New List(Of Shape)
        Private ScaleWidth As Single = 100
        Private Yoffset As Single
        'center (0,0) in window
        Private Corner As New Point(-ScaleWidth / 2, -ScaleWidth / 2)
        Private GridStep As Single = 20
        Private SnapStep As Single = 10
        Private MouseDownPt, MouseMovePt As PointF
        Private MouseStaus As Integer = 0
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ClientSize = New Size(300, 300)
            DoubleBuffered = True
            Text = "Snap to Grid Example"
            'draw initial view
            Form2_Resize(0, Nothing)
        End Sub
    
        Private Sub Form2_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            If e.Button = MouseButtons.Left Then
                Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                If SnapToolStripMenuItem.Checked = True Then
                    MouseDownPt = SnapToGrid(pt)
                Else
                    MouseDownPt = pt
                End If
                MouseMovePt = MouseDownPt
                MouseStaus = 1
            End If
        End Sub
    
        Private Sub Form2_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
            If e.Button = MouseButtons.Left Then
                Select Case MouseStaus
                    Case 1
                        Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                        If SnapToolStripMenuItem.Checked = True Then
                            MouseMovePt = SnapToGrid(pt)
                        Else
                            MouseMovePt = pt
                        End If
                        Invalidate()
                End Select
            End If
        End Sub
    
        Private Sub Form2_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
            Select Case MouseStaus
                Case 1
                    Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                    If SnapToolStripMenuItem.Checked = True Then
                        MouseMovePt = SnapToGrid(pt)
                    Else
                        MouseMovePt = pt
                    End If
                    Dim shp As New Shape
                    shp.pt1 = MouseDownPt
                    shp.pt2 = MouseMovePt
                    shp.color = Color.Red
                    Shapes.Add(shp)
            End Select
            MouseStaus = 0
            Invalidate()
        End Sub
    
        Private Sub Form2_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Yoffset = ScaleWidth * (ClientSize.Height / ClientSize.Width)
            Invalidate()
        End Sub
    
        Private Sub Form2_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    
            With e.Graphics
                .ResetTransform()
                .Clear(Color.White)
                .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    
                Dim sf As Single = CSng(ClientSize.Width / ScaleWidth)
                .ScaleTransform(sf, sf)
                .TranslateTransform(-Corner.X, Corner.Y)
    
                'draw origin
                .DrawLine(Pens.Green, -5, Yoffset - 0, 5, Yoffset - 0)
                .DrawLine(Pens.Green, 0, Yoffset - (-5), 0, Yoffset - 5)
    
                DrawGrid(e.Graphics)
    
                For Each shp As Shape In Shapes
                    shp.Draw(e.Graphics, Yoffset)
                Next
    
                Select Case MouseStaus
                    Case 1  'draw line tracer
                        .DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt.X, Yoffset - MouseDownPt.Y, MouseMovePt.X, Yoffset - MouseMovePt.Y)
                        '.DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt, MouseMovePt)
                End Select
            End With
        End Sub
        Private Sub DrawGrid(g As Graphics)
            'setup drawing corners etc
            Dim x1 As Single = RoundToIncrement(Corner.X - GridStep, CInt(GridStep))
            Dim y1 As Single = RoundToIncrement(Corner.Y - GridStep, CInt(GridStep))
            Dim sw As Single = CSng(ScaleWidth + (2 * GridStep))
            Dim pxlSize As Double = ScaleWidth / ClientSize.Width
            With g
                Using pg As New Pen(Color.DarkGray, CSng(pxlSize / 6)),
                        f As New Font("arial", CSng(11 * pxlSize)),
                        br As New SolidBrush(Color.DimGray)
                    For x As Single = x1 To CSng(x1 + sw) Step GridStep
                        .DrawLine(pg, x, Yoffset - y1, x, Yoffset - CSng(y1 + sw))
                        .DrawString(x.ToString, f, br, x, Yoffset - (-Corner.Y))
                    Next
                    For y As Single = y1 To CSng(y1 + sw) Step GridStep
                        .DrawLine(pg, x1, Yoffset - y, CSng(x1 + sw), Yoffset - y)
                        .DrawString(y.ToString, f, br, Corner.X, Yoffset - y)
                    Next
                End Using
            End With
        End Sub
    
        Private Function SnapToGrid(thispt As PointF) As PointF
            If SnapToolStripMenuItem.Checked = True Then
                Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
                Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
                Return New PointF(x, y)
            End If
        End Function
        Private Function RoundToIncrement(theValue As Double, roundIncrement As Integer) As Integer
            'ie value = 1433 roundinc = 100 returns 1400
            If SnapToolStripMenuItem.Checked = True Then
                Return CInt((CDbl(theValue) + (0.5 * roundIncrement)) / roundIncrement) * roundIncrement
            Else
                Return CInt(CDbl(theValue))
            End If
        End Function
        Private Function GetScalePtFromClientPt(pt As PointF) As PointF
            'convert screen pixels to scale drawing coords
            Dim sf As Double = ClientSize.Width / ScaleWidth
            Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (Yoffset - pt.Y / sf)))
            'Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (pt.Y / sf)))
        End Function
        Private Sub SnapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SnapToolStripMenuItem.Click
            If SnapToolStripMenuItem.Checked = True Then
                SnapToolStripMenuItem.Checked = False
            Else
                SnapToolStripMenuItem.Checked = True
            End If
        End Sub
    End Class

    Hi Mr. Les, Livingston,

    The above is Mr Tommy Code adjusted to make Snap On and off

    Attached the photo of Form1.

    Kind Regards,

    Hany Sabry


    Hany Metry


    • Edited by Hany Metry Wednesday, October 2, 2019 4:05 PM
    Wednesday, October 2, 2019 4:01 PM
  • Dear Mr Livingston,

    Private Sub DrawGrid(g As Graphics)
            'setup drawing corners etc
            If GridToolStripMenuItem.Checked = True Then
                Dim x1 As Single = RoundToIncrement(Corner.X - GridStep, CInt(GridStep))
                Dim y1 As Single = RoundToIncrement(Corner.Y - GridStep, CInt(GridStep))
                Dim sw As Single = CSng(ScaleWidth + (2 * GridStep))
                Dim pxlSize As Double = ScaleWidth / ClientSize.Width
                With g
                    Using pg As New Pen(Color.DarkGray, CSng(pxlSize / 6)),
                            f As New Font("arial", CSng(11 * pxlSize)),
                            br As New SolidBrush(Color.DimGray)
                        For x As Single = x1 To CSng(x1 + sw) Step GridStep
                            .DrawLine(pg, x, Yoffset - y1, x, Yoffset - CSng(y1 + sw))
                            .DrawString(x.ToString, f, br, x, Yoffset - (-Corner.Y))
                        Next
                        For y As Single = y1 To CSng(y1 + sw) Step GridStep
                            .DrawLine(pg, x1, Yoffset - y, CSng(x1 + sw), Yoffset - y)
                            .DrawString(y.ToString, f, br, Corner.X, Yoffset - y)
                        Next
                    End Using
                End With
            End If
        End Sub
    
    Private Sub GridToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GridToolStripMenuItem.Click
            If GridToolStripMenuItem.Checked = True Then
                GridToolStripMenuItem.Checked = False
            Else
                GridToolStripMenuItem.Checked = True
            End If
        End Sub
    
    

    The above is the code for Grid on and off.

    Kind Regards,


    Hany Metry

    Wednesday, October 2, 2019 4:24 PM
  • Hi

    As you are well aware, you get a lot of good help in this forum. However, it would seem that you want everyone here to create all your code for you. You say you are having difficulty in solving the differences between the previous thread and this one - but you show NO CODE.

    Tommy put a lot of time and effort into providing you with the latge part of your question. You should show here what attempts you have made to adjust it to your needs. I would say that the changes you would need to make to Tommy's code are very small - just a flag to indicate snap on/off, key handler for close path.


    Regards Les, Livingston, Scotland

    Thank you for trying to help me but I am still very very beginner with respect to Microsoft staff but lets try to solve for me window state is maximized and draw a Polygon (instead of line) with the mouse line attach to last point draw until closed the polygon by pressing enter by key board.

    Kind Regards,


    Hany Metry

    Hello,

    Those who have been assisting you are not Microsoft staff, I'm not either. 


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, October 2, 2019 4:31 PM
    Moderator
  • Hi

    As you are well aware, you get a lot of good help in this forum. However, it would seem that you want everyone here to create all your code for you. You say you are having difficulty in solving the differences between the previous thread and this one - but you show NO CODE.

    Tommy put a lot of time and effort into providing you with the latge part of your question. You should show here what attempts you have made to adjust it to your needs. I would say that the changes you would need to make to Tommy's code are very small - just a flag to indicate snap on/off, key handler for close path.


    Regards Les, Livingston, Scotland

    Thank you for trying to help me but I am still very very beginner with respect to Microsoft staff but lets try to solve for me window state is maximized and draw a Polygon (instead of line) with the mouse line attach to last point draw until closed the polygon by pressing enter by key board.

    Kind Regards,


    Hany Metry

    Hello,

    Those who have been assisting you are not Microsoft staff, I'm not either. 


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Hello Karen,

    All of what trying to assist me or helping me, are worry to provide answer to assist others to find answers of their questions and what are the benefit of them? What Microsoft give to them? and who are give the points to what give the answers? and how they find the questions of others to answer it? ????

    Kind Regards,  


    Hany Metry


    • Edited by Hany Metry Wednesday, October 2, 2019 4:55 PM adjust
    Wednesday, October 2, 2019 4:52 PM
  • Hany,

    This is the last one of these. You need to learn it and debug it and modify it for your desires.

    Sometimes I am interested or have an example. However, most of the time you will have to make the questions a simple one question thing or you wont get many responses from me unless I already have an example made.

    It took me over 40 years to get here. I dont give that away.

    :)

    PS in the example click the right mouse button to reset the tool.

    The example makes the controls just cut and paste the code into an empty form. Change the form name as required.

    'version 3 example with multitools 'positive y axis

    Imports System.Drawing.Imaging Public Class Form3 Private WithEvents Picturebox1 As New PictureBox With {.Parent = Me, .BackColor = Color.White} Private WithEvents LineCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(20, 10), .Size = New Size(60, 32), .Text = "Line", .Appearance = Appearance.Button, .BackColor = Color.AntiqueWhite, .TextAlign = ContentAlignment.MiddleCenter, .Name = "Line"} Private WithEvents LineMultiCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(90, 10), .Size = New Size(60, 32), .Text = "MultiLine", .Appearance = Appearance.Button, .BackColor = Color.AntiqueWhite, .TextAlign = ContentAlignment.MiddleCenter, .Name = "LineMulti"} Private WithEvents SnapCb As New CheckBox With {.Parent = Me, .FlatStyle = FlatStyle.Flat, .Location = New Point(200, 10), .Text = "Snap"} Private SelectedTool As String Public Class Shape Public pt1 As PointF Public pt2 As PointF Public color As Color = Color.Red Public Sub Draw(g As Graphics, yOffset1 As Single) Using p As New Pen(color, g.VisibleClipBounds.Width / 100) g.DrawLine(p, pt1.X, yOffset1 - pt1.Y, pt2.X, yOffset1 - pt2.Y) 'g.DrawLine(p, pt1, pt2) End Using End Sub End Class Private Shapes As New List(Of Shape) Private ScaleWidth As Single = 100 Private Yoffset As Single 'Private Corner As New Point(-ScaleWidth / 2, -ScaleWidth / 2) Private Corner As New Point(0, 0) Private GridStep As Single = 20 Private SnapStep As Single = 10 Private MouseDownPt, MouseMovePt As PointF Private MouseStatus As Integer = 0 Private ToolCbCancel As Boolean = False Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load ClientSize = New Size(400, 300) DoubleBuffered = True Text = "Line drawing Example" BackColor = Color.BurlyWood LineCb.FlatAppearance.CheckedBackColor = Color.White LineMultiCb.FlatAppearance.CheckedBackColor = Color.White LineCb.Checked = True 'draw initial view Form2_Resize(0, Nothing) End Sub Private Sub Form2_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim border As Integer = 20 Picturebox1.Location = New Point(border, 50) Picturebox1.Size = New Size(ClientSize.Width - (2 * border), ClientSize.Height - (50 + border)) Yoffset = ScaleWidth * (Picturebox1.ClientSize.Height / Picturebox1.ClientSize.Width) Picturebox1.Invalidate() End Sub Private Sub Picturebox1_MouseDown(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseDown Dim pt As PointF = GetScalePtFromClientPt(e.Location) Select Case SelectedTool Case "LineMulti" 'for multiline dont need to set mouse down If MouseStatus = 0 Then MouseDownPt = pt Case Else MouseDownPt = pt End Select MouseMovePt = MouseDownPt MouseStatus = 1 If e.Button = MouseButtons.Right Then MouseStatus = 0 Picturebox1.Invalidate() End Sub Private Sub Picturebox1_MouseMove(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseMove Select Case MouseStatus Case 1 Dim pt As PointF = GetScalePtFromClientPt(e.Location) MouseMovePt = SnapToGrid(pt) Picturebox1.Invalidate() End Select End Sub Private Sub Picturebox1_MouseUp(sender As Object, e As MouseEventArgs) Handles Picturebox1.MouseUp If e.Button = MouseButtons.Right Then MouseStatus = 0 Else Select Case MouseStatus Case 1 Dim pt As PointF = GetScalePtFromClientPt(e.Location) MouseMovePt = SnapToGrid(pt) Dim shp As New Shape shp.pt1 = MouseDownPt shp.pt2 = MouseMovePt shp.color = Color.Red Shapes.Add(shp) MouseStatus = 0 Select Case SelectedTool Case "LineMulti" 'for multiline repeat last point as new second point MouseStatus = 1 MouseDownPt = shp.pt2 End Select End Select End If Picturebox1.Invalidate() End Sub Private Sub Picturebox1_Paint(sender As Object, e As PaintEventArgs) Handles Picturebox1.Paint With e.Graphics .ResetTransform() .Clear(Color.White) .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias Dim sf As Single = CSng(Picturebox1.ClientSize.Width / ScaleWidth) .ScaleTransform(sf, sf) .TranslateTransform(-Corner.X, Corner.Y) 'draw origin .DrawLine(Pens.Green, -5, Yoffset - 0, 5, Yoffset - 0) .DrawLine(Pens.Green, 0, Yoffset - (-5), 0, Yoffset - 5) DrawGrid(e.Graphics) For Each shp As Shape In Shapes shp.Draw(e.Graphics, Yoffset) Next Select Case MouseStatus Case 1 'draw line tracer .DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt.X, Yoffset - MouseDownPt.Y, MouseMovePt.X, Yoffset - MouseMovePt.Y) '.DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt, MouseMovePt) End Select End With End Sub Private Sub DrawGrid(g As Graphics) 'setup drawing corners etc Dim x1 As Single = RoundToIncrement(Corner.X - GridStep, CInt(GridStep)) Dim y1 As Single = RoundToIncrement(Corner.Y - GridStep, CInt(GridStep)) Dim sw As Single = CSng(ScaleWidth + (2 * GridStep)) Dim pxlSize As Double = ScaleWidth / Picturebox1.ClientSize.Width With g Using pg As New Pen(Color.DarkGray, CSng(pxlSize / 6)), f As New Font("arial", CSng(11 * pxlSize)), br As New SolidBrush(Color.DimGray) For x As Single = x1 To CSng(x1 + sw) Step GridStep .DrawLine(pg, x, Yoffset - y1, x, Yoffset - CSng(y1 + sw)) .DrawString(x.ToString, f, br, x, Yoffset - (-Corner.Y)) Next For y As Single = y1 To CSng(y1 + sw) Step GridStep .DrawLine(pg, x1, Yoffset - y, CSng(x1 + sw), Yoffset - y) .DrawString(y.ToString, f, br, Corner.X, Yoffset - y) Next End Using End With End Sub Private Function SnapToGrid(thispt As PointF) As PointF Dim x, y As Single If SnapCb.Checked Then x = CInt(thispt.X / SnapStep) * SnapStep y = CInt(thispt.Y / SnapStep) * SnapStep Else x = thispt.X y = thispt.Y End If Return New PointF(x, y) End Function Private Function RoundToIncrement(theValue As Double, roundIncrement As Integer) As Integer 'ie value = 1433 roundinc = 100 returns 1400 Return CInt((CDbl(theValue) + (0.5 * roundIncrement)) / roundIncrement) * roundIncrement End Function Private Function GetScalePtFromClientPt(pt As PointF) As PointF 'convert screen pixels to scale drawing coords Dim sf As Double = Picturebox1.ClientSize.Width / ScaleWidth Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (Yoffset - pt.Y / sf))) End Function Private Sub Tools_CheckedChanged(sender As Object, e As EventArgs) Handles _ LineCb.CheckedChanged, LineMultiCb.CheckedChanged If ToolCbCancel = False Then ToolCbCancel = True Select Case DirectCast(sender, CheckBox).Name Case "Line" If LineCb.Checked = True Then SelectedTool = "Line" LineMultiCb.Checked = False End If Case "LineMulti" SelectedTool = "LineMulti" If LineMultiCb.Checked = True Then LineCb.Checked = False End Select End If ToolCbCancel = False MouseStatus = 0 End Sub End Class




    Wednesday, October 2, 2019 5:16 PM
  • Dear Mr. Tommy,

    Thank you very much.

    Kind Regards,


    Hany Metry

    Wednesday, October 2, 2019 5:50 PM
  • Dear Mr. Tommy,

    Thank you very much.

    Kind Regards,


    Hany Metry

    You are welcome.

    :)

    Wednesday, October 2, 2019 6:14 PM
  • Dear Mr. Tommy,

    I get the following error while change the code as below.

    Knowing that form1 is of window state maximized and the pictureBox1 is anchored from four sides.

    And the reason of maximize the form because I want the drawing of maximum scale because reinforcement shall be drawn the drawing which require large scale.

    And for me that is not the program while the program starts after input the data by drawings (image) that the remaining more than that by trillions times.


    Imports System.Drawing.Imaging
    Public Class Form1
        Public Class Shape
            Public pt1 As PointF
            Public pt2 As PointF
            Public color As Color = color.Black
            Public Sub Draw(g As Graphics, yOffset1 As Single)
                Using p As New Pen(color, g.VisibleClipBounds.Width / 300)
                    g.DrawLine(p, pt1.X, yOffset1 - pt1.Y, pt2.X, yOffset1 - pt2.Y)
                    'g.DrawLine(p, pt1, pt2)
                End Using
            End Sub
        End Class
        Private Shapes As New List(Of Shape)
        Dim factorx As Single = 1.0
        Dim factory As Single = 1.0
        Private ScaleWidthy As Single = factory * PictureBox1.Height
        Private ScaleWidthx As Single = factorx * PictureBox1.Width
        Private Yoffset As Single
        'center (0,0) in window
        Private Corner As New Point(-PictureBox1.width / 2, -PictureBox1.height / 2)
        Private GridStepx As Single = 20
        Private GridStepy As Single = 20
        Private SnapStepx As Single = 10
        Private SnapStepy As Single = 10
        Private MouseDownPt, MouseMovePt As PointF
        Private MouseStatus As Integer = 0
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ClientSize = New Size((PictureBox1.Width), (PictureBox1.Height))
            DoubleBuffered = True
            Text = "Snap to Grid Example"
            'draw initial view
            Form1_Resize(0, Nothing)
        End Sub
        Private Sub Picturebox1_MouseDown(sender As Object, e As MouseEventArgs)
            If e.Button = MouseButtons.Left Then
                Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                If SnapToolStripMenuItem.Checked = True Then
                    If MouseStatus = 0 Then MouseDownPt = pt
                    'MouseDownPt = SnapToGrid(pt)
                Else
                    If MouseStatus = 0 Then MouseDownPt = pt
                    'MouseDownPt = pt
                End If
                MouseMovePt = MouseDownPt
                MouseStatus = 1
                PictureBox1.Invalidate()
            End If
        End Sub
        Private Sub Picturebox1_MouseMove(sender As Object, e As MouseEventArgs)
            If e.Button = MouseButtons.Left Then
                Select Case MouseStatus
                    Case 1
                        Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                        'If SnapToolStripMenuItem.Checked = True Then
                        MouseMovePt = SnapToGrid(pt)
                        'Else
                        'MouseMovePt = pt
                        'End If
                        PictureBox1.Invalidate()
                End Select
            End If
        End Sub
        Private Sub Picturebox1_MouseUp(sender As Object, e As MouseEventArgs)
            Select Case MouseStatus
                Case 1
                    Dim pt As PointF = GetScalePtFromClientPt(e.Location)
                    If SnapToolStripMenuItem.Checked = True Then
                        MouseMovePt = SnapToGrid(pt)
                    Else
                        MouseMovePt = pt
                    End If
                    Dim shp As New Shape
                    shp.pt1 = MouseDownPt
                    shp.pt2 = MouseMovePt
                    shp.color = Color.Black
                    Shapes.Add(shp)
                    MouseStatus = 1
                    MouseDownPt = shp.pt2
            End Select
            PictureBox1.Invalidate()
        End Sub
        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            Yoffset = PictureBox1.Height / 2
            PictureBox1.Invalidate()
        End Sub
        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            With e.Graphics
                .ResetTransform()
                .Clear(Color.White)
                .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                Dim sfx As Single = CSng(PictureBox1.Width / ScaleWidthx)
                Dim sfy As Single = CSng(PictureBox1.Height / ScaleWidthy)
                .ScaleTransform(sfx, sfy)
                .TranslateTransform(-Corner.X, Corner.Y)
                'draw origin
                .DrawLine(Pens.Black, -5, Yoffset - 0, 5, Yoffset - 0)
                .DrawLine(Pens.Black, 0, Yoffset - (-5), 0, Yoffset - 5)
                DrawGrid(e.Graphics)
                For Each shp As Shape In Shapes
                    shp.Draw(e.Graphics, Yoffset)
                Next
                Select Case MouseStatus
                    Case 1  'draw line tracer
                        .DrawLine(New Pen(Color.Black, .VisibleClipBounds.Width / 300), MouseDownPt.X, Yoffset - MouseDownPt.Y, MouseMovePt.X, Yoffset - MouseMovePt.Y)
                        '.DrawLine(New Pen(Color.Red, .VisibleClipBounds.Width / 100), MouseDownPt, MouseMovePt)
                End Select
            End With
        End Sub
        Private Sub DrawGrid(g As Graphics)
            'setup drawing corners etc
            If GridToolStripMenuItem.Checked = True Then
                Dim x1 As Single = RoundToIncrement(Corner.X - GridStepx, CInt(GridStepx))
                Dim y1 As Single = RoundToIncrement(Corner.Y - GridStepy, CInt(GridStepy))
                Dim swx As Single = CSng(ScaleWidthx + (2 * GridStepx))
                Dim swy As Single = CSng(ScaleWidthy + (2 * GridStepy))
                Dim pxlSize As Double = ScaleWidthx / PictureBox1.Width
                With g
                    Using pg As New Pen(Color.DarkGray, CSng(pxlSize / 10)),
                            f As New Font("arial", CSng(11 * pxlSize)),
                            br As New SolidBrush(Color.DimGray)
                        For x As Single = x1 To CSng(x1 + swx) Step GridStepx
                            .DrawLine(pg, x, Yoffset - y1, x, Yoffset - CSng(y1 + swy))
                            .DrawString(x.ToString, f, br, x, Yoffset - (-Corner.Y))
                        Next
                        For y As Single = y1 To CSng(y1 + swy) Step GridStepy
                            .DrawLine(pg, x1, Yoffset - y, CSng(x1 + swy), Yoffset - y)
                            .DrawString(y.ToString, f, br, Corner.X, Yoffset - y)
                        Next
                    End Using
                End With
            End If
        End Sub
        Private Function SnapToGrid(thispt As PointF) As PointF
            Dim x As Single
            Dim y As Single
            If SnapToolStripMenuItem.Checked = True Then
                x = CInt(thispt.X / SnapStepx) * SnapStepx
                y = CInt(thispt.Y / SnapStepy) * SnapStepy
            Else
                x = thispt.X
                y = thispt.Y
            End If
            Return New PointF(x, y)
        End Function
        Private Function RoundToIncrement(theValue As Double, roundIncrement As Integer) As Integer
            'ie value = 1433 roundinc = 100 returns 1400
            If SnapToolStripMenuItem.Checked = True Then
                Return CInt((CDbl(theValue) + (0.5 * roundIncrement)) / roundIncrement) * roundIncrement
            Else
                Return CInt(CDbl(theValue))
            End If
        End Function
        Private Function GetScalePtFromClientPt(pt As PointF) As PointF
            'convert screen pixels to scale drawing coords
            Dim sfx As Single = CSng(PictureBox1.Width / ScaleWidthx)
            Dim sfy As Single = CSng(PictureBox1.Height / ScaleWidthy)
            Return New PointF(CSng(Corner.X + (pt.X / sfx)), CSng(Corner.Y + (Yoffset - pt.Y / sfy)))
            'Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (pt.Y / sf)))
        End Function
        Private Sub SnapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SnapToolStripMenuItem.Click
            If SnapToolStripMenuItem.Checked = True Then
                SnapToolStripMenuItem.Checked = False
            Else
                SnapToolStripMenuItem.Checked = True
            End If
        End Sub
        Private Sub GridToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GridToolStripMenuItem.Click
            If GridToolStripMenuItem.Checked = True Then
                GridToolStripMenuItem.Checked = False
            Else
                GridToolStripMenuItem.Checked = True
            End If
        End Sub
    End Class

    Can you help me to find the mistake.?

    Also why there is Yoffest and there is no Xoffest.

    Kind Regards,


    Hany Metry






    Thursday, October 3, 2019 10:04 AM
  • Hany,

    Dont mark question as answered and come back the next day and unmark it because you added something that does not work. Start a new quesiton.

    "Can you help me to find the mistake"

    What is drawsnapbymouse?

    When it says object not set to instance means you made an object without the new word

       ie Dim DrawSnapByMouse as NEW form1

    What is a GridToolStripMenuItem? I cant find how to make a toolstripmenuitem control? I cant remake the form as you have it and debug it for you. When I add your code to a form then it locks up as I dont have the right controls.

    You need to learn to debug. You need to learn to make a complex thing. You did too much at once and now have errors you cant track. YOu should add one thing and run it. If error debug it. YOu need to learn to debug.

    Start removing sub routines until the error stops. Probably the last thing you added.

    Or start over. Run your code, add something, run, debug, then add...

    YOu need to work practice simple one form examples of what you are doing. ie make a practice form with a menustrip and try to add the code you get the error with. I have thousands of exmaples I have made to learn something before I add it to my no 1 app.

    PS you should make a tool bar as I show. ie takes one click to set snap with a toolbar that is visible it takes several clicks to use a menu.

    "Also why there is Yoffest and there is no Xoffest."

    You tell me. What does yoffset do for the yaxis? Do you need to do that for the x axis?

    I am not going to answer every quesiton you come up with Hany. You need to work harder to understand it. YOu need to learn how to hunt down answers. I know its harder for you since the language is differnt etc. But one day I wont be here and then you are stuck.

    :)

    Edit: Set Option Strict On for the project and elimate all the red line errors.
    Thursday, October 3, 2019 2:37 PM
  • Dear Tommy,

    I have marked it as an answer because you did an effort while it is not complete answer, that while I make the size of form1 maximized and scale X not must equal to scale Y, I got error that I don't change any code from the definition of variables or definition of Object.

    All what I will do, if I don't have clear answer, that I will ignore input the shape by drawing and I will depend on input the shape by coordinates and I will complete that development by input shape by coordinates which is a challenging by it self.

    Because all the equations shall depend on numerical integrations of any shape by coordinates under biaxial moments and vertical loads (column).

    The numerical integrations of any shape by coordinates is imaginary works and it is too difficult and it is trillions of work more than this thread.

    God with me

    Thank you and sorry for taking many time from you and maybe I will try to ask questions related to draw by mouse after finish that development to be second development of the same program.

    I have done 4 applications for about 28 months of work and that is all my relation of visual basic applications and I did many macro with programming excel spread  sheets for a period of 36 months.

    And that all what I did from losing my job in structural design.

    I will complete till end of my life for doing structural design programs unless I find a job in structural design field. 

    Kind Regards,



    Hany Metry



    • Edited by Hany Metry Saturday, October 5, 2019 2:16 AM
    Thursday, October 3, 2019 6:40 PM
  • By coordinates


    Hany Metry

    Saturday, October 5, 2019 9:26 AM
  • Hi,

    Do you resolve the issue? If you resolve the issue, please mark the helpful as answer. It will be beneficial to other community.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, October 8, 2019 9:46 AM
    Moderator
  • Hi,

    The issue not solved yet.


    Hany Metry


    • Edited by Hany Metry Tuesday, October 8, 2019 4:33 PM
    Tuesday, October 8, 2019 4:33 PM
  • Dear Hany,

    If the solution given by Tommy is useful, it is recommended that you do not mark it as an answer and then unmark it.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 14, 2019 2:02 AM
    Moderator
  • Dear Hany,

    If the solution given by Tommy is useful, it is recommended that you do not mark it as an answer and then unmark it.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Dear Julie,

    The solution is useful for others (because I am bad than others and others may understand more than me) and I don't solve the issue yet that I changed my mind to input the data by mouse while I input data by coordinates.

    Maybe also I will try to understand what Tommy written after a year or more, so it is better to mark it as an answer as I did from one and half hour than leave it for more than year without response from me.

    Best Regards,


    Hany Metry


    • Edited by Hany Metry Thursday, November 14, 2019 9:48 AM
    Thursday, November 14, 2019 9:46 AM