none
How I can draw grid lines on picture box and then draw by mouse lines between grids ?(snap at intersection of grids)? RRS feed

  • Question

  • How I can draw grid lines on picture box and then draw by mouse lines between grids ?(snap at intersection of grids)? 

    Hany Metry

    Monday, May 15, 2017 5:32 PM

Answers

  • Well well there you are!

    We all wondered how you were dong Hany?

    Are you still working the same program or is this something new?

    Here is an example that uses a class.

    I included several things you should find useful. Note you set the grid and other parameters like the gridstep and use the SnapToGrid function to round from the mouse pointer client pixels to the drawing grid coordinates.

    The grid can be defined any scale size and grid step. YOu can offset the origin and etc. Basically everything one needs to draw a nice zoomable and scrollable grid and then draw on it and save the drawing data.

    Using the shape class one can draw and save the line shapes. You should learn this if you have not. We have shown you before how to use a class to store data. And the example makes a list of the shapes instead of using an old school array.

    This is a complete working example. Just copy the code into an empty form. If you learn how this works your coding will improve greatly. Mine did.

    :)

    Public Class Form2
        Public Class Shape
            Public pt1 As PointF
            Public pt2 As PointF
            Public color As Color = Color.Red
    
            Public Sub Draw(g As Graphics)
                Using p As New Pen(color, g.VisibleClipBounds.Width / 100)
                    g.DrawLine(p, pt1, pt2)
                End Using
            End Sub
        End Class
        Private Shapes As New List(Of Shape)
    
        Private Corner As New Point(-5, -5)
        Private GridStep As Single = 20
        Private SnapStep As Single = 10
        Private ScaleWidth As Single = 100
    
        Private MouseDownPt, MouseMovePt As PointF
        Private MouseStaus As Integer = 0
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DoubleBuffered = True
            Text = "Snap to Grid Example"
        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)
                MouseDownPt = SnapToGrid(pt)
                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)
                        MouseMovePt = SnapToGrid(pt)
                        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)
                    MouseMovePt = SnapToGrid(pt)
    
                    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
            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)
    
                DrawGrid(e.Graphics)
    
                For Each shp As Shape In Shapes
                    shp.Draw(e.Graphics)
                Next
    
                Select Case MouseStaus
                    Case 1  'draw line tracer
                        .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, y1, x, CSng(y1 + sw))
                        .DrawString(x.ToString, f, br, x, Corner.Y)
                    Next
    
                    For y As Single = y1 To CSng(y1 + sw) Step GridStep
                        .DrawLine(pg, x1, y, CSng(x1 + sw), y)
                        .DrawString(y.ToString, f, br, Corner.X, y)
                    Next
                End Using
            End With
        End Sub
    
        Private Function SnapToGrid(thispt As PointF) As PointF
            Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
            Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
            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 = ClientSize.Width / ScaleWidth
            Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (pt.Y / sf)))
        End Function
    End Class

    • Proposed as answer by leshay Tuesday, May 16, 2017 2:01 PM
    • Marked as answer by Morgan Mosa Friday, May 19, 2017 5:06 AM
    • Unmarked as answer by Morgan Mosa Thursday, September 26, 2019 12:05 PM
    • Marked as answer by Morgan Mosa Thursday, September 26, 2019 12:24 PM
    Tuesday, May 16, 2017 11:37 AM
  • Dear Tommy,

    How to make the origin at the center of the form and the snap shall be positive value or negative value as well as the ruler  and the top and at the sides shall be with negative values and positive values.

    I tried by change the corner coordinates from -5,-5 to be -me.width/2,-me.height/2 but that not solve the problem.

    Kind Regards,


    Hany Metry



    Hi Hany,

    How are you?

    Sold any programs?

    I assume this is what you mean?

    In windows graphics drawing the yaxis increases going down I call it negative y axis. So we reverse the entire window in the y axis it to change the direction to positive y axis.

    Basically, everytime a y value is drawn, subtract the y coordinate from the scale height of the window ( the yOffset). That will flip the y axis. That is all there is to it.

    See where the class level (global) yoffset is calced in the form resize event using the scalewidth?

    And see where (yoffset - yvalue) is used everywhere we draw in the form coordinate neg yaxis system? Not used to calc in our coordinate system that just stays normal as-is. But when we draw we use the yoffset to reverse it.

    To center origin use -ScaleWidth / 2 see where I set it at the start? Scalewidth is our definition of number of units per window width in pixels. ie in the example the scalewidth is 100 so 100 units across the widow horz.

    If this is not want you mean then show a picture of the result you want. You will have to debug it further?

    :)

    Its the same example from above with Yoffset added.

    'version 2 example with positive y axis, centered origin
    Imports System.Drawing.Imaging
    
    Public Class Form2
        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)
                    MouseDownPt = SnapToGrid(pt)
                    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)
                            MouseMovePt = SnapToGrid(pt)
                            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)
                        MouseMovePt = SnapToGrid(pt)
    
                        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
            Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
            Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
            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 = 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
    End Class



    • Edited by tommytwotrain Thursday, September 26, 2019 5:08 PM
    • Marked as answer by Morgan Mosa Wednesday, October 2, 2019 2:46 PM
    Thursday, September 26, 2019 5:02 PM

