Algorthmic Processes: 3D Voronoi Diagram as Space-Maker

Page 1

ALGORITHMIC STRATEGIES: 3D VORONOI DIAGRAM AS SPACE–MAKER //dylan powell

2


Parameters/

Curve Point

Transform/ Scale Solid Trim Brep Plane Extrude

Throughout the centuries, geometry has been employed as a keystone of architectural design, from the ancient Egyptian pyramids to modern-day skyscrapers. However, recent trends and technology have rendered the manufacturing and construction industries the ability to produce nearly any shape desirable, leading to the emergence of many designs that blatantly ignore all possibilities of geometry as a system of organizing principles for design. This script represents one attempt to return to a geometry-based sense of order as a way of giving meaning and wonder back to architectural design. The geometrical diagram utilized by this script, the Voronoi diagram, derives from the work of Georgy Voronoy, a Ukrainian mathematician. I utilized the custom-scripted VB.net component made by Vicente Soler, available here: http://www.grasshopper3d.com/forum/topics/voronoi-3d

1&2 3

3

4


1

2

3

4

5

6

7

8

9

5&6

7&8

9 4


The starting geometry: a simple box.

1&2 5


1 2a

2b

2c

Find the X, Y, & Z domains of the input geometry to determine the maximum boundaries for random point distribution. 1 // Find corners of bounding box of referenced Brep geometry. 2a // Decompose box corners in the X, Y, and Z directions. 2b // Find the minimum and maximum of the point coordinates in each direction. 2c // Use the minimum and maximum values to create the domain for each axis.

6


The original box volume, with corner points.

Random array of points generated within the box volume.

3 7


3b 3a Generate random points to be used as the centroids for the Voronoi cells. 3a // Create a random distribution of numbers based on Seed values, desired number of vertices, and the X, Y, Z domains calculated previously. 3b // Recompose the random values as X, Y, Z coordinates for Voronoi centroids, constrained within the overall box volume.

8


The three-dimensional Voronoi diagram, generated from the random points inside the box. Each cell can be extracted as a closed Brep geometry for further analysis.

4 9


Private Sub RunScript(ByVal x As List(Of On3dPoint), ByVal bvol As List(Of OnBrep), ByRef A As Object, ByRef B As Object) ‘ based on: ‘ 3d Voronoi AKA Project Cell by (c) Gabe Smedresman 2005 Dim tm As DateTime = System.DateTime.Now Dim vcells As New List(Of OnBrep) Dim bbox As New OnBoundingBox(bvol(0). BoundingBox) Dim boxsize As Double = bbox.Diagonal.length For i As Integer = 0 To x.count - 1 Dim boxes As New List(Of OnBrep) boxes = CreateBlocks(x(i), x, boxsize) Dim vcell As New OnBrep vcell = IntersectBlocks(boxes, bvol) vcells.add(vcell) Next

4b 4a Use the randomized point set as centroids, from which to calculate the overall three-dimensional Voronoi diagram. 4a // Scale the output of the diagram to the desired size (1.00 = no change in scale). 4b // Calculate the three-dimensional Voronoi diagram through a custom VB component.

a = vcells Dim ts As System.TimeSpan = System.DateTime. Now - tm b = “It took “ & ts.minutes & “ min, “ & ts.Seconds & “ sec, “ & ts.Milliseconds & “ msec for “ & x.Count & “ cells.” End Sub ‘<Custom additional code> Dim tol As Double = doc.AbsoluteTolerance Function CreateBlocks(ByVal point As on3dpoint, ByVal x As list(Of on3dpoint), ByVal boxsize As Double) As list(Of onbrep) Dim boxes As New list(Of onbrep)

Custom VB code for the Voronoi diagram (see page 17 for complete code)

10


Selected curve (red) intersecting the overall Voronoi diagram, showing intersected cells (yellow) and non-intersected cells (blue).

11


5a

6 5b

