



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.