parametric lace_distanceBasedRecursion

080731_layout_1 080731_layout_1

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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s