All replies

  • Hi Hany Metry,

    Please refer to the article (Q&A): Draw on a picturebox image using mouse vb.net
    http://stackoverflow.com/questions/13327311/draw-on-a-picturebox-image-using-mouse-vb-net
    ___________
    Ashidacchi
    Tuesday, May 16, 2017 2:26 AM
  • How I can draw grid lines on picture box and then draw by mouse lines between grids ?(snap at intersection of grids)?

    That would depend on how you have defined the grid lines for the object you are drawing on. Once you know what the grid line positions (vertical and horizontal) are you can draw the lines.   That same data source tells you what the grid intersection points are. When you know that you can calculate the distance from the mouse click point to each one (using plane trigonometry), and choose the one with the shortest distance as the drawing point.  Typically, if the shortest distance is longer than some arbitrary value (eg, 1/4 of the grid spacing) you will not select any point, but that depends on what the application is. 

    Tuesday, May 16, 2017 2:46 AM
  • How I can draw grid lines on picture box and then draw by mouse lines between grids ?(snap at intersection of grids)? 

    Hany Metry

    Hi

    Here is some code that should 'snap to grid intersections' when mouse button pressed. Minimal testing done but seems to work.

    No drawing of lines done.

    ' blank Form1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim myPen As New Pen(Color.DarkGray)
        Dim topBorder As Integer = 40
        Dim leftBorder As Integer = 20
        Dim gridsize As Integer = 40
        Dim HorCells As Integer = 10
        Dim VertCells As Integer = 5
        Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
            For i As Integer = 0 To HorCells
                e.Graphics.DrawLine(myPen, New Point(leftBorder + i * gridsize, topBorder), New Point(leftBorder + i * gridsize, topBorder + VertCells * gridsize))
            Next
            For i As Integer = 0 To VertCells
                e.Graphics.DrawLine(myPen, New Point(leftBorder, topBorder + i * gridsize), New Point(leftBorder + HorCells * gridsize, topBorder + i * gridsize))
            Next
        End Sub
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
            Dim dx As Integer = ((PointToClient(MousePosition).X - leftBorder + gridsize \ 2) \ gridsize)
            Dim dy As Integer = ((PointToClient(MousePosition).Y - topBorder + gridsize \ 2) \ gridsize)
            If dx > HorCells Or dy > VertCells Then Exit Sub
            Cursor.Position = PointToScreen(New Point(leftBorder + dx * gridsize, topBorder + dy * gridsize))
        End Sub
    End Class


    Regards Les, Livingston, Scotland

    Tuesday, May 16, 2017 3:40 AM
  • Hi Hany,

    You can refer to the code below to draw grid lines on picture box.

    Private Sub pictureBox1_Paint(sender As Object, e As PaintEventArgs)
    	Dim g As Graphics = e.Graphics
    	Dim numOfCells As Integer = 200
    	Dim cellSize As Integer = 5
    	Dim p As New Pen(Color.Black)
    
    	For y As Integer = 0 To numOfCells - 1
    		g.DrawLine(p, 0, y * cellSize, numOfCells * cellSize, y * cellSize)
    	Next
    
    	For x As Integer = 0 To numOfCells - 1
    		g.DrawLine(p, x * cellSize, 0, x * cellSize, numOfCells * cellSize)
    	Next
    
    End Sub
    

    Best Regards,

    Cherry


    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, May 16, 2017 5:51 AM
    Moderator
  • You can refer to the code below to draw grid lines on picture box.

    OP already knows how to draw gridlines and freehand graphics, The only new part of the problem is to make the lines snap. Please see:
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/91e1297c-5376-4637-875e-6613eaf988bb

    Tuesday, May 16, 2017 10:23 AM
  • Well well there you are!

    We all wondered how you were dong Hany?

    Are you still working the same program or is this something new?

    Here is an example that uses a class.

    I included several things you should find useful. Note you set the grid and other parameters like the gridstep and use the SnapToGrid function to round from the mouse pointer client pixels to the drawing grid coordinates.

    The grid can be defined any scale size and grid step. YOu can offset the origin and etc. Basically everything one needs to draw a nice zoomable and scrollable grid and then draw on it and save the drawing data.

    Using the shape class one can draw and save the line shapes. You should learn this if you have not. We have shown you before how to use a class to store data. And the example makes a list of the shapes instead of using an old school array.

    This is a complete working example. Just copy the code into an empty form. If you learn how this works your coding will improve greatly. Mine did.

    :)

    Public Class Form2
        Public Class Shape
            Public pt1 As PointF
            Public pt2 As PointF
            Public color As Color = Color.Red
    
            Public Sub Draw(g As Graphics)
                Using p As New Pen(color, g.VisibleClipBounds.Width / 100)
                    g.DrawLine(p, pt1, pt2)
                End Using
            End Sub
        End Class
        Private Shapes As New List(Of Shape)
    
        Private Corner As New Point(-5, -5)
        Private GridStep As Single = 20
        Private SnapStep As Single = 10
        Private ScaleWidth As Single = 100
    
        Private MouseDownPt, MouseMovePt As PointF
        Private MouseStaus As Integer = 0
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DoubleBuffered = True
            Text = "Snap to Grid Example"
        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)
                MouseDownPt = SnapToGrid(pt)
                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)
                        MouseMovePt = SnapToGrid(pt)
                        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)
                    MouseMovePt = SnapToGrid(pt)
    
                    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
            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)
    
                DrawGrid(e.Graphics)
    
                For Each shp As Shape In Shapes
                    shp.Draw(e.Graphics)
                Next
    
                Select Case MouseStaus
                    Case 1  'draw line tracer
                        .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, y1, x, CSng(y1 + sw))
                        .DrawString(x.ToString, f, br, x, Corner.Y)
                    Next
    
                    For y As Single = y1 To CSng(y1 + sw) Step GridStep
                        .DrawLine(pg, x1, y, CSng(x1 + sw), y)
                        .DrawString(y.ToString, f, br, Corner.X, y)
                    Next
                End Using
            End With
        End Sub
    
        Private Function SnapToGrid(thispt As PointF) As PointF
            Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
            Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
            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 = ClientSize.Width / ScaleWidth
            Return New PointF(CSng(Corner.X + (pt.X / sf)), CSng(Corner.Y + (pt.Y / sf)))
        End Function
    End Class

    • Proposed as answer by leshay Tuesday, May 16, 2017 2:01 PM
    • Marked as answer by Morgan Mosa Friday, May 19, 2017 5:06 AM
    • Unmarked as answer by Morgan Mosa Thursday, September 26, 2019 12:05 PM
    • Marked as answer by Morgan Mosa Thursday, September 26, 2019 12:24 PM
    Tuesday, May 16, 2017 11:37 AM
  • hi tommy,

    I marked as answer even uptill now, I do not understand it.

    I cant copy paste that answer because really it is part of solution and it is not thr final solution, that I want to draw shapes like pologens so it is not a line that the user must find the mouth continue draw pologen from the last grid line which snap on it untill the shape is colsed to draw line to first grid intersection which snap on it. (Draw column of irregular shapes).

    Also I must find back the coordinates of all grid lines intersection in serial.

    Kind regards,

    Hany

     


    Hany Metry

    Friday, May 19, 2017 6:06 AM
  • hi tommy,

    I marked as answer even uptill now, I do not understand it.

    I cant copy paste that answer because really it is part of solution and it is not thr final solution, that I want to draw shapes like pologens so it is not a line that the user must find the mouth continue draw pologen from the last grid line which snap on it untill the shape is colsed to draw line to first grid intersection which snap on it. (Draw column of irregular shapes).

    Also I must find back the coordinates of all grid lines intersection in serial.

    Kind regards,

    Hany

     


    Hany Metry

    Hany,

    Yes I knew that code would not copy directly into your stress chart projet if thats what you mean.

    However that code will copy into an empty form in a new project. And then you can run that. And you can see and learn how it works and then you can modify it for your exact needs.

    The basic methods in the example are what you will need thats how VB works. Once you understand it you can modify and add to it to do what you describe.

    This is the basic drawing method in VB. This is what you will need to do what you want.

    What do you understand in the example?

    You see how the grid is drawn using the paint event right? In the paint event the line shapes that have already been made are drawn. And the line that is currently being made is drawn, if there is one.

    You can see there is the mousedown event when the first point is clicked by the user, and that point is saved in mousedownpt, a flag is set telling use we are on step one of drawing a line mousestatus = 1.

    Then in the mousemove event the current mouse posisitone is saved in mousemovept and the paint event called using .invalidate. So the line is draw from mousedownpt to mousemovept as the user moves.

    When the line is done the user releases the mouse and the mouseup event fires and now the example code creates a new line shape and saves it in the list of line shapes. Invalidate is called and the paint event fires and the gride and the shapes in the list of shapes is drawn.

    So do you follow drawing a single line?

    Once you follow that then you just need to add to it to draw a polygon of many lines etc.

    If you learn this example then most of what you need is there.

    If you do not then you will never be able to do what you want exactly.

    Thats what it boils down to.

    You cant write a program until you learn to program. You have not learned to program until you learn to use a class to store and manipulate data.

    Friday, May 19, 2017 11:52 AM
  • I am not understand any from your program, it is too difficult.

    Hany Metry

    Saturday, May 20, 2017 11:35 AM
  • I am not understand any from your program, it is too difficult.

    Hany Metry

    Hany,

    I see. Did you get the example I posted to run?

    So what do you want to do now?

    Do you understand this sub routine? It is the answer to your question if I understand it. How to snap to the grid lines. Is that what your basic question is?

       Private Function SnapToGrid(thispt As PointF) As PointF
            Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
            Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
            Return New PointF(x, y)
        End Function

    The example is not that hard. If you want we can explain each step. But you have to give us something to go on.

    Or are you not understanding how to draw on a picturebox using the mouse?

    Saturday, May 20, 2017 12:05 PM
  • Dear Tommy,

    How to make the origin at the center of the form and the snap shall be positive value or negative value as well as the ruler  and the top and at the sides shall be with negative values and positive values.

    I tried by change the corner coordinates from -5,-5 to be -me.width/2,-me.height/2 but that not solve the problem.

    Kind Regards,


    Hany Metry



    • Edited by Morgan Mosa Thursday, September 26, 2019 3:11 PM correction
    Thursday, September 26, 2019 2:41 PM
  • Dear Tommy,

    How to make the origin at the center of the form and the snap shall be positive value or negative value as well as the ruler  and the top and at the sides shall be with negative values and positive values.

    I tried by change the corner coordinates from -5,-5 to be -me.width/2,-me.height/2 but that not solve the problem.

    Kind Regards,


    Hany Metry



    Hi Hany,

    How are you?

    Sold any programs?

    I assume this is what you mean?

    In windows graphics drawing the yaxis increases going down I call it negative y axis. So we reverse the entire window in the y axis it to change the direction to positive y axis.

    Basically, everytime a y value is drawn, subtract the y coordinate from the scale height of the window ( the yOffset). That will flip the y axis. That is all there is to it.

    See where the class level (global) yoffset is calced in the form resize event using the scalewidth?

    And see where (yoffset - yvalue) is used everywhere we draw in the form coordinate neg yaxis system? Not used to calc in our coordinate system that just stays normal as-is. But when we draw we use the yoffset to reverse it.

    To center origin use -ScaleWidth / 2 see where I set it at the start? Scalewidth is our definition of number of units per window width in pixels. ie in the example the scalewidth is 100 so 100 units across the widow horz.

    If this is not want you mean then show a picture of the result you want. You will have to debug it further?

    :)

    Its the same example from above with Yoffset added.

    'version 2 example with positive y axis, centered origin
    Imports System.Drawing.Imaging
    
    Public Class Form2
        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)
                    MouseDownPt = SnapToGrid(pt)
                    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)
                            MouseMovePt = SnapToGrid(pt)
                            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)
                        MouseMovePt = SnapToGrid(pt)
    
                        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
            Dim x As Single = CInt(thispt.X / SnapStep) * SnapStep
            Dim y As Single = CInt(thispt.Y / SnapStep) * SnapStep
            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 = 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
    End Class



    • Edited by tommytwotrain Thursday, September 26, 2019 5:08 PM
    • Marked as answer by Morgan Mosa Wednesday, October 2, 2019 2:46 PM
    Thursday, September 26, 2019 5:02 PM
  • Dear Mr. Tommy,

    Really you are brilliant but the problem is complicated which require from you much effort to learn me.

    I want the form shall be full size (maximum window size) and when I make full screen window the drawing still of small size.

    I want to input some data by using menu strip and before start of input data by menu strip the grid appear by default value and the maximum and minimum scale (ruler appear by default value).

    I need the size of drawing will be variable that the user shall input(by menu strip) the maximum X positive coordinates and maximum Y positive coordinates and the minimum X negative coordinates  as well as the minimum Y negative coordinates (the negative and positive values may exceed the size of form in Pixel). So the ruler shall be changed after input.

    Also the user shall input the snap step which equal to grid step.

    I tried to make the ClientSize = New Size(me.width, me.height) but I got troubles (that will not solve the problem because the size of drawing may exceed the pixel size of form).

    Before to draw the shape the user must use the menu strip to start draw the shape.

    How to make the draw a lines and the line will still attach from the last drawn point till closed the pologens so it is not a line that the user must find the mouth continue draw pologen from the last grid line which snap on it until the shape is closed to draw line to first grid intersection which snap on it. (Draw column of irregular shapes).

    How to save the input coordinates for each point in serial as array Coorx(1,X) , Coorx(n,X) and Coory(1,Y), Coory(n,Y)

    The user will use menu strip again to draw the reinforcement coordinates by mouse and the diameter of drawing shall be different according to diameter of reinforcement (which shall be input by menu strip before start to draw and the user may change the diameter each time to input different diameters).

    How to save the input reinforcement coordinates for each point in serial as array CoorxRF(1,X) , CoorxRF(n,X) and CooryRF(1,Y), CooryRF(n,Y).

    Concerning the selling, I sold two programs (open copy) for one company only and they purchase to help me.

    Kind Regards,



    Hany Metry



    • Edited by Morgan Mosa Friday, September 27, 2019 9:33 AM correction
    Friday, September 27, 2019 8:30 AM
  • Dear Mr. Tommy,

    Really you are brilliant but the problem is complicated which require from you much effort to learn me.

    I want the form shall be full size (maximum window size) and when I make full screen window the drawing still of small size.

    I want to input some data by using menu strip and before start of input data by menu strip the grid appear by default value and the maximum and minimum scale (ruler appear by default value).

    I need the size of drawing will be variable that the user shall input(by menu strip) the maximum X positive coordinates and maximum Y positive coordinates and the minimum X negative coordinates  as well as the minimum Y negative coordinates (the negative and positive values may exceed the size of form in Pixel). So the ruler shall be changed after input.

    Also the user shall input the snap step which equal to grid step.

    I tried to make the ClientSize = New Size(me.width, me.height) but I got troubles (that will not solve the problem because the size of drawing may exceed the pixel size of form).

    Before to draw the shape the user must use the menu strip to start draw the shape.

    How to make the draw a lines and the line will still attach from the last drawn point till closed the pologens so it is not a line that the user must find the mouth continue draw pologen from the last grid line which snap on it until the shape is closed to draw line to first grid intersection which snap on it. (Draw column of irregular shapes).

    How to save the input coordinates for each point in serial as array Coorx(1,X) , Coorx(n,X) and Coory(1,Y), Coory(n,Y)

    The user will use menu strip again to draw the reinforcement coordinates by mouse and the diameter of drawing shall be different according to diameter of reinforcement (which shall be input by menu strip before start to draw and the user may change the diameter each time to input different diameters).

    How to save the input reinforcement coordinates for each point in serial as array CoorxRF(1,X) , CoorxRF(n,X) and CooryRF(1,Y), CooryRF(n,Y).

    Concerning the selling, I sold two programs (open copy) for one company only and they purchase to help me.

    After you help me, I will use the coordinates for integration and complicated mathematics to make the program and program output .... etc.

    Kind Regards,



    Hany Metry


    LOL!

    Sold two! Good for you!

    Yes test test test and debug...

    Well you have your work cut out for you with all that to do.

    "How to make the draw a lines and the line will still attach from the last drawn point"

    That is not hard. I think you can figure it? Search for examples.

    All that can be done.

    It is just a matter of doing one thing at a time.

    So on the last example posted here version 2 it is the class Shape you dont understand? That is how we make a line object for our drawing. When we click the mouse we save the points in Shape.Pt1 and Shape.Pt2 for the two end points of a line. You understand that right?

    You just need to start at the beginning and learn one thing at a time and then practice with it and then maybe try to include it in your large project when you think you can understand and imagine how it will work.

    And on and on...

    If you have a question start a new forum thread showing what you have tried and a one form example or link to show exactly what the question is and even a picture showing the exact result you want.

    :)

    Friday, September 27, 2019 9:36 AM
  • Dear Mr. Tommy,

    Egyptian are not happy to pay money for programs and they want programs with crack free of charge.

    The benefits of my programs includes Egyptian design codes and it will be no useful outside Egypt because there are many available programs which include American, Europe and British code and available in the internet with crack (free of charge).

    There are a lot of work from integrations and mathematical equations and charts after find the coordinates.

    Kind Regards,


    Hany Metry

    Friday, September 27, 2019 11:22 AM
  • Dear Mr. Tommy,

    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

    I need explannation of the above code

    what is the meaning and function of 

    Using p As New Pen(color, g.VisibleClipBounds.Width / 100)

    and what happened if

    I wrote

    Using p As New Pen(color, g.VisibleClipBounds.Width / 200)


    what is the meaning of and function of visibleClipBound

    Hany Metry


    • Edited by Morgan Mosa Friday, September 27, 2019 3:01 PM add
    Friday, September 27, 2019 2:41 PM
  • Dear Mr. Tommy,

    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

    I need explannation of the above code

    what is the meaning and function of 

    Using p As New Pen(color, g.VisibleClipBounds.Width / 100)

    and what happened if

    I wrote

    Using p As New Pen(color, g.VisibleClipBounds.Width / 200)


    what is the meaning of and function of visibleClipBound

    Hany Metry


    First off next time start a new thread! This question will help others if they can find it. If you add it to this old thread it will be lost.

    Just ref this thread as reqd in a new thread.


    Plus if you Click the word Pen in the vs code editor and then press the F1 key you will get topic help:

    https://docs.microsoft.com/en-us/dotnet/api/system.drawing.pen?redirectedfrom=MSDN&view=netframework-4.8

    On the link page set the language to vb with the menu at top.

    Pick the version with two constructors:

    "   Pen(Color, Single)

        Parameters

        color Color  
        A Color structure that indicates the color of this Pen.

        width Single  
        A value indicating the width of this Pen.
    "


    Notice the second variable is width of pen. So that is the scale width of the line draw with that pen.

    Maybe you know that already?

    Now in this code example the drawing is done in the Form2_Paint event. In the paint event the drawing scale is defined for the view window for the paint event object form2 in this case.

       .ScaleTransform(sf, sf)

    If you F1 that you will learn that is where we give the window a user defined scale ratio. The scaletransform will produce the ScaleWidth we define for our user defined window ie scale width user units wide (by a simple ratio sf of the pixel width of the widow).

    So in our example the scalewidth = 100 as defined at start. We have set the form.clientsize to clientsize.width = 300 pixels. So our scale ratio for the widow is

           sf = window width in pixels / scalewidth

           sf = 300 / 100 = 3.

    So the scale of the window is 100 user units across the width. Comprende? We enlarged the unit width x 3. ie 300 pixels form window horz width = 100 user units. See how the drawing grid shows 100 unit wide?

    F1 on VisibleClipBounds you will learn that is the size of the window that paint event is from which is form2 so that is same as form2.clientrectangle and gives us the width of our window in pixels.

    I used VisibleClipBounds instead of form2.clientsize.width so I can copy my Shape class to other projects or forms and it still works without hard coding the control name form2. ie in some other place maybe its picturebox22. Using visible window avoids using the control name.

    Back to the pen, we use the window scale ratio so we can resize the window and the pen width gets scaled up and down with the window size. We may or may not want that. If we do it this way then the pen remains constant size as the window changes size even though the width of our drawing window is increasing or decreasing.

    Notice as you drag the form border to resize the window of example 2, the grid lines and text stay the same size. However the red line you drew gets wider as the window is enlarged. And... see how the grid shows 100 units across the form width as the form is enlarged?

    Now try changing the pen width and whatch what happens. It wont break anything.

    PS start a new thread next time unless it is only related to the original question. I wont always be here and others know more than I about it.

    See how the form is larger and the drawing is larger and the red pen is larger in the image.




    Ooops where did the x axis labels go?   :)

    Friday, September 27, 2019 4:40 PM
  • Hi Hany,

    How are you?

    Sold any programs?

    I assume this is what you mean?

    In windows graphics drawing the yaxis increases going down I call it negative y axis. So we reverse the entire window in the y axis it to change the direction to positive y axis.

    Basically, everytime a y value is drawn, subtract the y coordinate from the scale height of the window ( the yOffset). That will flip the y axis. That is all there is to it.

    See where the class level (global) yoffset is calced in the form resize event using the scalewidth?

    And see where (yoffset - yvalue) is used everywhere we draw in the form coordinate neg yaxis system? Not used to calc in our coordinate system that just stays normal as-is. But when we draw we use the yoffset to reverse it.

    To center origin use -ScaleWidth / 2 see where I set it at the start? Scalewidth is our definition of number of units per window width in pixels. ie in the example the scalewidth is 100 so 100 units across the widow horz.

    If this is not want you mean then show a picture of the result you want. You will have to debug it further?


    Dear Mr. Tommy,

    I still have difficulties to make Client Size equal to Windowstate = Maximized and make drawing area not equal for X axis and Y axis.

    Kind Regards,


    Hany Metry


    • Edited by Morgan Mosa Wednesday, October 2, 2019 3:08 PM adjust
    Wednesday, October 2, 2019 3:06 PM
  • Dear Mr. Tommy,

    I still have difficulties to make Client Size equal to Windowstate = Maximized and make drawing area not equal for X axis and Y axis.

    Kind Regards,


    Hany Metry


    Start a new question.

    Show a simple one form code example  what you have done so far and explain exactly what you dont understand and explain or show image of exactly what you want to achieve.


    Wednesday, October 2, 2019 3:12 PM
  • Dear Mr. Tommy,

    I still have difficulties to make Client Size equal to Windowstate = Maximized and make drawing area not equal for X axis and Y axis.

    Kind Regards,


    Hany Metry


    Start a new question.

    Show a simple one form code example  what you have done so far and explain exactly what you dont understand and explain or show image of exactly what you want to achieve.


    Dear Mr Tommy,

    Please refer to question      https://social.msdn.microsoft.com/Forums/en-US/8f8f70ec-9a87-43c2-9ae8-957dc9c97927/how-to-draw-by-mouse-a-polygon-of-any-shape-snap-to-grid-or-not-snap-to-grid-the-snap-maybe-off?forum=vbgeneral

    Kind Regards,



    Hany Metry

    Wednesday, October 2, 2019 3:23 PM
  • Hi tommytwotrain

    I am working with your code that makes a grid inside a windows form then allows you to draw lines on the grid.

    The problem that is have is that I want to draw the grid inside a panel so that it would give me a little room on

    top to place buttons, like save, undo, print, etc.

    I don't now how to change this function so that It responds to the mouse pointer correctly.  so when mousedown is on 10, 10 on the grid, that's where the line starts.

    How can I change this function so it works on the Panel1 instead of the form1

     Private Function GetScalePtFromClientPt(pt As PointF) As PointF
            'convert screen pixels to scale drawing coords
            Dim sf As Double = Panel1.ClientSize.Width / ScaleWidth
            Return New PointF(CSng(Corner.X + (pt.X / sf)),
                          CSng(Corner.Y + (pt.Y / sf)))
        End Function

    Thank you so much. 

    Tony Springs


    Easterbird

    Wednesday, February 12, 2020 5:32 AM
  • Hi tommytwotrain

    I am working with your code that makes a grid inside a windows form then allows you to draw lines on the grid.

    The problem that is have is that I want to draw the grid inside a panel so that it would give me a little room on

    top to place buttons, like save, undo, print, etc.

    I don't now how to change this function so that It responds to the mouse pointer correctly.  so when mousedown is on 10, 10 on the grid, that's where the line starts.

    How can I change this function so it works on the Panel1 instead of the form1

     Private Function GetScalePtFromClientPt(pt As PointF) As PointF
            'convert screen pixels to scale drawing coords
            Dim sf As Double = Panel1.ClientSize.Width / ScaleWidth
            Return New PointF(CSng(Corner.X + (pt.X / sf)),
                          CSng(Corner.Y + (pt.Y / sf)))
        End Function

    Thank you so much. 

    Tony Springs


    Easterbird

    Tony,

    That code seems ok. Which example are you starting with? Negative or Positive y axis?

    Here is another example using a picture box with pos y:

    https://social.msdn.microsoft.com/Forums/en-US/8f8f70ec-9a87-43c2-9ae8-957dc9c97927/how-to-draw-by-mouse-a-polygon-of-any-shape-snap-to-grid-or-not-snap-to-grid-the-snap-maybe-off?forum=vbgeneral

    If you have more questions start your own new question thread and show a complete example of the code you are using.

    Wednesday, February 12, 2020 7:57 AM