Anqi, Huijuan, Jinyang, Fangzhen
From KokkugiaWiki
project development
This time we examine how the particles affect the field,
as showing in the diagrams.
The rules are dead agents will divert the field surround them,
providing more void for them;
while moving agents will modify part of the field into the same direction with them.
One of the architectural possibilities is that layers of field provide layers of space for
some events or activities.
When moving agents get to a certain density and become the dead agent,
the field will be consequently changed to offer more space available.
Moving agents also will show the tendency of occupying the space in some direction.
Since the agents including moving agents and dead agents will have their own rules
to move through the field and also will be responsive to the field,
the final result will be dynamic and complex.
Also we examine the possibilities of form of those agents separately.
The next step we will combine the field and particles (agents)
to address the interplay between them.
Option Explicit
'Script written by < Anqi Zhang >
'Script copyrighted by < USC >
'Script version 2009年10月16日 20:06:41
Call Main()
Sub Main
'''generate the field
Dim gens, scope, windmouth, windheight,startpoint, windvel, winddir,windheigth,agents,distofagents
Dim startvec,startpts,newpt,vecsca,vec,i,j,k,pts,newpt1,newpts(),newptss(6),count,dist,threshold,m,arragents()
''''user input
Dim startAgents : startAgents = Rhino.GetObjects("select the starting agent vectors",4)
Rhino.AddLayer ("wind field")
Rhino.CurrentLayer ("wind field")
gens=rhino.GetReal("how many generations of wind",10)
startpoint=rhino.GetPoint("select a start point of windfield")
scope=rhino.GetReal("boundary of the wind field",300)
windmouth=5
windheigth=5
windvel=5
winddir=5
threshold=20
' loop through generations to create wind field
startvec=rhino.VectorRotate(array(windvel,0,0),winddir,array(0,0,1))
For j=0 To 6
startpts=rhino.VectorAdd(array(0,j*windmouth,0),startpoint)
'rhino.AddLine startpts,newpt
For k=0 To 3
vecsca=rhino.VectorScale(startvec,(k+1)^0.5)
pts=rhino.VectorAdd(array(0,0,k*windheigth),startpts)
newpt1=rhino.VectorAdd(vecsca,pts)
'rhino.AddPoint newpt1
rhino.AddLine pts,newpt1
ReDim Preserve newpts(k)
newpts(k)=newpt1
Next
newptss(j)=newpts
Next
' the second generation
For i=0 To gens-2
startvec=rhino.VectorScale(startvec,(1+rnd))
startvec=rhino.VectorRotate(startvec,30*sin(10*i),array(0,0,1))
For j=0 To Ubound(newptss)
count=0
For k=0 To Ubound(newpts)
dist=rhino.Distance(newptss(j)(k),startpoint)
If dist<scope Then
vecsca=rhino.VectorScale(startvec,(k+1)^0.5)
newpt1=rhino.VectorAdd(vecsca,newptss(j)(k))
'rhino.AddPoint newpt1
rhino.AddLine newptss(j)(k),newpt1
ReDim Preserve newpts(k)
newpts(count)=newpt1
count=count+1
End If
Next
newptss(j)=newpts
Next
Next
rhino.AddLayer "pointcloud"
rhino.CurrentLayer "pointclound"
'user input - numbers of generations / numbers of iterations
Dim generations : generations = Rhino.GetInteger ("how many generation?",100)
Dim iterations : iterations = Rhino.GetInteger("how many steps/iterations", 20)
'user input - select all the vectors in the field
Dim arrField : arrField = Rhino.ObjectsByLayer ("wind field", True)
'user input - start vector of the agent
Dim maxVel : maxVel= 2
Dim maxForce : maxForce = 0.2
Dim n : n = UBound (startAgents)
'put the agent information in an array
For i = 0 To n
Dim pos : pos = Rhino.CurveStartPoint (startAgents (i))
Dim endPt : endPt = Rhino.CurveEndPoint (startAgents (i))
Dim vel : vel = Rhino.VectorCreate(endPt, pos)
ReDim Preserve arrAgents(i)
arrAgents(i) = Array(pos, vel, maxVel, maxForce)
Next
'save the original state of the agents
Dim arrAgentOriginalState : arrAgentOriginalState = arrAgents
'put the field information in an array
For i = 0 To UBound (arrField)
Dim posField : posField = Rhino.CurveStartPoint ( arrField (i) )
Dim endPtField : endPtField = Rhino.CurveEndPoint ( arrField (i) )
Dim velField : velField = Rhino.VectorCreate(endPtField, posField)
ReDim Preserve arrVecField(i)
arrVecField(i) = Array(velField, posField, maxVel,maxForce)
Next
'loop through generations >>>
Dim x, y, z, arrSediment(),arrAgentPos(),ptCloud
For x=0 To generations - 1
'loop through iterations
For y=0 To iterations - 1
'loop through agent
For z = 0 To UBound(arrAgents)
acc = Array(0,0,0)
Dim vecSediment
'call the functions
Dim vecAli : vecAli = align(arrAgents(z), arrAgents, 10)
Dim vecSep : vecSep = separate(arrAgents(z), arrAgents, 5)
Dim vecCoh : vecCoh = cohesion(arrAgents(z), arrAgents, 10)
Dim vecField : vecField = field (arrAgents(z), arrVecField, 5)
If x > 0 Then
vecSediment = deadagentsimpact( arrSediment, arrAgents(z), 10)
Else vecSediment = array (0,0,0)
End If
'weight - priority
vecAli = Rhino.VectorScale(vecAli, 5)
vecSep = Rhino.VectorScale(vecSep, 1)
vecCoh = Rhino.VectorScale(vecCoh, 1)
vecField = Rhino.VectorScale(vecField, 10)
vecSediment = Rhino.VectorScale(vecSediment, 3)
'update the agents position
Dim acc : acc = array(0,0,0)
acc = Rhino.VectorAdd(acc, vecAli)
acc = Rhino.VectorAdd(acc, vecSep)
acc = Rhino.VectorAdd(acc, vecCoh)
acc = Rhino.VectorAdd(acc, vecField)
acc = Rhino.VectorAdd(acc, vecSediment)
'add acc to vel
vel = Rhino.VectorAdd(arrAgents(z)(1), acc)
'limitvel to maxVel
vel = vectorLimit(vel, arrAgents(z)(2))
'update the array
arrAgents(z)(0) = Rhino.VectorAdd(arrAgents(z)(0), vel)
arrAgents(z)(1) = vel
Next
For z = 0 To n
ReDim Preserve arrAgentPos(z)
arrAgentPos(z) = arrAgents(z)(0)
Next
Rhino.EnableRedraw False
'delet the previous
If y>0 Then
'Rhino.DeleteObject ptCloud
End If
'update the point cloud
ptCloud = Rhino.AddPointCloud(arrAgentPos)
Next
'update the arrSediment
Dim posSediment : posSediment = Rhino.PointCloudPoints (ptCloud)
For i=0 To n
ReDim Preserve arrSediment(n*(x+1))
arrSediment(n*x + i)= posSediment(i)
Next
'update the field >>> call function confusion(in processing...)
Call impactonfield (arrField,arrSediment)
'restore the agent to the original state
For i = 0 To n
arrAgents(i) = arrAgentOriginalState(i)
Next
Next
End Sub
Function vectorLimit(vec,maxLength)
Dim vecLength
vecLength = Rhino.VectorLength(vec)
If vecLength > maxLength Then
'unitize
vec = Rhino.VectorUnitize(vec)
'scale by maxLength
vec = Rhino.VectorScale(vec,maxLength)
End If
vectorLimit = vec
End Function
Function align(agent, arrAgents, rangeOfVis)
Dim j, dist, sumVec, count
sumVec = Array(0,0,0)
count = 0
For j =0 To UBound(arrAgents)
dist = Rhino.Distance(agent(0),arrAgents(j)(0))
If dist<rangeOfVis & dist>0 Then
sumVec = Rhino.VectorAdd(sumVec, arrAgents(j)(1))
count = count + 1
End If
Next
'divide sumVec by the number of vectors in the rangeOfVis
If count>0 Then
sumVec = Rhino.VectorDivide(sumVec, count)
End If
'return the scaled vector
align = sumVec
End Function
Function separate(agent, arrAgents, rangeOfVis)
Dim sumVec, count, vec, dist, j
'defining a blank vector
sumVec = Array(0,0,0)
count = 0
'loop through all the agents
For j = 0 To UBound(arrAgents)
''get the distiance - if less than
dist = Rhino.Distance(agent(0),arrAgents(j)(0))
If dist < rangeOfVis And dist>0 Then
''get a vector from the other agent to the current agent - sum
vec = Rhino.VectorCreate(agent(0),arrAgents(j)(0))
vec = Rhino.VectorScale(vec, 1/dist)
sumVec = Rhino.VectorAdd(sumVec, vec)
count = count +1
End If
Next
'divide by the number of vectors
If count > 0 Then
sumVec = Rhino.VectorDivide(sumVec, count)
End If
separate = sumVec
End Function
Function cohesion(agent, arrAgents, rangeOfVis)
Dim sumVec, count, j, dist
sumVec = Array (0,0,0)
'loop through all the agents
For j = 0 To UBound(arrAgents)
''get the distance to each agent
dist = Rhino.Distance(agent(0),arrAgents(j)(0))
''if distance is within the rangOfVision
If dist< rangeOfVis And dist>0 Then
''sum positions
sumVec = Rhino.VectorAdd(sumVec, arrAgents(j)(0))
count = count +1
End If
Next
'divide sum pos by count
If count > 0 Then
sumVec = Rhino.VectorDivide(sumVec, count)
'create a vector from the agent to the average position
sumVec = Rhino.VectorCreate(sumVec, agent(0))
'limit the vector by maximum force
sumVec = vectorLimit(sumVec, agent(3))
End If
'reture the result
cohesion = sumVec
End Function
Function deadagentsimpact(arrDeadAgents, agent, rangeOfvis)
Dim sumvec,i,dist,vec,arrPtPos
sumvec = array(0,0,0)
For i=0 To Ubound(arrDeadAgents)
'distance between srfagent+the agent
dist = Rhino.Distance (arrDeadAgents(i),agent(0))
If dist < rangeOfvis Then
vec = Rhino.VectorCreate(agent(0),arrDeadAgents(i))
Else
vec = array(0,0,0)
End If
sumvec = Rhino.VectorAdd(sumvec, vec)
Next
'return a vector-sumvec
deadagentsimpact = sumvec
End Function
Function field (agent,arrFieldVector,rangeOfvis)
Dim j, dist, sumVec
sumVec = Array(0,0,0)
For j =0 To UBound(arrFieldVector)
dist = Rhino.Distance(agent(0),arrFieldVector(j)(1))
If dist < rangeOfVis & dist > 0 Then
sumVec = Rhino.VectorAdd(sumVec, arrAgents(j)(0))
End If
'sumvec = Rhino.VectorAdd(sumvec, vec)
Next
field = sumvec
End Function
Function impactonfield(arrField,deadagents)
Dim i,j,dist,startPT,endPT,vel,arrwinds(),vecacc,vec,pos,deadpos
For i=0 To Ubound(arrField)
startPT=rhino.CurveStartPoint(arrField(i))
endPT=rhino.CurveEndPoint(arrField(i))
vel = Rhino.VectorCreate(startPT,endPT)
'rhino.AddPoint startPT
'rhino.AddPoint endPT
ReDim Preserve arrwinds(i)
arrwinds(i)= Array(startPT,vel)
Next
For i=0 To Ubound(arrwinds)
For j=0 To Ubound(deadagents)
dist=rhino.Distance(arrwinds(i)(0),deadagents(j))
If dist<1000 Then
vecacc=rhino.VectorCreate(arrwinds(i)(0),deadagents(j))
'vec=rhino.VectorScale(vecacc,10)
vec=rhino.VectorAdd(arrwinds(i)(1),vecacc)
pos=rhino.vectoradd(arrwinds(i)(0),vec)
'update the new position of windfield
arrwinds(i)(0)=pos
End If
Next
Next
End Function
COMMENTS - NOV 5
it looks as though the logic is mostly resolved in terms of the nature of the interactions between the 3 systems. the critical thing now is to be more specific about the design intent and how you are curating these systems. at the moment the geometry appears to be more of a mapping of the system than the result of its self-organisation. in other words you need to have a coherent relationship between the design intent, the operation of the process and the geometry that is generated. it is not enough to simply accept the outcome of these systems and assume that they will inherently generate useful architectural matter. it is critical that you actually curate the process to draw out geometry that you have a strong authorship of. part of this shift needs to be re-conceptualizing (and renaming) your systems - they need to be the systems of architecture now, they can no longer be considered a simulation of your wind and sand analogy. this involves a more careful consideration of what are the behaviors of the architecture that you are trying to create. and how these behaviors operate in the various agents. obviously this requires you to describe what the agents are and which of them generate geometry and which are involved in the self-organisation process as virtual agents.
additionally i think you should give more consideration to the methodology for generating geometry from the agents. the lofted surfaces of the field begin to become crude when they interesect. however the intersection of the actual field agents might be critical points, consequently i would look at using something like rhino's meshFromPoints command to create a single manifold mesh surface. however be careful to ensure you have a high enough population of points to ensure a decent result - this technique with low populations of points generates very crude surfaces.
COMMENTS DEC 8
It is good to see a variety of explorations in how this feedback system is capable of generating usable geometry. I suggest that you don't get overly concerned with making the project convincing in terms of an architectural project, it can certainly remain at a very proto-architectural level of resolution. It is more crucial at this stage to ensure that the behavior of the feedback system is legible in the geometry it creates.
I think the studies in Field003.jpg are particularly beautiful (notably the ones without the surface and cross members), however it appears to be more of a mapping of trajectories rather than the negotiation of a proto-architectural concern.
It seems from your own comments that you have a strong direction, I would only emphasis that you work towards the result being a cohesive whole which exhibits emergent characteristics as some of your previous studies still isolate the individual element (with a normative tectonic relationship).











