Option Explicit
'script written by <the sum-things>
'agent-based growing geometry-script for RouseDetroit

Call Main()
Sub Main()

Dim startAgents,startPt,endPt,i,boxPtArr,prevBoxPtArr,n,attractors,maxVel,maxForce,threshold,arrSrf
Dim vel,vec
Dim j,iterations,area

startAgents = Rhino.GetObjects ("get start agents",4)
arrSrf = Rhino.GetObject ("get surface",8)
area = Rhino.SurfaceArea (arrSrf)
iterations = Int (area(0)/400)
'iterations = 35
Rhino.Print iterations
threshold = 50
maxForce = 0.2

'Rhino.AddLayer "boxes", RGB (0,0,255)
'Rhino.AddLayer "pipes", RGB (0,0,255)

Rhino.EnableReDraw False

For i = 0 To Ubound(startAgents)
ReDim Preserve arrAgents(i)

startPt = Rhino.CurveStartPoint(startAgents(i))
endPt = Rhino.CurveEndPoint(startAgents(i))
maxVel = Rhino.Distance (startPt,endPt)
vel = Rhino.VectorCreate(endPt, startPt)
vec = Rhino.VectorCreate (Array(0,0,1),Array(0,0,0))

arrAgents(i) = Array(startPt,vel,endPt,maxVel*2,maxForce,vec)

Next

ReDim prevBoxPtArr (Ubound(arrAgents))

For i = 0 To iterations-1
n = 0
For j = 0 To UBound(arrAgents)

Dim vecAcc,vecVel,vecAtt,vecCoh, vecSep,vecRepel

vecAcc = Array(0,0,0)

' call vector function - behaviors: align, cohesion etc
vecCoh = aCohesion(arrAgents(j), arrAgents)
vecSep = aSeparate(arrAgents(j), arrAgents)

vecCoh = Rhino.VectorScale(vecCoh, 1.1)
vecSep = Rhino.VectorScale(vecSep, 1.2)

' add each vector to acc
vecAcc = Rhino.VectorAdd(vecAcc, vecCoh)
vecAcc = Rhino.VectorAdd(vecAcc, vecSep)

' add acc to vel
vecVel = Rhino.VectorAdd(vecAcc, arrAgents(j)(1)) ''''previous vel + acc

' limit vel to max speed
vecVel = vectorLimit(vecVel, maxVel)

'-------------------------------------------
'-------------------------------------------

'get box points of current agent
boxPtArr = boxPoints (arrAgents(j))

If i > 0 Then
ReDim Preserve boxArr(n)
'call addbox function
'current agent box points + last agent box points
boxArr(n) = addBox (prevBoxPtArr(j),boxPtArr)
n = n + 1
End If

prevBoxPtArr(j) = boxPtArr

'-------------------------------------------
'-------------------------------------------

'add line
'Rhino.AddLine arrAgents(j)(0), Rhino.VectorAdd(arrAgents(j)(0), vecVel)

' update the arrAgent - set the new pos + vel
arrAgents(j)(0) = Rhino.VectorAdd(arrAgents(j)(0), vecVel) '''add pos + vel
arrAgents(j)(1) = vecVel
arrAgents(j)(2) = Rhino.VectorAdd(arrAgents(j)(2), vecVel)
arrAgents(j)(5) = prevBoxPtArr(j)(4)

Next

'add box deform function
If i > 0 Then
'call deform function
adhesion boxArr,threshold

Dim box,k,pt
For j = 0 To Ubound (boxArr)
box = Rhino.AddBox (Rhino.BoundingBox (boxArr(j)))
ReDim Preserve boxPtArr(j)
pt = Rhino.SurfaceVolumeCentroid (box)
boxPtArr(j) = pt(0)
Rhino.DeleteObject box
Next

For k = 0 To Ubound(boxPtArr)
pipe boxPtArr(k),boxPtArr,2
Next

Rhino.DeleteObjects boxArr

End If

Next

Rhino.Command "_SelDup"
Rhino.Command "_SelPt"
Rhino.Command "_Delete"

Rhino.EnableReDraw True

End Sub

Function vectorLimit(vec, maxVel)

Dim length

length = Rhino.VectorLength(vec)

If length > maxVel Then
vec = Rhino.VectorUnitize(vec)
vec = Rhino.VectorScale(vec, maxVel)
vectorLimit = vec
Else
vectorLimit = vec
End If

