Anqi, Huijuan, Jinyang, Fangzhen

From KokkugiaWiki

project development

Image:FieldandParticles_001.jpg Image:FieldandParticles_002.jpg Image:FieldandParticles_003.jpg Image:FieldandParticles_004.jpg Image:FieldandParticles.jpg Image:Field001.jpg Image:Field002.jpg Image:Field003.jpg Image:Field004.jpg Image:Field005.jpg Image:Field006.jpg

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).

Views