(n)certainties

GSAPP-Fall 2012

(n)certainties header image 3

no ‘heimat’ for you

“””
##########################################################
script written by matthew miller, pablo costa & ezio blasetti
script version Dec. 4, 2012
#########################################################
“””

import rhinoscriptsyntax as rs
import random

class dlaPt():

def __init__(self, POS, GUID):
self.pos = POS
self.id = GUID
self.fertile = True

def aggregate(self, howMany, howFar, otherDlaPts, attractors, percentBack, minLength):
if self.fertile:
newDlaPts = []
for i in range(howMany):
crvPts = []
crvPts.append(self.pos)
#randomize
x = random.random()-0.5
y = random.random()-0.5
z = random.random()-0.5
#make the random vector
vec = rs.VectorUnitize([x,y,z])
rnd = random.random()
#adjust it to the attractors
adjValue = self.attractor(self.pos, attractors, howFar+2)
#scale it to how far
vec = rs.VectorScale(vec, howFar*adjValue)
#add it to the coordinate of your pos
newPos = rs.PointAdd(self.pos,vec)
crvPts.append(newPos)
#randomize again
x2 = random.uniform(-rs.VectorLength(vec)/6,rs.VectorLength(vec)/6)
y2 = random.uniform(-rs.VectorLength(vec)/6,rs.VectorLength(vec)/3)
z2 = random.uniform(-rs.VectorLength(vec)/6,rs.VectorLength(vec)/3)
newPos4Crv = rs.PointAdd(newPos,[x2,y2,z2])

crvPts.append(newPos4Crv)
#make the point in rhino
newID = rs.AddPoint(newPos)
#make a line between you and the new random point
if rs.VectorLength (vec) > minLength:
crv = rs.AddCurve(crvPts)
#find the closest other point in the aggregation
domain = rs.CurveDomain(crv)
substr = domain[1]-domain[0]
uni = random.uniform(0,substr)
t = domain[0]+uni
backPos = rs.EvaluateCurve(crv,t)
backID = rs.AddPoint(backPos)
otherPtCoords = []
for otherPt in otherDlaPts:
if otherPt.pos != self.pos:
otherPtCoords.append(otherPt.pos)
index = rs.PointArrayClosestPoint(otherPtCoords, backPos)
#caclulate the distance between the new point and the closest other point
distance = rs.Distance(backPos, otherPtCoords[index])
if distance < howFar :
pts4OtherCrv = []
pts4OtherCrv.append(backPos)
#randomize again
x3 = random.uniform(-howFar/6,howFar/6)
y3 = random.uniform(-howFar/6,howFar/6)
z3 = random.uniform(-howFar/6,howFar/6)
pts4OtherCrv.append(rs.PointAdd(backPos,[x3,y3,z3]))
pts4OtherCrv.append(otherPtCoords[index])
rs.AddCurve(pts4OtherCrv)
rs.DeleteObject(newID)
newDlaPts.append( dlaPt (backPos , backID) )
self.fertile = False
return newDlaPts
else:
return “empty”

def attractor(self, endPt, attrs, thres):
# Define a new array of Attractors’ Coordinates from the Attractors’ Identifiers
attrCoords = attrs
# Calculate the closest Attractor to the Test Point
closestAttrIndex = rs.PointArrayClosestPoint(attrCoords, endPt)
closestAttr = attrCoords[closestAttrIndex]
# Calculate the Distance between the Test Point and its closest Attractor
dist = rs.Distance(endPt, closestAttr)
# Calculate the Adjustment Amount:
# If the Distance is less than the Threshold Then
if dist<thres:
#The Adjustment Amount will be 1 – ( ( Threshold – Distance ) / Threshold )
return 1-((thres-dist)/thres)
#Else
else:
#The Adjustment Amount will be 1
return 1
# End If
# End Function

def Main():

#get some points to make the lda starting points
ptGUIDs = rs.GetObjects(“select some points”, rs.filter.point)
attractorGUIDs = rs.GetObjects(“select the attractors”, rs.filter.point)
percentBack = rs.GetReal(“how much back in percent 0-1”, 0.2,0,1)
minLength = rs.GetReal(“minimum length for curves”, 0.2)
attractors = []
for attrGUID in attractorGUIDs:
attractors.append(rs.PointCoordinates(attrGUID))
myDlaPts = []
for ptGUID in ptGUIDs:
coord = rs.PointCoordinates(ptGUID)
index = rs.PointArrayClosestPoint(attractors,coord)
dist = rs.Distance(coord, attractors[index])
myDlaPts.append( dlaPt(coord, ptGUID) )

for i in range(5):
newDlaPts = []
for myDlaPt in myDlaPts:
#default recursive amount, default length
tempList = myDlaPt.aggregate(2, 15, myDlaPts, attractors, percentBack, minLength)

if tempList != “empty”:
newDlaPts.extend( tempList )
myDlaPts.extend(newDlaPts)

Main()