End Function

Function aCohesion(agent, arrAgents)

Dim sum, count, i, dist, maxForce

sum = Array(0,0,0)
maxForce = agent(4)
' loop through all the agents
count = 0
For i = 0 To UBound(arrAgents)

dist = Rhino.Distance(agent(0), arrAgents(i)(0))
' if the agent is within a threshold distance
If dist < 50 And dist > 10 Then
' add together positions - sum
sum = Rhino.VectorAdd(sum, arrAgents(i)(0))
count = count + 1
End If
Next

' divide the sum vector by the number of agents
If count > 0 Then
sum = Rhino.VectorDivide(sum, count)
' create a new vector towards that pos
sum = Rhino.VectorCreate(sum, agent(0))
' limit the vector
sum = vectorLimit(sum, maxForce)
End If

' return the vector
aCohesion = sum

End Function

Function aSeparate(agent, arrAgents)

Dim sum, count, i, dist, sepVec, maxForce,vec
sum = Array (0,0,0)
vec = Rhino.VectorCreate (Array(0,0,1),Array(0,0,0))
maxForce = agent(4)
' loop through all the agents
count = 0
For i = 0 To UBound(arrAgents)
' check if the agent is within the threshold
dist = Rhino.Distance(agent(0), arrAgents(i)(0))
If dist < 20 And dist > 0 Then
' get the vector between the two agents and add it to sum
sepVec = Rhino.VectorCreate(agent(0), arrAgents(i)(0))
sepVec = Rhino.VectorScale(sepVec, 1/dist)
sum = Rhino.VectorAdd(sum, sepVec)
count = count + 1
End If

Next

' divide sum by the number of neighbors
If count > 0 Then
sum = Rhino.VectorDivide(sum, count)
sum = Rhino.VectorAdd(sum, vec)
' limit sum
'sum = vectorLimit(sum, maxForce)
End If

' return the vector
aSeparate = sum

End Function

Function aAttractor(agent, arrAtt)

Dim vec,vec1, dist, attInd, maxForce, maxAngle
maxForce = agent(4)
vec = Array(0,0,0)

' get closest attractor
attInd = Rhino.PointArrayClosestPoint(arrAtt, agent(0))

' get distance
dist = Rhino.Distance(agent(0), arrAtt(attInd))
maxAngle = 50
' if the distance is within a threshold return a vector
If dist < 25 Then
vec = Rhino.VectorCreate(arrAtt(attInd), agent(0))
'vec1 = Rhino.VectorScale (vec,5)
vec = vectorLimit(vec, maxForce)
End If

aAttractor = vec

End Function

Function boxPoints(arrAgents)

Dim yVec,zVec,vec1,vec2
Dim boxArr(4),length,scale,i

'agent array numbers:
''arrAgents(i) = Array(startPt,vel,endPt,maxVel,maxForce,vec)

length = Rhino.VectorLength (arrAgents(1))
scale = length/2

vec1 = Rhino.VectorRotate (arrAgents(1),-90, arrAgents(5))
vec2 = Rhino.VectorUnitize (vec1)
yVec = Rhino.VectorScale(vec2, scale)

'zVec = arrAgents(5)
vec1 = Rhino.VectorRotate (arrAgents(1),90, yVec)
vec2 = Rhino.VectorUnitize (vec1)
zVec = Rhino.VectorScale(vec2, scale)

boxArr(0) = Rhino.VectorAdd (arrAgents(2),yVec)

yVec = Rhino.VectorReverse (yVec)

boxArr(1) = Rhino.VectorAdd (arrAgents(2),yVec)

boxArr(2) = Rhino.VectorAdd (boxArr(0),zVec)

boxArr(3) = Rhino.VectorAdd (boxArr(1),zVec)

boxArr(4) = zVec

' For i = 0 To Ubound (boxArr)
' Rhino.AddPoint boxArr(i)
' Next

boxPoints = boxArr

End Function

Function addBox (prevBoxPtArr,boxPtArr)

Dim i,arrSrf(3),srfArr(3),box

