Home All Groups Group Topic Archive Search About

"Random" numbers cause pattern?

Author
22 Jun 2009 12:27 AM
AW <>
Simple(?) program to draw random lines in a rectangle but when I
discard all random lines longer than size and graph the results I get
a set of diagonal bands. How can random lines have a pattern? Can
anyone explain? When I discard a line, I generate a new random line
until is it short enough - so how can it not be random?
Win XP & VB 2008 Express. Thanks.
--------------------------
Imports System
Imports System.Drawing
Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.VBMath
Imports Microsoft.VisualBasic.PowerPacks
Public Class Form1
    Dim rec As New RectangleShape
    Dim arx(5000, 2) As Integer
    Dim ary(5000, 2) As Integer
    Public Sub New()
        InitializeComponent()
        Randomize()
        Me.rec.Left = 300
        Me.rec.Top = 2
        Me.rec.Width = 900
        Me.rec.Height = 900
        For n = 0 To 4999
            arx(n, 0) = arx(n, 1) = ary(n, 0) = ary(n, 1) = 0
        Next
    End Sub
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        PGr()
    End Sub
    Private Sub PGr()
        Dim e As Graphics
        e = Me.CreateGraphics
        e.FillRectangle(Brushes.White, rec.Left, rec.Top, rec.Width,
rec.Height)
        For n = 0 To 4999
            e.DrawLine(Pens.Black, rec.Left + arx(n, 0), rec.Top +
ary(n, 0), _
                       rec.Left + arx(n, 1), rec.Top + ary(n, 1))
        Next
    End Sub
    Private Sub ReP_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles ReP.Click
        Dim Dret As Integer = 0
        For n = 0 To 4999
            Do
                arx(n, 0) = Int(Rnd() * 900)
                arx(n, 1) = Int(Rnd() * 900)
                ary(n, 0) = Int(Rnd() * 900)
                ary(n, 1) = Int(Rnd() * 900)
                Dret = Dist(n)
            Loop Until Dret = 1
        Next
        PGr()
    End Sub
    Private Function Dist(ByVal n As Integer) As Integer
        Dim x1, x2, y1, y2, h, h1, h2, size As Double
        size = 40
        x1 = arx(n, 0)
        x2 = arx(n, 1)
        h1 = Math.Pow((x1 - x2), 2)
        y1 = ary(n, 0)
        y2 = ary(n, 1)
        h2 = Math.Pow((y1 - y2), 2)
        h = h1 + h2
        h = Math.Sqrt(h)
        If h > size Then Return 0
        Return 1
    End Function
    Private Sub Quit_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Quit.Click
        End
    End Sub
End Class