Use an intersecting curve to select Voronoi cells to subtract from overall box volume. 5a // Select the desired curve. 5b // Divide the selected curve into enough segments so that at least one curve division point is within the bounary of each Voronoi cell. 6 // Test the division points for inclusion in each Voronoi cell. If inclusion is true, output the cell(s) to a new Brep list.

5&6 12


The overall box volume and the selected cells, ready for boolean operations.

13

The final resultant geometry from the boolean trim operation.


8 Subtract the Voronoi cells intersected by the line from the original box geometry to create the final geometrical scheme. 8 // Using the Solid Trim command, subtract the intersected Voronoi cells from the total block mass.

8 14


Sectioning of the geometry in the horizontal direction at regular intervals allows for one method of generating floor plates inside the volume, creating distinct interior and exterior architectural realms.

15


9b 9a Generate floor plates inside the shape by sectioning at regular intervals. 9a // Draw a bounding box around the volume, find its corners, and draw a vertical line between two corner points. Then divide this line into the desired number of segments based on the number of floors desired. 9b // Section the geometry horizontally at the division points on the curve and convert the section lines into flat planes. Extrude the planes downward to create floor thickness.

9 16


Custom Component/ 3D Voronoi Visual Basic Code Private Sub RunScript(ByVal x As List(Of On3dPoint), ByVal bvol As List(Of OnBrep), ByRef A As Object, ByRef B As Object) ‘ based on: ‘ 3d Voronoi AKA Project Cell by (c) Gabe Smedresman 2005

Dim r As New on3dvector(VectorCrossProd uct(Normal, up)) If r.iszero Then r = New on3dvector(0,

1, 0)

Dim s As New on3dvector(VectorCrossProd uct(Normal, r))

Dim tm As DateTime = System.DateTime.Now

Dim corners(8) As On3dPoint

Dim vcells As New List(Of OnBrep)

corners(0) = center + s * boxsize

Dim bbox As New OnBoundingBox(bvol(0). BoundingBox)

corners(1) = center + -r * boxsize corners(2) = center + -s * boxsize

Dim boxsize As Double = bbox.Diagonal.length For i As Integer = 0 To x.count - 1 Dim boxes As New List(Of OnBrep) boxes = CreateBlocks(x(i), x, boxsize) Dim vcell As New OnBrep vcell = IntersectBlocks(boxes, bvol) vcells.add(vcell) Next

corners(3) = center + r * boxsize corners(4) = center + s * boxsize + normal * boxsize corners(5) = center + -r * boxsize + normal * boxsize corners(6) = center + -s * boxsize + normal * boxsize corners(7) = center + r * boxsize + normal * boxsize Dim pBrep As OnBrep = OnUtil.ON_ BrepBox(corners)

a = vcells Dim ts As System.TimeSpan = System.DateTime. Now - tm b = “It took “ & ts.minutes & “ min, “ & ts.Seconds & “ sec, “ & ts.Milliseconds & “ msec for “ & x.Count & “ cells.” End Sub ‘<Custom additional code> Dim tol As Double = doc.AbsoluteTolerance Function CreateBlocks(ByVal point As on3dpoint, ByVal x As list(Of on3dpoint), ByVal boxsize As Double) As list(Of onbrep) Dim boxes As New list(Of onbrep) For i As Integer = 0 To x.count - 1 If Not (point = x(i)) Then x(i))