'Define the points for each of the 4 surfaces
arrSrf(0) = Array(prevBoxPtArr(0),prevBoxPtArr(1),boxPtArr(1),boxPtArr(0))
arrSrf(1) = Array(prevBoxPtArr(1),prevBoxPtArr(3),boxPtArr(3),boxPtArr(1))
arrSrf(2) = Array(prevBoxPtArr(2),prevBoxPtArr(3),boxPtArr(3),boxPtArr(2))
arrSrf(3) = Array(prevBoxPtArr(2),prevBoxPtArr(0),boxPtArr(0),boxPtArr(2))

srfArr(0) = Rhino.AddSrfPt (arrSrf(0))
srfArr(1) = Rhino.AddSrfPt (arrSrf(1))
srfArr(2) = Rhino.AddSrfPt (arrSrf(2))
srfArr(3) = Rhino.AddSrfPt (arrSrf(3))

box = Rhino.JoinSurfaces (srfArr,True)

ReDim arrCorners(7)
arrCorners(0) = prevBoxPtArr(0)
arrCorners(1) = prevBoxPtArr(1)
arrCorners(2) = boxPtArr(1)
arrCorners(3) = boxPtArr(0)
arrCorners(4) = prevBoxPtArr(2)
arrCorners(5) = prevBoxPtArr(3)
arrCorners(6) = boxPtArr(3)
arrCorners(7) = boxPtArr(2)

Rhino.ObjectLayer Rhino.AddBox (arrCorners), "boxes"

addBox = box

End Function

Function adhesion(boxArr,threshold)

Dim i,j,box,boxPt,neighbourbox,neighbourPt
Dim dist,testdist,count,index
Dim crvArr(1)

For i = 0 To Ubound (boxArr)

box = Rhino.AddBox (Rhino.BoundingBox (boxArr(i)))
boxPt = Rhino.SurfaceVolumeCentroid (box)
Rhino.DeleteObject box

count = 0
For j = 0 To Ubound(boxArr)

neighbourbox = Rhino.AddBox (Rhino.BoundingBox (boxArr(j)))
neighbourPt = Rhino.SurfaceVolumeCentroid (neighbourbox)
Rhino.DeleteObject neighbourbox

dist = Rhino.Distance (boxPt(0), neighbourPt(0))

If dist > 0.01 Then
ReDim Preserve testArr(count)
ReDim Preserve testBoxArr(count)
testArr(count) = neighbourPt(0)
testBoxArr(count) = boxArr(j)
count = count + 1
End If

Next

index = Rhino.PointArrayClosestPoint (testArr,boxPt(0))

dist = Rhino.Distance (testArr(index), boxPt(0))

If dist < threshold Then

ReDim arrSrf1(3)
ReDim arrSrf2(3)
ReDim srfPtArr1(3)
ReDim srfPtArr2(3)
ReDim loftSrf(1)
Dim srfArr1,srfArr2,boxPt2,index1,index2,ptArr1,ptArr2,angle,k

srfArr1 = Rhino.ExplodePolysurfaces (boxArr(i), False)
arrSrf1(0) = srfArr1(0)
arrSrf1(1) = srfArr1(1)
arrSrf1(2) = srfArr1(2)
arrSrf1(3) = srfArr1(3)
srfPtArr1(0) = Rhino.PointCoordinates(Rhino.AddPoint(Rhino.SurfaceAreaCentroid (arrSrf1(0))(0)))
srfPtArr1(1) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf1(1))(0)))
srfPtArr1(2) = Rhino.PointCoordinates(Rhino.AddPoint(Rhino.SurfaceAreaCentroid (arrSrf1(2))(0)))
srfPtArr1(3) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf1(3))(0)))


srfArr2 = Rhino.ExplodePolysurfaces (testBoxArr(index), False)
arrSrf2(0) = srfArr2(0)
arrSrf2(1) = srfArr2(1)
arrSrf2(2) = srfArr2(2)
arrSrf2(3) = srfArr2(3)
srfPtArr2(0) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf2(0))(0)))
srfPtArr2(1) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf2(1))(0)))
srfPtArr2(2) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf2(2))(0)))
srfPtArr2(3) = Rhino.PointCoordinates(Rhino.AddPoint( Rhino.SurfaceAreaCentroid (arrSrf2(3))(0)))

index1 = Rhino.PointArrayClosestPoint (srfPtArr1,testArr(index))
index2 = Rhino.PointArrayClosestPoint (srfPtArr2,boxPt(0))

