
This rhinoscript subdivides triangular surfaces from multiple point attractors. There are two types of subdivision patterns which may be called; one derives from the mid points of each triangle, while the other divides from the quarter points. Both may be called at the sametime, or separately, within the function subdivideTriangle, the triangleLength for i & j may be adjusted for such calls.
Option Explicit
‘Script written by heath west & mark bearak
‘Script version 17 November 2008 13:57:37
Call distanceBasedRecursion()
Sub distanceBasedRecursion()
Dim triangle, fallOffDist, intPts
Dim j, k, strAttractor, strTriangle, arrPt, arrAttractor, testDistance, dblDistance, strCrv, arrCrvs, dblCrvLength, dblCurrentLength
Dim triangleLength, vertexPts, i, centerPt, triangleCrv, srfParam, srfNormal, arrTri, arrAttPt, arrCrvCnt, dblDist
Dim arrtriangle : arrtriangle = Rhino.GetObjects(“select the triangles”,8)
Dim arrStrAttractors : arrStrAttractors = Rhino.GetObjects (“select the points”,1)
Dim arrParameters: arrParameters = array(“Fall Off Distance”)
Dim arrValues: arrValues = array(“2″)
Dim arrResults: arrResults = Rhino.PropertyListBox(arrParameters, arrValues, “Distance Based Recursion” )
If IsArray(arrResults) Then
fallOffDist = arrResults(0)
End If
Call Rhino.enableredraw (False)
ReDim arrAttractors(UBound(arrStrAttractors ))
k=0
For Each strAttractor In arrStrAttractors
arrAttractors(k) = Rhino.PointCoordinates (strAttractor)
k=k+1
Next
For Each strTriangle In arrtriangle
arrPt = Rhino.SurfaceAreaCentroid (strTriangle)
arrCrvs = Rhino.DuplicateSurfaceBorder (strTriangle)
dblCrvLength = 0
For j = 0 To Ubound(arrCrvs)
dblCurrentLength = Rhino.CurveLength (arrCrvs(j))
dblCrvLength = dblCrvLength + dblCurrentLength
Next
dblDistance = fallOffDist
For Each arrAttractor In arrAttractors
testDistance = Rhino.Distance (arrPt(0), arrAttractor)
If testDistance < dblDistance Then
dblDistance = testDistance
End If
Next
arrTri = Rhino.DuplicateSurfaceBorder (strTriangle)
For Each triangleCrv In arrTri
triangleLength = Rhino.CurveLength(triangleCrv)
arrAttPt = Rhino.PointCoordinates(arrStrAttractors(0))
arrCrvCnt = Rhino.CurveAreaCentroid (triangleCrv)
dblDist = Rhino.Distance (arrCrvCnt(0),arrAttPt)
If dblDistance < fallOffDist+0.1 Then
subdivideTriangle(strTriangle)
Else
End If
Next
Next
Rhino.EnableRedraw (True)
End Sub
Function subdivideTriangle(strTriangle)
Dim triangleLength, vertexPts, centerPt, triangleCrv, srfParam, srfNormal, arrTri, nMin, nMax, i, j, fallOffDist
arrTri = Rhino.DuplicateSurfaceBorder (strTriangle)
For Each triangleCrv In arrTri
Dim midpt0, midpt1, midpt2, midpt3, midpt4, midmid3, midmid4, quarterPt0, quarterPt1, quarterPt2, quarterPt3, quarterPt4
Dim triangle0, triangle1, triangle2, triangle3, triangle4, triangle5, triangle6, triangle7
triangleLength = Rhino.CurveLength(triangleCrv)
centerPt = Rhino.CurveAreaCentroid(triangleCrv)
srfParam = Rhino.SurfaceClosestPoint(strTriangle, centerPt(0))
srfNormal = Rhino.SurfaceNormal(strTriangle, srfParam)
vertexPts = Rhino.PolylineVertices(triangleCrv)
midPt0 = Array(((vertexPts(1)(0) + vertexPts(0)(0)))/2, ((vertexPts(1)(1) + vertexPts(0)(1)))/2, ((vertexPts(1)(2) + vertexPts(0)(2)))/2)
midPt1 = Array(((vertexPts(2)(0) + vertexPts(1)(0)))/2, ((vertexPts(2)(1) + vertexPts(1)(1)))/2, ((vertexPts(2)(2) + vertexPts(1)(2)))/2)
midPt2 = Array(((vertexPts(0)(0) + vertexPts(2)(0)))/2, ((vertexPts(0)(1) + vertexPts(2)(1)))/2, ((vertexPts(0)(2) + vertexPts(2)(2)))/2)
quarterPt0= Array((midPt0(0) + centerPt(0)(0))/2, (midPt0(1) + centerPt(0)(1))/2, (midPt0(2) + centerPt(0)(2))/2)
quarterPt1= Array((midPt1(0) + centerPt(0)(0))/2, (midPt1(1) + centerPt(0)(1))/2, (midPt1(2) + centerPt(0)(2))/2)
quarterPt2= Array((midPt2(0) + centerPt(0)(0))/2, (midPt2(1) + centerPt(0)(1))/2, (midPt2(2) + centerPt(0)(2))/2)
For i=0 To UBound(arrTri)
If (triangleLength > RandomNumber(2,3)) Then
triangle0 = Rhino.AddSrfPt(Array(vertexPts(0), quarterPt0, quarterPt2))
triangle1 = Rhino.AddSrfPt(Array(vertexPts(1), quarterPt1, quarterPt0))
triangle2 = Rhino.AddSrfPt(Array(vertexPts(2), quarterPt2, quarterPt1))
triangle3 = Rhino.AddSrfPt(Array(quarterPt0, quarterPt1, quarterPt2, quarterPt0))
subdivideTriangle triangle0
subdivideTriangle triangle1
subdivideTriangle triangle2
subdivideTriangle triangle3
Rhino.DeleteObjects(Array(strTriangle, triangleCrv))
End If
Next
For j=0 To UBound(arrTri)
If (triangleLength > RandomNumber(3,4)) Then
triangle4 = Rhino.AddSrfPt(Array(vertexPts(0), midPt0, midPt2))
triangle5 = Rhino.AddSrfPt(Array(vertexPts(1), midPt1, midPt0))
triangle6 = Rhino.AddSrfPt(Array(vertexPts(2), midPt2, midPt1))
triangle7 = Rhino.AddSrfPt(Array(midPt0, midPt1, midPt2, midPt0))
subdivideTriangle triangle4
subdivideTriangle triangle5
subdivideTriangle triangle6
subdivideTriangle triangle7′comment out this line to produce a sierpiński triangle
Rhino.DeleteObjects(Array(strTriangle, triangleCrv))
End If
Next
Next
End Function
Function RandomNumber(nMin, nMax)
RandomNumber = Null
If Not IsNumeric(nMin) Then Exit Function
If Not IsNumeric(nMax) Then Exit Function
If nMin >= nMax Then Exit Function
Randomize
RandomNumber = Int((nMax – nMin + 1) * Rnd + nMin)
End Function