








'Script written by <the sum-things>
Call Main()
Sub Main()
Dim arrSrf,startAgents, attPts, i, iterations, angle, threshold
Dim startPt, endPt, vec, maxVel
startAgents = Rhino.GetObjects ("select start curves", 4)
arrSrf = Rhino.GetObjects ("select surfaces", 8)
iterations = 10
angle = 20
threshold = 15
For i = 0 To Ubound (startAgents)
startPt = Rhino.CurveStartPoint (startAgents(i))
endPt = Rhino.CurveEndPoint (startAgents(i))
vec = Rhino.VectorCreate (endPt, startPt)
maxVel = Rhino.Distance (endPt, startPt)
ReDim Preserve agentArr(i)
agentArr(i) = Array (startPt,vec, maxVel-1,endPt)
Next
Aagregate agentArr, iterations, angle, threshold, arrSrf
Rhino.Command "_SelDup"
Rhino.Command "_Delete"
End Sub
Function Aagregate (agentArr, iterations, angle, threshold, arrSrf)
Dim i, j, vec, vecMove, vecBranch, dist, attIndex, n, arrAxis, line, trajArr, arrTraj, count, pt, crv, newcrv
Dim vecAcc, vecAli, vecSrf, scale
If iterations > 1 Then
iterations = iterations - 1
n = 0
For i = 0 To Ubound (agentArr)
scale = agentArr(i)(2)
count = 0
Rhino.EnableRedraw False
'calculate neighbor distance
For j = 0 To Ubound (agentArr)
dist = Rhino.Distance (agentArr(j)(3), agentArr(i)(3))
If dist > 0.00 Then
ReDim Preserve attArr(count)
pt = Rhino.AddPoint (agentArr(j)(3))
attArr(count) = Rhino.PointCoordinates (pt)
Rhino.DeleteObject pt
count = count + 1
End If
Next
Rhino.EnableRedraw True
If count > 0 Then
attIndex = Rhino.PointArrayClosestPoint (attArr, agentArr(i)(3))
dist = Rhino.Distance (attArr(attIndex), agentArr(i)(3))
arrAxis = Rhino.VectorCreate (attArr(attIndex), agentArr(i)(3))
If dist > threshold Then
'-------------------------------------------------------------------------------------------------------------
vec = Rhino.VectorRotate (agentArr(i)(1), angle, arrAxis)
trajArr = Rhino.ObjectsByType (4)
arrTraj = Atraj (trajArr)
vecBranch = merge (agentArr(i), vec, arrTraj)
If vecBranch(1) = 1 Then
'ReDim Preserve lineArr(n)
line = Rhino.AddLine (agentArr(i)(3), Rhino.VectorAdd (agentArr(i)(3), vecBranch(0)))
ReDim Preserve newAgentArr(n)
newAgentArr(n) = Array (Rhino.CurveStartPoint (line), vecBranch(0), agentArr(i)(2), Rhino.CurveEndPoint (line))
n = n + 1
End If
'-------------------------------------------------------------------------------------------------------------
'-------------------------------------------------------------------------------------------------------------
vec = Rhino.VectorRotate (agentArr(i)(1), -angle, arrAxis)
vecBranch = merge (agentArr(i), vec, arrTraj)
If vecBranch(1) = 1 Then
'ReDim Preserve lineArr(n)
line = Rhino.AddLine (agentArr(i)(3), Rhino.VectorAdd (agentArr(i)(3), vecBranch(0)))
ReDim Preserve newAgentArr(n)
newAgentArr(n) = Array (Rhino.CurveStartPoint (line), vecBranch(0), agentArr(i)(2), Rhino.CurveEndPoint (line))
n = n + 1
End If
'-------------------------------------------------------------------------------------------------------------
Else
'-------------------------------------------------------------------------------------------------------------
trajArr = Rhino.ObjectsByType (4)
arrTraj = Atraj (trajArr)
vecMove = merge (agentArr(i), agentArr(i)(1), arrTraj)
If vecMove(1) = 1 Then
'add functions!
vecAcc = Array(0,0,0)
'vecAli = aAlign (agentArr(i), agentArr)
vecSrf = aSrfRepel(agentArr(i), arrSrf)
'vecAli = Rhino.VectorScale(vecAli, .1)
vecSrf = Rhino.VectorScale(vecSrf, 2)
'vecAcc = Rhino.VectorAdd(vecAcc, vecAli)
vecAcc = Rhino.VectorAdd(vecAcc, vecSrf)
vecMove(0) = Rhino.VectorAdd(vecMove(0), vecAcc)
vec = Rhino.VectorUnitize (vecMove(0))
vec = Rhino.VectorScale (vec, scale+1)
'ReDim Preserve lineArr(n)
line = Rhino.AddLine (agentArr(i)(3), Rhino.VectorAdd (agentArr(i)(3), vec))
ReDim Preserve newAgentArr(n)
newAgentArr(n) = Array (Rhino.CurveStartPoint (line), vec, agentArr(i)(2), Rhino.CurveEndPoint (line))
n = n + 1
End If
'-------------------------------------------------------------------------------------------------------------
End If
End If
Next
End If
If n > 0 Then
For i = 0 To Ubound (newAgentArr)
Aagregate newAgentArr, iterations, angle, threshold, arrSrf
Next
End If
End Function
Function aSrfRepel(agent, arrSrf)
Dim sum, count, i, srfUV, srfPt, dist, srfNormal, maxForce
sum = Array(0,0,0)
'maxForce = agent(3)
' loop srf
count = 0
For i = 0 To UBound(arrSrf)
' get the distance from the agent to closest pt on srf
srfUV = Rhino.SurfaceClosestPoint(arrSrf(i), agent(3))
srfPt = Rhino.EvaluateSurface(arrSrf(i), srfUV)
'Rhino.AddPoint srfPt
dist = Rhino.Distance(agent(3), srfPt)
' if point is closer than x
If dist < 40 Then
srfNormal = Rhino.SurfaceNormal(arrSrf(i), srfUV)
' scale the normal based on distance to agent
'srfNormal = Rhino.VectorUnitize(srfNormal)
'srfNormal = Rhino.VectorScale(srfNormal, (1/(dist)))
' add the normal vector to sum
sum = Rhino.VectorAdd(sum, srfNormal)
count = count + 1
End If
Next
' divide by the number of normals
' If count > 0 Then
' sum = Rhino.VectorDivide(sum, count)
' 'sum = vectorLimit(sum, maxForce)
' End If
' return
aSrfRepel = sum
End Function
Function aAlign(agent, arrAgents)
Dim sum, count, i, dist, maxForce
sum = Array(0,0,0)
'maxForce = agent(2)
' loop through all the agents
count = 0
For i = 0 To UBound(arrAgents)
' check distance from one agent to the other
dist = Rhino.Distance(agent(3), arrAgents(i)(3))
' if dist is less than X then add the vel vec
If dist < 30 And dist > 0 Then
sum = Rhino.VectorAdd(sum, arrAgents(i)(1))
count = count + 1
End If
Next
' divide the sum vector by the number of neighbors
If count > 0 Then
sum = Rhino.VectorDivide(sum, count)
End If
sum = vectorLimit(sum, agent(2))
' return the average vel vector
aAlign = sum
End Function
Function merge (agentArr, vec, arrTraj)
Dim i, dist, n, index, pt, Avec, num, agent,length
length = Rhino.Distance(agentArr(0), agentArr(3))
agent = agentArr(3)
n = 0
For i = 0 To Ubound (arrTraj)
dist = Rhino.Distance (Rhino.VectorAdd (agent, vec), arrTraj(i))
If dist < length-1 Then
ReDim Preserve testArr(n)
testArr(n) = Array (arrTraj(i)(0), arrTraj(i)(1), arrTraj(i)(2))
n = n + 1
End If
Next
If n > 0 Then
index = Rhino.PointArrayClosestPoint (testArr, Rhino.VectorAdd (agent, vec))
Rhino.AddLine testArr(index), agent
Avec = Rhino.VectorCreate (Rhino.VectorAdd (agent, vec), testArr(index))
num = 0
End If
If n = 0 Then
Avec = vec
num = 1
End If
merge = Array (Avec, num)
End Function
Function Atraj (trajArr)
Dim i, color, testColor, n
n = 0
color = RGB (0,0,0)
For i = 0 To Ubound (trajArr)
testColor = Rhino.ObjectColor (trajArr(i))
If testColor = color Then
ReDim Preserve arrTraj (n)
arrTraj (n) = Rhino.CurveEndPoint (trajArr(i))
n = n + 1
End If
Next
Atraj = arrTraj
End Function