loftSrf(0) = Rhino.CopyObject (arrSrf1(index1))
loftSrf(1) = Rhino.CopyObject (arrSrf2(index2))

Rhino.DeleteObjects arrSrf1
Rhino.DeleteObjects arrSrf2

ptArr1 = Rhino.SurfacePoints (loftSrf(0))
ptArr2 = Rhino.SurfacePoints (loftSrf(1))

angle = vectorAngle (ptArr1,ptArr2)

If index1 = 0 And index2 = 0 Then

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(0))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(1))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(3))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(2))

Else

If index1 = 2 And index2 = 2 Then

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(0))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(1))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(3))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(2))

Else

If index1 = 0 And index2 = 2 Then

' For k = 0 To Ubound(ptArr1)
' Rhino.AddTextDot "pt" & k , ptArr1(k)
' Next

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(2))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(3))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(1))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(0))

Else

If index1 = 2 And index2 = 0 Then

' For k = 0 To Ubound(ptArr1)
' Rhino.AddTextDot "pt" & k , ptArr1(k)
' Next

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(2))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(3))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(1))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(0))

Else

If angle > 90 Then

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(3))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(2))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(0))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(1))

Else

ReDim vec(3)

vec(0) = Rhino.AddLine (ptArr1(2),ptArr2(0))

vec(1) = Rhino.AddLine (ptArr1(3),ptArr2(1))

vec(2) = Rhino.AddLine (ptArr1(1),ptArr2(3))

vec(3) = Rhino.AddLine (ptArr1(0),ptArr2(2))

End If

End If

End If

End If

End If

ReDim arrCorners(7)
arrCorners(0) = ptArr1(2)
arrCorners(1) = ptArr1(3)
arrCorners(2) = ptArr1(1)
arrCorners(3) = ptArr1(0)
arrCorners(4) = Rhino.CurveMidPoint (vec(0))
arrCorners(5) = Rhino.CurveMidPoint (vec(1))
arrCorners(6) = Rhino.CurveMidPoint (vec(2))
arrCorners(7) = Rhino.CurveMidPoint (vec(3))

Rhino.ObjectLayer Rhino.AddBox (arrCorners), "boxes"

Rhino.DeleteObjects loftSrf
Rhino.DeleteObjects vec

End If

Next

End Function

Function vectorAngle (ptArr1,ptArr2)

Dim crv(1),angle

angle = Rhino.Angle2 (Array (ptArr1(0),ptArr1(1)), Array (ptArr2(0),ptArr2(1)))

vectorAngle = angle(0)

End Function

Function pipe (boxPt,boxPtArr,iterations)

If iterations > 0 Then

Dim i,j,n,dist,index,testdist,crv

n = 0

For j = 0 To Ubound(boxPtArr)

dist = Rhino.Distance (boxPt,boxPtArr(j))

If dist > 0 Then
ReDim Preserve testArr(n)
testArr(n) = boxPtArr(j)
n = n + 1
End If

Next

index = Rhino.PointArrayClosestPoint (testArr,boxPt)
Rhino.AddLine boxPt,testArr(index)
crv = Rhino.FirstObject
Rhino.ObjectLayer crv, "pipes"

dist = Rhino.CurveLength (crv)

n = 0

For j = 0 To Ubound(testArr)

testdist = Rhino.Distance (boxPt,testArr(j))

If testdist > dist Then
ReDim Preserve newPtArr(n)
newPtArr(n) = testArr(j)
n = n + 1
End If

Next

pipe boxPt,newPtArr,iterations-1

End If

End Function

 

Option Explicit
'Script written by <the sum-things>
'RouseDetroit: agent-based site-subdivision curvenetwork

Call Main()
Sub Main()

Dim arrPts,i,j,dist,divisions,pointThreshold,curveThreshold,scalefactor,repelThreshold,border,crvDegree,crv,arrCCX

Rhino.LayerLocked "border",False

arrPts = Rhino.GetObjects ("select points",1)
border = Rhino.GetObjects ("select border",4)
divisions = 5
pointThreshold = 500
curveThreshold = 100
repelThreshold = 20
scalefactor = .8
crvDegree = 3

Rhino.AddLayer "curves",RGB (0,255,0)

Rhino.EnableRedraw False

For i = 0 To Ubound(arrPts)
ReDim Preserve ptArr(i)
ptArr(i) = Rhino.PointCoordinates (arrPts(i))
Next