Author
22 Jun 2009 1:37 AM
Family Tree Mike
Show quote Hide quote
"AW" wrote in message news:h6jt3558jmhnt7av632plpl7ljisto48q5@4ax.com...
> Simple(?) program to draw random lines in a rectangle but when I
> discard all random lines longer than size and graph the results I get
> a set of diagonal bands. How can random lines have a pattern? Can
> anyone explain? When I discard a line, I generate a new random line
> until is it short enough - so how can it not be random?
> Win XP & VB 2008 Express. Thanks.
> --------------------------
> Imports System
> Imports System.Drawing
> Imports Microsoft.VisualBasic
> Imports Microsoft.VisualBasic.VBMath
> Imports Microsoft.VisualBasic.PowerPacks
> Public Class Form1
>    Dim rec As New RectangleShape
>    Dim arx(5000, 2) As Integer
>    Dim ary(5000, 2) As Integer
>    Public Sub New()
>        InitializeComponent()
>        Randomize()
>        Me.rec.Left = 300
>        Me.rec.Top = 2
>        Me.rec.Width = 900
>        Me.rec.Height = 900
>        For n = 0 To 4999
>            arx(n, 0) = arx(n, 1) = ary(n, 0) = ary(n, 1) = 0
>        Next
>    End Sub
>    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As
> System.Windows.Forms.PaintEventArgs) Handles Me.Paint
>        PGr()
>    End Sub
>    Private Sub PGr()
>        Dim e As Graphics
>        e = Me.CreateGraphics
>        e.FillRectangle(Brushes.White, rec.Left, rec.Top, rec.Width,
> rec.Height)
>        For n = 0 To 4999
>            e.DrawLine(Pens.Black, rec.Left + arx(n, 0), rec.Top +
> ary(n, 0), _
>                       rec.Left + arx(n, 1), rec.Top + ary(n, 1))
>        Next
>    End Sub
>    Private Sub ReP_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles ReP.Click
>        Dim Dret As Integer = 0
>        For n = 0 To 4999
>            Do
>                arx(n, 0) = Int(Rnd() * 900)
>                arx(n, 1) = Int(Rnd() * 900)
>                ary(n, 0) = Int(Rnd() * 900)
>                ary(n, 1) = Int(Rnd() * 900)
>                Dret = Dist(n)
>            Loop Until Dret = 1
>        Next
>        PGr()
>    End Sub
>    Private Function Dist(ByVal n As Integer) As Integer
>        Dim x1, x2, y1, y2, h, h1, h2, size As Double
>        size = 40
>        x1 = arx(n, 0)
>        x2 = arx(n, 1)
>        h1 = Math.Pow((x1 - x2), 2)
>        y1 = ary(n, 0)
>        y2 = ary(n, 1)
>        h2 = Math.Pow((y1 - y2), 2)
>        h = h1 + h2
>        h = Math.Sqrt(h)
>        If h > size Then Return 0
>        Return 1
>    End Function
>    Private Sub Quit_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles Quit.Click
>        End
>    End Sub
> End Class
>


I would recommend not using Rnd().  Instead create an instance of Random,
and use it.  I believe after this change you will see what your are trying
to get.  So my code looks like the following mods:

public class Form1
....
  Dim r as New Random
