See Barnsley's Fern by Eric W. Weisstein from MathWorld, a Wolfram Web Resource.
The program starts from a random point. At each step, it randomly picks a function (with non-uniform probability) and applies the function to the point to find the next point. It then plots that point.
Each function has the form:
X(n+1) = A * X(n) + B * Y(n) + C
Y(n+1) = D * X(n) + E * Y(n) + F
The Form_Load event handler initializes the parameters for each function in the m_Func array, and the probability for each function. It also sets the color to be used when plotting a point found by each function. Using different colors is interesting and gives you some sense of what each set of functions does but the final result here is drawn in green.
|
Private m_Prob(3) As Single
Private m_Func(3, 1, 1) As Single
Private m_Plus(3, 1) As Single
Private m_Clr(3) As Color
Private Sub Form1_Load(ByVal sender As System.Object, ByVal _
e As System.EventArgs) Handles MyBase.Load
' Initialize the fern functions.
m_Clr(0) = Color.Red
m_Prob(0) = 0.01
m_Func(0, 0, 0) = 0
m_Func(0, 0, 1) = 0
m_Func(0, 1, 0) = 0
m_Func(0, 1, 1) = 0.16
m_Plus(0, 0) = 0
m_Plus(0, 1) = 0
m_Clr(1) = Color.Green
m_Prob(1) = 0.85
m_Func(1, 0, 0) = 0.85
m_Func(1, 0, 1) = 0.04
m_Func(1, 1, 0) = -0.04
m_Func(1, 1, 1) = 0.85
m_Plus(1, 0) = 0
m_Plus(1, 1) = 1.6
m_Clr(2) = Color.Blue
m_Prob(2) = 0.08
m_Func(2, 0, 0) = 0.2
m_Func(2, 0, 1) = -0.26
m_Func(2, 0, 1) = -0.23
m_Func(2, 1, 1) = 0.22
m_Plus(2, 0) = 0
m_Plus(2, 1) = 1.6
m_Clr(3) = Color.White
m_Prob(3) = 0.06
m_Func(3, 0, 0) = -0.15
m_Func(3, 0, 1) = 0.28
m_Func(3, 1, 0) = 0.26
m_Func(3, 1, 1) = 0.24
m_Plus(3, 0) = 0
m_Plus(3, 1) = 0.44
m_Clr(0) = Color.Lime
m_Clr(1) = Color.Lime
m_Clr(2) = Color.Lime
m_Clr(3) = Color.Lime
MakeFern()
picCanvas.Invalidate()
End Sub
|
Private m_Bm As Bitmap
Private Sub MakeFern()
m_Bm = New Bitmap(picCanvas.ClientSize.Width, _
picCanvas.ClientSize.Height)
Dim gr As Graphics = Graphics.FromImage(m_Bm)
gr.Clear(picCanvas.BackColor)
Dim rnd As New Random
Dim func_num As Integer
Dim clr As Color
Dim x As Single = 1
Dim y As Single = 1
Dim x1 As Single
Dim y1 As Single
Dim ix As Integer
Dim iy As Integer
For i As Long = 1 To 100000
Dim num As Double = rnd.NextDouble()
For j As Integer = 0 To 3
num = num - m_Prob(j)
If num <= 0 Then
func_num = j
clr = m_Clr(j)
Exit For
End If
Next j
x1 = x * m_Func(func_num, 0, 0) + y * _
m_Func(func_num, 0, 1) + m_Plus(func_num, 0)
y1 = x * m_Func(func_num, 1, 0) + y * _
m_Func(func_num, 1, 1) + m_Plus(func_num, 1)
x = x1
y = y1
Const W_XMIN As Single = -4
Const W_XMAX As Single = 4
Const W_YMIN As Single = -0.1
Const W_YMAX As Single = 10.1
Const W_WID As Single = W_XMAX - W_XMIN
Const W_HGT As Single = W_YMAX - W_YMIN
ix = (x - W_XMIN) / W_WID * _
picCanvas.ClientSize.Width
iy = (picCanvas.ClientSize.Height - 1) - (y - _
W_YMIN) / W_HGT * picCanvas.ClientSize.Height
If ix >= 0 AndAlso iy >= 0 _
AndAlso ix < picCanvas.ClientSize.Width _
AndAlso iy < picCanvas.ClientSize.Height _
Then
m_Bm.SetPixel(ix, iy, clr)
End If
Next i
End Sub
|