0

My goal here is to create a list of a certain size and randomly select 3 points from that list. Once a point is selected, it is deleted from the list so it won't be selected again. My problem is the debugger is saying I've got an index out of the range of the list. I'm relatively new to VB.NET, but am pretty experienced with VBA. Thank you in advance for your help.

Private Sub Analyze_Click(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles Analyze_Image.Click

    Dim i As Long, j As Long, k As Long, Image_Width As Long, Image_Height As Long, Pixel_Count As Long, Pixel As Long
    Dim My_Image As Image
    Dim RandomClass As New Random()
    Dim RandomIndex_1 As Long, RandomIndex_2 As Long, RandomIndex_3 As Long
    Dim P1 As Point, P2 As Point, P3 As Point

    My_Image = My_PictureBox.Image
    Image_Width = My_Image.Width
    Image_Height = My_Image.Height
    Pixel_Count = Image_Width * Image_Height

    Dim Numbers = Enumerable.Range(0, Pixel_Count + 1).ToList()

    For Pixel = 1 To Pixel_Count
        RandomIndex_1 = RandomClass.Next(0, Numbers.Count)
        Numbers.RemoveAt(RandomIndex_1)
        RandomIndex_2 = RandomClass.Next(0, Numbers.Count)
        Numbers.RemoveAt(RandomIndex_2)
        RandomIndex_3 = RandomClass.Next(0, Numbers.Count)
        Numbers.RemoveAt(RandomIndex_3)

        i = Numbers(RandomIndex_1)
        j = Numbers(RandomIndex_2)
        k = Numbers(RandomIndex_3)

        If i Mod Image_Width = 0 Then
            P1.X = Image_Width
        Else
            P1.X = i Mod Image_Width
        End If
        If j Mod Image_Width = 0 Then
            P2.X = Image_Width
        Else
            P2.X = j Mod Image_Width
        End If
        If k Mod Image_Width = 0 Then
            P3.X = Image_Width
        Else
            P3.X = k Mod Image_Width
        End If
        If ((i - i Mod Image_Width) / Image_Width) + 1 = Image_Height + 1 Then
            P1.Y = Image_Height
        Else
            P1.Y = ((i - i Mod Image_Width) / Image_Width) + 1
        End If
        If ((j - j Mod Image_Width) / Image_Width) + 1 = Image_Height + 1 Then
            P2.Y = Image_Height
        Else
            P2.Y = ((j - j Mod Image_Width) / Image_Width) + 1
        End If
        If ((k - k Mod Image_Width) / Image_Width) + 1 = Image_Height + 1 Then
            P3.Y = Image_Height
        Else
            P3.Y = ((k - k Mod Image_Width) / Image_Width) + 1
        End If
    Next

End Sub
GollumInATuxedo
  • 153
  • 1
  • 1
  • 10
  • It would probably be helpful to indicate which line throws the exception, but it looks like you are removing items from the list (`Numbers.RemoveAt(RandomIndex_1)`) and then trying to read them (`i = Numbers(RandomIndex_1)`). – Mark Jul 14 '16 at 16:37
  • It also looks like you need `3 * Pixel_Count` items in your `Number` list? – Mark Jul 14 '16 at 16:44
  • Surprisingly simple fixes, I don't know where my brain is today. Made both of those changes and it's working now. Thanks! – GollumInATuxedo Jul 14 '16 at 16:50

1 Answers1

0

In addition to the comments on the question, you could simplify the logic somewhat by using a randomly sorted stack of numbers (however, see this question for a discussion about better ways to shuffle the list):

Dim Numbers = New Stack(
    Enumerable.Range(0, 3 * Pixel_Count) _
        .OrderBy(Function(i) RandomClass.Next()) _
        .ToList()
)

Your loop can then just pop numbers off the stack:

For Pixel = 1 To Pixel_Count
    i = Numbers.Pop()
    j = Numbers.Pop()
    k = Numbers.Pop()

    If i Mod Image_Width = 0 Then
        '... etc.
Next
Community
  • 1
  • 1
Mark
  • 8,140
  • 1
  • 14
  • 29