The concept is easy. A simple L-system start to grown randomly from a seed, and after every generation it try to touch other L-systems, that are growing from different one seed.
[edit]
I forgot to explain some aspects. In this script singles L-system recive a feedback from others, because configuration of every generation depend on configuration of previous one.
Unlike my previous script there isn't only one final perfect configuration, but infinity ones... because every random event of system "A" affects other systems in next generation, thus itself in following one.
[/edit]
Option Explicit
' Script written by Alessandro Zomparelli
' alessandro.zomparelli@gmail.com
' http://alessandrozompa.altervista.org/
' Script version domenica 1 novembre 2009 14.40.18
Call Main()
Sub Main()
'picking seed points
Dim arrSeed, arrSub
ReDim arrSeed(0)
arrSeed(0)=Rhino.GetObjects("pick seed points",1)
'defining number of branch
Dim dblBrN
dblBrN=Rhino.GetInteger("number of branches",2,1)
'defining number of branch generation
Dim dblBranch
dblBranch=Rhino.GetInteger("number of branch generation",3,1)
ReDim Preserve arrSeed(dblBranch)
Dim arrData, dblVote, arrVote
ReDim arrData(dblBranch), arrVote(0)
'defining number of generations and amount of mutation between following generations
Dim dblGen, dblMut, strLine
dblGen=Rhino.GetInteger("set number of generations",100,2,10000)
dblMut=Rhino.GetReal("set mutation value",2,0.1,100)
Call Rhino.EnableRedraw(False)
'starting evolution system
Dim i,j,z,k,y,m,a
Dim dblDis, arrDist, strC1, strC2
ReDim arrDist(0)
'generation of different layers
Dim strL1: strL1="lines"
Call Rhino.AddLayer(strL1)
'evaluation of distance between seed points for a better L-System scale
dblDist=Rhino.Distance(Rhino.PointCoordinates(arrSeed(0)(0)),Rhino.PointCoordinates(arrSeed(0)(1)))
For i=0 To ubound(arrSeed(0))
For j=0 To ubound(arrSeed(0))
If i<>j Then
If Rhino.Distance(Rhino.PointCoordinates(arrSeed(0)(i)),Rhino.PointCoordinates(arrSeed(0)(j)))
arrSeed(i)=arrSub
End If
arrData(i)=arrSub
For j=0 To ubound(arrSeed(i))
arrData(i)(j)=array(0,array(0,0,0),array(0,0,0),dblDis)
Next
Next
For z=0 To dblGen-1
Call Rhino.Print(int(z*100/(dblGen-1))&"%")
For i=1 To dblBranch
'generation of branches
For j=0 To ubound(arrSeed(i-1))
For y=0 To dblBrN-1
'defining vector scattering direction
arrData(i)(j*(dblBrN)+y)(2)=array(arrData(i)(j*(dblBrN)+y)(1)(0)+dblMut*(dblGen-z)/dblGen*(rnd-rnd),arrData(i)(j*(dblBrN)+y)(1)(1)+dblMut*(dblGen-z)/dblGen*(rnd-rnd),arrData(i)(j*(dblBrN)+y)(1)(2)+dblMut*(dblGen-z)/dblGen*(rnd-rnd))
'propotional scaling factor
arrData(i)(j*(dblBrN)+y)(2)=Rhino.VectorUnitize(arrData(i)(j*(dblBrN)+y)(2))
arrData(i)(j*(dblBrN)+y)(2)=Rhino.VectorScale(arrData(i)(j*(dblBrN)+y)(2),arrData(i)(j*(dblBrN)+y)(3)/i/3)
arrSeed(i)(j*(dblBrN)+y)=Rhino.CopyObject(arrSeed(i-1)(j),arrData(i)(j*(dblBrN)+y)(2))
'drawing last generation
If z=dblGen-1 Then
strLine=Rhino.AddLine(Rhino.PointCoordinates(arrSeed(i-1)(j)),Rhino.PointCoordinates(arrSeed(i)(j*(dblBrN)+y)))
Call Rhino.objectlayer(strLine,strL1)
If i=1 Then
strC1=Rhino.AddCircle(Rhino.PlaneFromNormal(Rhino.PointCoordinates(arrSeed(i-1)(j)),arrData(i)(j*(dblBrN)+y)(2)),arrData(i-1)(j)(3)/20/i)
Else
strC1=Rhino.AddCircle(Rhino.PlaneFromNormal(Rhino.PointCoordinates(arrSeed(i-1)(j)),arrData(i)(j*(dblBrN)+y)(2)),arrData(i-1)(j)(3)/40/(i-1))
End If
strC2=Rhino.AddCircle(Rhino.PlaneFromNormal(Rhino.PointCoordinates(arrSeed(i)(j*(dblBrN)+y)),arrData(i)(j*(dblBrN)+y)(2)),arrData(i)(j*(dblBrN)+y)(3)/40/i)
Call Rhino.AddLoftSrf(array(strC1,strC2))
If i=1 Then
Call Rhino.AddSphere(Rhino.PointCoordinates(arrSeed(i-1)(j)),arrData(i-1)(j)(3)/20/i)
'Else
' Call Rhino.AddSphere(Rhino.PointCoordinates(arrSeed(i-1)(j)),arrData(i-1)(j)(3)/30/(i-1))
End If
Call Rhino.AddSphere(Rhino.PointCoordinates(arrSeed(i)(j*(dblBrN)+y)),arrData(i)(j*(dblBrN)+y)(3)/40/i)
Call Rhino.DeleteObjects(array(strC1,strC2))
End If
'for display colors of different generation
'If z/10=int(z/10) Then
' strLine=Rhino.AddLine(Rhino.PointCoordinates(arrSeed(i-1)(j)),Rhino.PointCoordinates(arrSeed(i)(j*2+y)))
' Call Rhino.ObjectColor(strLine, RGB(255-255/dblGen*z,0,255/dblGen*z))
'End If
Next
Next
'recordn data of individual branches
For j=0 To ubound(arrSeed(i-1))
For y=0 To dblBrN-1
a=-1
'defining votes for branches generated from different seeds
For k=0 To ubound(arrSeed(i-1))
If int(k/(dblBrN^(i-1)))<>int(j/(dblBrN^(i-1))) Then
For m=0 To dblBrN-1
a=a+1
ReDim Preserve arrVote(a), arrDis(a+1)
'defining a vote for element efficiency
arrVote(a)=(Rhino.Distance(PointCoordinates(arrSeed(i-1)(j)),Rhino.PointCoordinates(arrSeed(i-1)(k)))-Rhino.Distance(Rhino.PointCoordinates(arrSeed(i)(j*(dblBrN)+y)),Rhino.PointCoordinates(arrSeed(i-1)(k))))
'recording distance from detected points
arrDist(a)=Rhino.Distance(PointCoordinates(arrSeed(i-1)(j)),Rhino.PointCoordinates(arrSeed(i-1)(k)))
Next
End If
Next
dblVote=Rhino.Max(arrVote)
'recording dist for nearest point
For k=0 To ubound(arrVote)
If arrVote(k)=dblVote Then
arrDist(a+1)=arrDist(k)
End If
Next
'recording data about the new element
If dblVote>arrData(i)(j*(dblBrN)+y)(0) Then
arrData(i)(j*(dblBrN)+y)(0)=dblVote
arrData(i)(j*(dblBrN)+y)(1)=arrData(i)(j*(dblBrN)+y)(2)
arrData(i)(j*(dblBrN)+y)(3)=arrDist(a+1)
End If
Next
Next
Next
For i=1 To dblBranch
Call Rhino.DeleteObjects(arrSeed(i))
Next
Next
Call Rhino.LayerVisible(strL1,False)
Call Rhino.EnableRedraw(True)
Call Rhino.Print("100%")
End Sub