Option Explicit
‘ Script written by maxi@supermanoeuvre.com
‘ draws agent population as a pointCloud object
Call AgentSwarm()
Sub AgentSwarm()
Dim maxTimeSteps : maxTimeSteps = 1000
If isNull(maxTimeSteps) Then Exit Sub
Dim numAgents : numAgents = 25
If isNull(numAgents) Then Exit Sub
Dim envsizeX : envsizeX = 100
Dim envsizeY : envsizeY = 100
Dim envsizeZ : envsizeZ = 100
rhino.Print ” “
rhino.Print “!!! SCRIPT STARTED !!!”
‘ Set and Draw Environment
Call Rhino.ViewDisplayMode(“Perspective”,0)
Call makeEnvironment(envsizeX,envsizeX,envsizeX)
‘——————————————————————————–
‘ MAKE AGENTS
‘Each agent is described as — Array( pos(0), vel(1), maxVel(2), maxForce(3) )
Dim i
Dim arrAgents()
Dim maxVel : maxVel = 0.75
Dim maxForce : maxForce = 0.25
Dim rangeOfVision : rangeOfVision = 20
Dim alignScale : alignScale = 0.8
Dim cohScale : cohScale = 0.5
Dim sepScale : sepScale = 12.0
For i = 0 To numAgents -1
Dim rndStart : rndStart = randomStart(envsizeX,envsizeX,envsizeX)
Dim rndVel : rndVel = randomVelocity()
ReDim Preserve arrAgents(i)
arrAgents(i) = Array( rndStart, rndVel, maxVel, maxForce )
Next
‘——————————————————————————–
‘ ITERATE SIMULATION
Dim j,k
Dim currAgent, otherAgent
Dim swarmCloud
swarmCloud = Null
For j = 0 To maxTimeSteps-1
rhino.enableRedraw False
‘—————————————————-
‘ UPDATE EACH AGENT’S POSITION
For k = 0 To ubound(arrAgents)
‘ The steering forces
Dim arrAcc, arrNewVel, vecSep, vecCoh, vecAli
‘ Reset acceleration
arrAcc = Array(0,0,0)
‘ Get steering vectors
vecSep = agentSeparate( arrAgents(k), arrAgents, rangeOfVision )
vecCoh = agentCohesion( arrAgents(k), arrAgents, rangeOfVision )
vecAli = agentAlign ( arrAgents(k), arrAgents, rangeOfVision )
‘ Scale steering forces
vecSep = rhino.vectorScale(vecCoh, sepScale)
vecCoh = rhino.vectorScale(vecCoh, cohScale)
vecAli = rhino.vectorScale(vecCoh, alignScale)
‘ Update agents position
arrAcc = rhino.vectorAdd(arrAcc, vecSep)
arrAcc = rhino.vectorAdd(arrAcc, vecCoh)
arrAcc = rhino.vectorAdd(arrAcc, vecAli)
arrNewVel = rhino.VectorAdd( arrAgents(k)(1), arrAcc ) ‘ Add acceleration to velocity
arrNewVel = vectorLimit( arrNewVel, arrAgents(k)(2) ) ‘ Limit velocity
arrAgents(k)(0) = rhino.VectorAdd( arrAgents(k)(0), arrNewVel )
Next
‘—————————————————
‘ DRAW AGENTS
‘ generate array of all agent coords
Dim m
Dim arrPosToroid
ReDim arrAgentPos(-1)
For m = 0 To ubound(arrAgents)
arrPosToroid = borders( arrAgents(m), envsizeX, envsizeY, envsizeZ )
arrAgents(m)(0) = arrPosToroid
ReDim Preserve arrAgentPos(m)
arrAgentPos(m) = arrAgents(m)(0)
Next
If Not isNull(swarmCloud) Then
rhino.deleteObject swarmCloud
End If
swarmCloud = Rhino.AddPointCloud(arrAgentPos)
Rhino.EnableRedraw True
rhino.Print “Current time step is : ” & j+1
Next
rhino.Print “!!! SCRIPT COMPLETE !!!”
End Sub
Function borders(AGENT, XX, YY, ZZ)
borders = Null
Dim newX, newY, newZ
‘ Solve for X coordinate
If AGENT(0)(0) XX Then
newX = 0
Else
newX = AGENT(0)(0)
End If
‘ Solve for X coordinate
If AGENT(0)(1) XX Then
newY = 0
Else
newY = AGENT(0)(1)
End If
‘ Solve for X coordinate
If AGENT(0)(2) ZZ Then
newZ = 0
Else
newZ = AGENT(0)(2)
End If
borders = Array(newX, newY, newZ)
End Function
‘ Draws a box the size of the defined environemnt
Function makeEnvironment(XX,YY,ZZ)
makeEnvironment = Null
Dim arrCnrs(7)
arrCnrs(0) = Array(0,0,0)
arrCnrs(1) = Array(XX,0,0)
arrCnrs(2) = Array(XX,YY,0)
arrCnrs(3) = Array(0,YY,0)
arrCnrs(4) = Array(0,0,ZZ)
arrCnrs(5) = Array(XX,0,ZZ)
arrCnrs(6) = Array(XX,YY,ZZ)
arrCnrs(7) = Array(0,YY,ZZ)
rhino.addBox arrCnrs
End Function
Function randomStart(envX, envY, envZ)
randomStart = Null
Dim arrVec : arrVec = Array( rnd*envX, rnd*envY, rnd*envZ )
randomStart = arrVec
End Function
Function randomVelocity()
randomVelocity = Null
Dim i
ReDim switch(2)
For i = 0 To 2
Dim rndNum : rndNum = rnd*1
ReDim Preserve switch(i)
If rndNum > 0.5 Then
switch(i) = 1
Else
switch(i) = -1
End If
Next
randomVelocity = Array( switch(0)*(rnd*1), switch(1)*(rnd*1), switch(2)*(rnd*1) )
End Function
Function vectorLimit(V1, LIMIT)
vectorLimit = Null
Dim arrVec
Dim dblLength : dblLength = Rhino.VectorLength(V1)
If dblLength > LIMIT Then
arrVec = rhino.VectorUnitize(V1)
vectorLimit = rhino.VectorScale(arrVec, LIMIT)
Else
vectorLimit = V1
End If
End Function
Function printAgent(AGENT)
Dim i
For i = 0 To ubound(AGENT)
If i = 0 Then rhino.print “position ” & pt2str(AGENT(0))
If i = 1 Then rhino.print “velocity ” & pt2str(AGENT(1))
If i = 2 Then rhino.print “maximum velocity is ” & AGENT(2)
If i = 3 Then rhino.print “maximum force is ” & AGENT(3)
Next
End Function
Function steer( AGENT, TARGET, RNG )
steer = Null
Dim vec2Target, dblLength, vecSteer
vec2Target = Rhino.VectorSubtract( AGENT(0), TARGET )
dblLength = Rhino.VectorLength( vec2Target )
If dblLength > 0 And dblLength 0 And dblDist 0 Then
Dim steerForce ‘ the lateral steering force to apply
arrSum = rhino.vectorDivide(arrSum, counter)
steerForce = steer( AGENT, arrSum, RNG )
agentCohesion = steerForce
Else
agentCohesion = arrSum
End If
End Function
Function agentSeparate( AGENT, POP, RNG )
‘ Separate works by applying a negative steering force to the average position of an agents neighbours
‘ sum of all positions / number of agents
agentSeparate = Null
Dim i, dblDist, counter
Dim arrSum : arrSum = Array(0,0,0)
Dim sepVec
counter = 0
For i = 0 To ubound(POP)
dblDist = rhino.Distance( AGENT(0), POP(i)(0) )
If dblDist > 0 And dblDist 0 Then
arrSum = rhino.vectorDivide(arrSum, counter)
arrSum = vectorLimit(arrSum, AGENT(3))
End If
agentSeparate = arrSum
End Function
Function agentAlign( AGENT, POP, RNG )
‘ Align works by averaging the headings of all neighbouring agents
‘ sum of all velocities / number of agents
agentAlign = Null
Dim i, dblDist, counter
Dim arrSum : arrSum = Array(0,0,0)
counter = 0
For i = 0 To ubound(POP)
dblDist = rhino.Distance( AGENT(0), POP(i)(0) )
If dblDist > 0 And dblDist 0 Then
arrSum = rhino.vectorDivide(arrSum, counter)
arrSum = vectorLimit(arrSum, AGENT(3))
End If
agentAlign = arrSum
End Function