branching algorithm on a surface |
DayThree_Branching Algorithm
The Branching Algorithm has been done as a individual assignment, to practice the scripting skills on a project which can be developed also after the workshop.This algorithm consists of three main logical steps :
01. generating Points in the boundary between 4 corners of a subSurface
02. generating a branch by finding the nearest Point from the last nearest Pt found /starting at corners
03. repeating the branching process to a subdivided Surface, generating a unique branching pattern each time the process is run on a subSurface of a Surface
The next steps in further development will be to adapt the branch lengths and threshold value for finding the nearest point individually for each subSurface by applying a surface attractor.
CODE:
import rhinoscriptsyntax as rs
import random as rnd
#definition for finding a random point between two points
def randomPtbetweenTwoPoints (strPt00,strPt01):
vec01 = rs.VectorCreate(strPt01,strPt00)
vec01 = rs.VectorScale(vec01,rnd.random())
vecPt01 = rs.VectorAdd(strPt00,vec01)
return vecPt01
#------------------------------------------------------------------------------
#SURFACE EVALUATION#
strSrf = rs.GetObject("Pick a surface",8)
#strAttractor = rs.GetObject("Pick an attractor",1)
#get srf domains
listDomainU = rs.SurfaceDomain(strSrf,0)
listDomainV = rs.SurfaceDomain(strSrf,1)
#getdomain lengths
Udivision = 10
Vdivision = 10
domainULength = listDomainU[1]-listDomainU[0]
domainVLength = listDomainV[1]-listDomainV[0]
#get domain Tstep
uStep = domainULength/Udivision
vStep = domainVLength/Vdivision
#declaring empty Main and Sub Lists
mainListPt = []
mainListNormal = []
rs.EnableRedraw(False)
#starting to evaluate with loop
for i in rs.frange(listDomainU[0],listDomainU[1]+0.01,uStep):
subListNormal = []
subListPt = []
for j in rs.frange(listDomainV[0],listDomainV[1]+0.01,vStep):
#evaluate surface for Ptcoordinates
PtCoord = rs.EvaluateSurface(strSrf,i,j)
Pt = rs.AddPoint(PtCoord)
#evaluate surface for normals
normal = rs.SurfaceNormal(strSrf,[i,j])
normal = rs.VectorUnitize(normal)
#append the Pts to the subList and the subList to the mainList
subListPt.append(Pt)
mainListPt.append(subListPt)
#------------------------------------------------------------------------------
intIterations = 80
listPtsRandom = []
gen = 16
# running a loop to find the strating corners of each subSurface quad and generating branches
for k in range(0,Udivision):
for l in range (0,Vdivision):
#corners of the quad
strPt00 = mainListPt[k][l]
strPt01 = mainListPt[k+1][l]
strPt02 = mainListPt[k+1][l+1]
strPt03 = mainListPt[k][l+1]
#generating Pts inbetween the four corner of each quad
for i in range(0,intIterations):
PtA = randomPtbetweenTwoPoints(strPt00,strPt01)
PtB = randomPtbetweenTwoPoints(strPt03,strPt02)
ptRandom = randomPtbetweenTwoPoints(PtA,PtB)
listPtsRandom.append(ptRandom)
rs.AddPoints(listPtsRandom)
#generating the branches from each quad corner
listLines = []
ClosestPt = strPt00
ClosestPts = [strPt00,strPt01,strPt02,strPt03]
for i in range(0,gen):
newClosestPts = []
# print "gen", i
for j in range (0,len(ClosestPts)):
# print "point", j
newIndexPt = rs.PointArrayClosestPoint(listPtsRandom,ClosestPts[j])
newClosestPt = listPtsRandom.pop(newIndexPt)
strLine = rs.AddLine(ClosestPts[j],newClosestPt)
listLines.append(strLine)
newClosestPts.append(newClosestPt)
ClosestPts = newClosestPts
strPolyline = rs.JoinCurves(listLines,True)
rs.EnableRedraw(True)
Really nice work Miro!
ReplyDelete