RhinoScript recursive attractor hybrid
From KokkugiaWiki
this script hybridizes a simple branching script and a simple attractor script. the attractors effect the scale of the branches.
Option Explicit
'Script written by roland snooks | kokkugia.com | 2008
Call recursiveBranch()
Sub recursiveBranch()
Dim line, ang, scale, attArr, thresholdDistance
line = Rhino.GetObject("select a starting line", 4)
ang = Rhino.GetReal("angle of branches", 15)
scale = Rhino.GetReal("scale amount", 0.9)
attArr = Rhino.GetObjects("select some attractors", 1)
thresholdDistance = Rhino.GetReal("threshold distance", 20)
Rhino.EnableRedraw False
branch line, ang, scale, attArr, thresholdDistance
Rhino.EnableRedraw True
End Sub
Function branch(line, ang, scale, attArr, thresholdDistance)
Dim endPt, startPt, vec, line1, line2, branchLength, adjScale
branchLength = Rhino.CurveLength(line)
If branchLength > 5 Then
' get vector
endPt = Rhino.CurveEndPoint(line)
startPt = Rhino.CurveStartPoint(line)
vec = Rhino.VectorCreate(endPt, startPt)
' call attractors function
adjScale = scale * attractors(attArr, endPt, thresholdDistance) ''' 0-1
' draw new lines
line1 = Rhino.AddLine(endPt, Rhino.VectorAdd(endPt, Rhino.VectorScale(Rhino.VectorRotate(vec, ang, Array(0,0,1)), adjScale)))
line2 = Rhino.AddLine(endPt, Rhino.VectorAdd(endPt, Rhino.VectorScale(Rhino.VectorRotate(vec, -ang, Array(0,0,1)), adjScale)))
' call recursive function
branch line1, ang, scale, attArr, thresholdDistance
branch line2, ang, scale, attArr, thresholdDistance
End If
End Function
Function attractors(attArr, pt, thresholdDistance)
Dim xyzPt, attXYZArr(), i
' loop through attractors - get positions
For i = 0 To UBound(attArr)
xyzPt = Rhino.PointCoordinates(attArr(i))
ReDim Preserve attXYZArr(i)
attXYZArr(i) = xyzPt
Next
Dim centerPtArr, centerPt, closestPtIndex, dist, adjAmount
' find the closest attractor
closestPtIndex = Rhino.PointArrayClosestPoint(attXYZArr, pt)
' get distance to closest att
dist = Rhino.Distance(pt, attXYZArr(closestPtIndex) )
' scale
If dist < thresholdDistance Then
adjAmount = 1 - ( (thresholdDistance - dist) / thresholdDistance )
Else
adjAmount = 1
End If
' return the adjAmount
attractors = adjAmount
End Function

