"Random" numbers cause pattern?

  • Thread starter Thread starter AW
  • Start date Start date
A

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
 
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.
 
in message news:[email protected]...


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.
 
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
 
Back
Top