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