Search code examples
vb.netlistlinegdi+

VB.NET shifting all points of a line along the X coordinate from a list


I have a function that draws lines from a list of points in a VB.NET function onto a PictureBox. Two points are added to a list and a line is drawn between all points added in a list. However, when a new point is added to the list, I would want to shift all previously drawn lines to be shifted to the left.

For example, if 2 different lines were drawn between (9, 0) (9, 4) and between (10, 0) (10, 3) respectively from a list, and a third line was added to a list (10, 0) (10, 2), I would like to shift the first two lines like this:

(9, 0), (9, 4) to (8, 0), (8, 4)

(10, 0), (10, 3) to (9, 0), (9, 3)

This is an demostration of what I mean.

The green line is the first line drawn and the yellow is the second line drawn. In the second figure, a dark blue line is added and the first two lines drawn, yellow and green, are all shifted to the left.

Lines

I am using this code to attempt to draw these types of lines.

Public Class Line

    Public ReadOnly Property StartPoint As Point

    Public ReadOnly Property EndPoint As Point

    Public Sub New(startPoint As Point, endPoint As Point)
        Me.StartPoint = startPoint
        Me.EndPoint = endPoint
    End Sub

End Class
Public Class Form1
Private lines As New List(Of Line)

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    For Each line In lines
        e.Graphics.DrawLine(Pens.Black, line.StartPoint, line.EndPoint)
    Next
End Sub

Private Sub AddNewLine(length As Integer)

    Dim pictureBoxRightXPoint As Integer = 300 'the right most side of the PictureBox is the x coordinate of 300 (PictureBox has the x size of 300).

    For Each l As line In lines 'move all points of X in all previously drawn lines in the list to the left.
            l.StartPoint.X = l.StartPoint.X - 1
            l.EndPoint.X = l.EndPoint.X - 1

    Next
    lines.Add(New Line((pictureBoxRightXPoint, 0), (pictureBoxRightXPoint, length))
    PictureBox1.Invalidate() 'Refresh the PictureBox to redraw the lines.
End Sub

End Class

After I add this, I get the error of:

Expression is a value and therefore cannot be the target of an assignment

when I try to subtract 1 from the X coordinate to shift all points already in the list to the left.

How can I fix this or draw one line in a PictureBox when shifting all previously drawn points to the left? (Note: there can be multiple lines already added in the list).

(Code to just draw and add lines to list is from: https://stackoverflow.com/a/66621165/14924603).


Solution

  • If you would like to draw the image in which I believe you stated (in your example) at the end of the PictureBox, you could just position your PictureBox inside the right end of a Panel and draw your graphics/lines at the beginning of the PictureBox. To move all previously drawn graphics to the left, you could move the position of your PictureBox's location inside your Panel left.

    You can use your previous function to add a new line, but move your PictureBox and position its start at the end of a Panel. To add a new line, use this:

    Dim xint As Integer = 1
    
    Dim r As Random = New Random
    xint = xint + 1
    Dim Point1 As New Point(xint, r.Next(40, 79))
    Dim point2 As New Point(xint, r.Next(80, 100))
    
    AddNewLine(Point1, point2)
    PictureBox1.Left -= 1 'Move the PictureBox Left
    
    PictureBox1.Size = New Size(PictureBox2.Size.Width + 1, 269) 'Change its size to allow for continuous line drawing 
    

    You can replace the random Y length I used with an actual point that you manipulate. The Line drawing function you linked will work fine for this. To clarify, make sure to use this:

    Private Sub AddNewLine(startPoint As Point, endPoint As Point)
        lines.Add(New Line(startPoint, endPoint))
        PictureBox1.Invalidate()
    End Sub
    

    And your Paint event should be this:

    For Each line In lines
         e.Graphics.DrawLine(Pens.Black, line.StartPoint, line.EndPoint)
    Next