....
  Private Sub ReP_Click(...
  ...
    arx(n, 0) = CInt(r.NextDouble() * 900.0)
    arx(n, 1) = CInt(r.NextDouble() * 900.0)
    ary(n, 0) = CInt(r.NextDouble() * 900.0)
    ary(n, 1) = CInt(r.NextDouble() * 900.0)
  ...


I cannot address why Rnd() does what you are seeing, because I don't use
Rnd().

You also might consider generating point 2 (arx(n,1) and ary(n,1)) by using
a random distance less than your desired size and a random angle.  This will
save the loopy logic testing whether your random line works.  Your random
line generated by using a distance and angle will always be less than the
desired size.  You would have to check for points off the graphics area of
course, but that should be an easier check.

--
Mike
Author
22 Jun 2009 2:28 AM
AW <>
On Sun, 21 Jun 2009 21:37:24 -0400, "Family Tree Mike"
<FamilyTreeM***@ThisOldHouse.com> wrote:

Show quoteHide quote
>"AW" wrote in message news:h6jt3558jmhnt7av632plpl7ljisto48q5@4ax.com...
>> Simple(?) program to draw random lines in a rectangle but when I
>> discard all random lines longer than size and graph the results I get
>> a set of diagonal bands. How can random lines have a pattern? Can
>> anyone explain? When I discard a line, I generate a new random line
>> until is it short enough - so how can it not be random?
>> Win XP & VB 2008 Express. Thanks.
>> --------------------------
>> Imports System
>> Imports System.Drawing
>> Imports Microsoft.VisualBasic
>> Imports Microsoft.VisualBasic.VBMath
>> Imports Microsoft.VisualBasic.PowerPacks
>> Public Class Form1
>>    Dim rec As New RectangleShape
>>    Dim arx(5000, 2) As Integer
>>    Dim ary(5000, 2) As Integer
>>    Public Sub New()
>>        InitializeComponent()
>>        Randomize()
>>        Me.rec.Left = 300
>>        Me.rec.Top = 2
>>        Me.rec.Width = 900
>>        Me.rec.Height = 900
>>        For n = 0 To 4999
>>            arx(n, 0) = arx(n, 1) = ary(n, 0) = ary(n, 1) = 0
>>        Next
>>    End Sub
>>    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.PaintEventArgs) Handles Me.Paint
>>        PGr()
>>    End Sub
>>    Private Sub PGr()
>>        Dim e As Graphics
>>        e = Me.CreateGraphics
>>        e.FillRectangle(Brushes.White, rec.Left, rec.Top, rec.Width,
>> rec.Height)
>>        For n = 0 To 4999
>>            e.DrawLine(Pens.Black, rec.Left + arx(n, 0), rec.Top +
>> ary(n, 0), _
>>                       rec.Left + arx(n, 1), rec.Top + ary(n, 1))
>>        Next
>>    End Sub
>>    Private Sub ReP_Click(ByVal sender As Object, ByVal e As
>> System.EventArgs) Handles ReP.Click
>>        Dim Dret As Integer = 0
>>        For n = 0 To 4999
>>            Do
>>                arx(n, 0) = Int(Rnd() * 900)
>>                arx(n, 1) = Int(Rnd() * 900)
>>                ary(n, 0) = Int(Rnd() * 900)
>>                ary(n, 1) = Int(Rnd() * 900)
>>                Dret = Dist(n)
>>            Loop Until Dret = 1
>>        Next
>>        PGr()
>>    End Sub
>>    Private Function Dist(ByVal n As Integer) As Integer
>>        Dim x1, x2, y1, y2, h, h1, h2, size As Double
>>        size = 40
>>        x1 = arx(n, 0)
>>        x2 = arx(n, 1)
>>        h1 = Math.Pow((x1 - x2), 2)
>>        y1 = ary(n, 0)
>>        y2 = ary(n, 1)
>>        h2 = Math.Pow((y1 - y2), 2)
>>        h = h1 + h2
>>        h = Math.Sqrt(h)
>>        If h > size Then Return 0
>>        Return 1
>>    End Function
>>    Private Sub Quit_Click(ByVal sender As Object, ByVal e As
>> System.EventArgs) Handles Quit.Click
>>        End
>>    End Sub
>> End Class
>>
>
>
>I would recommend not using Rnd().  Instead create an instance of Random,
>and use it.  I believe after this change you will see what your are trying
>to get.  So my code looks like the following mods:
>
>public class Form1
>...
>  Dim r as New Random
>...
>  Private Sub ReP_Click(...
>  ...
>    arx(n, 0) = CInt(r.NextDouble() * 900.0)
>    arx(n, 1) = CInt(r.NextDouble() * 900.0)
>    ary(n, 0) = CInt(r.NextDouble() * 900.0)
>    ary(n, 1) = CInt(r.NextDouble() * 900.0)
>  ...
>
>
>I cannot address why Rnd() does what you are seeing, because I don't use
>Rnd().
>
>You also might consider generating point 2 (arx(n,1) and ary(n,1)) by using
>a random distance less than your desired size and a random angle.  This will
>save the loopy logic testing whether your random line works.  Your random
>line generated by using a distance and angle will always be less than the
>desired size.  You would have to check for points off the graphics area of
>course, but that should be an easier check.

As a now casual programmer, I did not know about NextDouble - Thank
you. Yes, I agree that my method is bad resource use but I was just
playing - this time. Anyhow it works - thanks again.
Author
23 Jun 2009 9:35 PM
Dale Atkin
>>I cannot address why Rnd() does what you are seeing, because I don't use
>>Rnd().

I encountered a similar problem many, many years ago mucking around in
QBasic. The problem there was I was running 'randomize timer' on each loop
iteration. Could it be a similar problem (haven't completely disected your
code).

The thing to remember, is there really aren't any 'random' numbers when it
comes to a computer. All random numbers are either the result of a formula
that creates pseudo-random/chaotic results, or 'entropy' gathered from user
input (things like mouse movements, or time between keystrokes etc), which
is then run through a formula.

Dale