For i = 0 To Ubound(ptArr)

For j = 0 To Ubound(ptArr)

dist = Rhino.Distance (ptArr(i),ptArr(j))

If dist > 0 And dist < pointThreshold Then
crv = Rhino.AddLine (ptArr(i),ptArr(j))

arrCCX = Rhino.CurveCurveIntersection(crv, border(0))

If IsArray(arrCCX) Then

Rhino.Print "Selected curves intersect."

Rhino.DeleteObject crv

End If


End If

Next

Next

Rhino.Command "_seldup"
Rhino.Command "_delete"

Rhino.EnableRedraw True

Dim arrLines,arrCrvPts,vec,vecMove,vecAcc,vecAtt,vecRepel,vecVel,k,arrAtt(),midpt1,midpt2,count,m

Rhino.LayerLocked "border",True

arrLines = Rhino.GetObjects ("select curves",4)

Rhino.LayerLocked "border",False

Rhino.EnableRedraw False

For i = 0 To Ubound(arrLines)

midpt1 = Rhino.CurveMidPoint (arrLines(i))

count = 0

For m = 0 To Ubound(arrLines)
midpt2 = Rhino.CurveMidPoint (arrLines(m))
dist = Rhino.Distance (midpt1,midpt2)

If dist > 0 Then
ReDim Preserve arrAtt(count)
arrAtt(count) = midpt2
count = count + 1
End If

Next

arrCrvPts = Rhino.DivideCurve (arrLines(i), divisions)

For j = 1 To Ubound(arrCrvPts)-1

vecAcc = Array(0,0,0)

vecAtt = attractor(arrCrvPts(j),arrAtt,curveThreshold,scalefactor)
vecRepel = repel (arrCrvPts(j),border,repelThreshold,scalefactor)

vecAcc = Rhino.VectorAdd(vecAcc, vecAtt)
vecAcc = Rhino.VectorAdd(vecAcc, vecRepel)

vecVel = Rhino.VectorAdd(arrCrvPts(j),vecAcc)

arrCrvPts(j) = vecVel

Next

crv = Rhino.AddCurve (arrCrvPts,crvDegree)
Rhino.ObjectLayer crv, "curves"

Next

Rhino.EnableRedraw True

End Sub

Function attractor(pt,attractors,threshold,scalefactor)

Dim index,dist,vec,vecMove

vecMove = Array(0,0,0)

index = Rhino.PointArrayClosestPoint (attractors, pt)
dist = Rhino.Distance (attractors(index),pt)

If dist < threshold Then

vec = Rhino.VectorCreate (attractors(index), pt)
vecMove = Rhino.VectorScale (vec,scalefactor)

End If

attractor = vecMove

End Function

Function repel (pt,border,threshold,scalefactor)

Dim crvUV,crvPt,dist,vec,vecMove

vecMove = Array(0,0,0)

crvUV = Rhino.CurveClosestPoint (border(0), pt)
crvPt = Rhino.EvaluateCurve(border(0), crvUV)

dist = Rhino.Distance (crvPt,pt)



If dist < threshold Then
Rhino.AddLine crvPt,pt
vec = Rhino.VectorCreate (pt,crvPt)
vecMove = Rhino.VectorScale (vec,scalefactor)

End If

repel = vecMove

End Function

 


<<<

swarm detroit!

_who: thomas t. jensen, david o. wolthers_where: the sum-things_when: 2009_what: the sum-things propose an urban redevelopment in detroit, mi, based on an intention of re-introducing the notion of neighborhood. cities that are split up into large, mono-functional areas, such as Detroit, tend to rely heavily on mobile infrastructure to connect these areas. People in such cities travel by car throughout their city and the sidewalks are deserted. Sidewalks, in turn, are important public spaces where the inhabitants of a city are presented to their context, both sociologically and physically.

in generating the emergence of a neighborhood, Swarm Detroit! utilizes a swarm logic derived from multi-agent based systems such as bird flocking and fish schooling. The resultant morphological configuration of the site is emergent but based on specific behavioral rules inherent to the system. a color-coding analysis of the emergent structures on site represents the differentiated and diverse spatial and functional qualities within the neighborhood. The color-coding is based on the parameters: distance to motorway, distance to site border and distance from ground.