'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


<<<

bifurcating morphologies

_who: david o. wolthers_where: the sum-things_when: 2010