Dim normal As New On3dVector(point normal.Unitize

Dim center As New on3dvector((point + x(i)) / 2) Dim up As New on3dvector(0, 0, 1)

17

boxes.add(pBrep) End If Next CreateBlocks = boxes End Function Function IntersectBlocks(ByVal boxes As list(Of onbrep), ByVal bvol As list(Of onbrep)) As onbrep Dim i As Integer = 0 Dim results As ionbrep() = Nothing Dim pendingresults As OnBrep() = Nothing Dim intbol As Boolean = False Do Dim singlebox As New list(Of iOnBrep) singlebox.add(boxes(i)) rhutil.RhinoBooleanIntersection(bvol. ToArray(), singlebox.ToArray(), tol, intbol, pendingresults) i = i + 1


Loop While Not IsArray(pendingresults)

x.Add(Nothing)

results = pendingresults

Else x.Add(CType(__item, On3dPoint))

For j As Integer = i To boxes.count - 1

End If

Dim singlebox As New list(Of iOnBrep) singlebox.add(boxes(j)) rhutil.RhinoBooleanIntersection(result s, singlebox.ToArray(), tol, intbol, pendingresults) If IsArray(pendingresults) Then results = pendingresults Next IntersectBlocks = results(0)

‘assign direct data_access.SetData(1, A)

Dim bvol As List(Of OnBrep) = Nothing If (data_in(1) IsNot Nothing) Then bvol = New List(Of OnBrep)(100) in(1)

For Each __item As System.Object In data_ If (__item Is Nothing) Then bvol.Add(Nothing) Else bvol.Add(CType(__item, OnBrep))

Dim xprod As New On3dVector

xprod.z = v1.x * v2.y - v1.y * v2.x

End If Next

data_access.SetDataList(0, __errors_ plus_messages) End If End Try End Sub End Class

End If Else data_access.SetData(1, Nothing) End If If (B IsNot Nothing) Then If (GH_Format.TreatAsCollection(B)) Then Dim __enum_B As IEnumerable = DirectCast(B, IEnumerable) data_access.SetDataList(2, __enum_B) Else

‘merge tree data_access.SetDataTree(2, DirectCast(B, Grasshopper.Kernel.Data.IGH_DataTree))

VectorCrossProduct = xprod End Function

Public Sub External_RunScript(ByVal script_ owner As IGH_ActiveObject, ByVal data_in As List(Of Object), ByVal data_access As IGH_DataAccess) Implements IGH_ScriptInstance.External_RunScript

End If

If (__errors_plus_messages.Count > 0) Then

If (TypeOf B Is Grasshopper.Kernel. Data.IGH_DataTree) Then

End If

xprod.Unitize

‘</Custom additional code>

Else

Next

Function VectorCrossProduct(ByVal v1 As on3dvector, ByVal v2 As on3dvector) As on3dvector

xprod.y = v1.z * v2.x - v1.x * v2.z

data_access.SetDataTree(1, DirectCast(A, Grasshopper.Kernel.Data.IGH_DataTree))

End If

End Function

xprod.x = v1.y * v2.z - v1.z * v2.y

‘merge tree

Else ‘assign direct

‘3. Declare output parameters

data_access.SetData(2, B)

Dim A As System.Object = Nothing Dim B As System.Object = Nothing

End If End If Else

‘Prepare for a new run...

‘4. Invoke RunScript

‘1. Reset lists

Call RunScript(x, bvol, A, B)

data_access.SetData(2, Nothing) End If

__out.Clear() __err.Clear() owner = script_owner ‘2. Assign input parametes Dim x As List(Of On3dPoint) = Nothing If (data_in(0) IsNot Nothing) Then x = New List(Of On3dPoint)(100) in(0)

For Each __item As System.Object In data_ If (__item Is Nothing) Then

Try ‘5. Assign output parameters to component... If (A IsNot Nothing) Then If (GH_Format.TreatAsCollection(A)) Then Dim __enum_A As IEnumerable = DirectCast(A, IEnumerable) data_access.SetDataList(1, __enum_A) Else If (TypeOf A Is Grasshopper.Kernel. Data.IGH_DataTree) Then

Catch ex As Exception __err.Add(String.Format(“Script exception: {0}”, ex.Message)) Finally ‘Add errors and messages... Dim __errors_plus_messages As New List(Of String) If (Me.__err IsNot Nothing) Then __errors_plus_messages.AddRange(Me.__err) If (Me.__out IsNot Nothing) Then __errors_plus_messages.AddRange(Me.__out)

18


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.