Digital Representation envisioning architecture 4ARC65
Michael Clarke
Digital Representation_Envisioning Architecture
pg. 02
Contents
Page No.
Introduction -
05
A summary of content and overview of the work
Part 1: Feature Modelling & Descriptive Geometry
06
Exploring 3 dimensional systems of translation and rotation using ‘Microstation’s’ in-built ‘Feature Modelling’ Geometric Machines
12
Constructing curved and shell surfaces from 2D profiles using ‘Generative Components’ to control parameters Objects & Feature Types
20
A series of further developments of ruled surfaces using created features as components within each surface Scripting & Coding : Iteration, Functions and Objects
29
A basic introduction and exploration into the use of coding for iterative processes and forms using ‘Processing’ Using objects and classes to provide greater control over iterative and generative scripts in ‘Processing’
Part 2:
36
Design explorations for a pavilion at Burning Man Festival using methods learnt in Part 1 Further Exploration
49
Appendix A:
51
A list of all the models contained withing this book
Michael Clarke
pg. 03
Digital Representation_Envisioning Architecture
pg. 04
Introduction This book is split into two parts. The first part covers my explorations into the geometries of ruled surfaces and iterative functions that were covered in the digital representation taught lecture module at the University of Westminster. Each chapter summarises the aims of these explorations and outlines in detail how models were constructed and varied to test certain geometric parameters. The second part summarises my work in Design Studio 10 and looks at a model using all of the skills I have learnt during the module that can begin to inform my studio work. The studio project is focused on an arts pavilion or theme camp for the Burning Man festival in Nevada. The models created in the following chapters use Bentley Microstation, Bentley Generative Components and Processing (an open source platform for Javascript programming). A list of the models created and their relevant pages can be found in Appendix A at the back of this book on page 51.
Michael Clarke
pg. 05
Digital Representation_Envisioning Architecture
Feature Modelling & Descriptive Geometry The following experiments define basic rotational arrays and translations using feature modelling in Bentley Microstation as an introduction to modelling geometries with an awareness of the parameters defining them. Functions such as polar arrays require certain inputs to define an output, these inputs can be fixed values or related to each other or outside variables thus enabling a control that can govern complex models or systems from simple rules. In each model, I have shown the global variables controlling the model and the parameters that define the model including illustrations for the model in different states by altering the initial global variables.
>> Model 1: Using straight lines to define a curve through 90° //Global Variables: cylinderHeight numberOfCylinders
01.
In this example a simple cylinder is manipulated to allow multiple occurrences constrained between 90°. The radius of each cylinder is also defined as a function of it’s height: radius (r) = Height (h) / 100. The height is defined as a named variable. A polar array then defines the rotations. The number of repeats is given as an additional named variable. The delta angle is defined as (pi/2)/(the number of cylinders - 1). Pi/2 is 90° in radians and the number of cylinders (n) -1 ensures that the final cylinder is placed at a right angle to the initial. To explain further, in it’s simplest form where n = 2 this means that the angle would be 90/(2-1) (Fig. 01). Fig 02. shows n = 6 and 03. is n = 20. It is unfortunate that microstation’s feature modelling does not allow a polar array to be varied each step by a translation in addition to it’s rotation. Although more of an iterative function this would allow the creation of items such as spiral staircases in a simple array, all it would need would be to define an origin point and a height increment throughout the array. I would like to look at this further in Generative Components or scripting. This might also allow me to find out how shapes like those on this page can be scripted so that structure below and to the right of the bounding cylinders can be removed as it is unnecessary to the curved form.
pg. 06
02.
03.
Part 1 - Feature Modelling & Descriptive Geometry
<< Model 2: Using straight lines to define a curve through 360° / generating polygons This experiment follows on from the previous using the same variables but constrains the rotation to 360° instead of 90°. Again the cylinder radius is a function of it’s height. What is interesting about this rotation is the ease of achieving regular polygons. As each array goes the full 360° we can see very clearly defined patterns. In each case the polygon achieved has sides equal to the number of cylinders (n) - 1. This is due to the last cylinder being in the same place as the first. Depending on the radius specified the overlap can be controlled but it is dependent on the number of columns and difficult to ensure that the ends of the overlaps always meet. The images here show iterations from fig04. to 06. of n = 5, 7 and 20 respectively.
04.
05.
06.
Michael Clarke
pg. 07
Digital Representation_Envisioning Architecture
>> Model 3: Using a revolution to define a 3D shape that fits perfectly within a polar array This model follows on from the lecture example that created an arch out of separate bricks. I have used a curved profile that has been revolved into a 3D shape around a point. Using this same point I have arrayed the shape about 360° so that it always forms an enclosed space with a slight gap between each shape. The number of pieces and the radius can be varied.
Constructing the model: //Global Variables: nShapes (set at 3) centralRadius (set at 100) -The profile curve is drawn in 2D (fig.01); -The curve is then revolved about a point into a 3D model (fig 02.) : Revolution: Angle = ((2*Pi)/nShapes)-(2*pi/180) Radius = centralRadius Thickness = 0.00 The formula for the angle translates as 360° divided by the number of shapes required - 2°. This means that a single shape will fit perfectly into 360° with a 2° gap between each shape when arrayed. - The shape is then arrayed to give the final form (fig. 03) : Array: Items = nShapes Delta Angle = (2*Pi)/nShapes Radius = centralRadius The formula for the delta angle is simply the angle to rotate each piece by when copying in the array, therefore 360° divided by the number of shapes required.
pg. 08
01.
02.
03.
Part 1 - Feature Modelling & Descriptive Geometry
<< Model 3 Variations
Figure 04. nShapes = 3 centralRadius = 300
Figure 05. nShapes = 20 centralRadius = 100
04.
05.
Michael Clarke
pg. 09
Digital Representation_Envisioning Architecture
>> Model 4: Using cone geometry to dictate a polar array This model looks at arraying a series of smaller cones around the edge of a single larger cone. By using equations that define the cones’s geometry the base radius of the smaller cones can become a function of the circumference of the larger cone ensuring a perfect fit however many cones are used. Constructing the model:
The following parameters are necessary in defining this array: =
l
=
r R C
= = =
nCylinders - The number of smaller cones in the model cylinderHeight - The length or height of a smaller cone The small cone’s base radius The large cone’s base radius The circumference of the base of the large cone
Defining the initial smaller cone: Height = cylinderHeight Top radius = 0 (for a cone instead of a cylinder) Base radius = an arbitrary initial value (to be defined later - see right). The cone is then rotated 30° in the XY plane to set up the initial condition. The array is then defined as: Items = Delta Angle = Radius =
30°
R = sin30°l R = 0.5l
l
The value of R can then be plugged into the calculation for the circumference of the larger cone’s base.
π C = 2π(0.5l) C = πl C=2 R
R
We know that we are trying to fit a certain number of smaller cones around the circumference of the larger cone therefore the diameter of each smaller cone needs to fit n amount of times into the circumference. I have split the diameter up in terms of its radius for ease of input into the parameters of the model.
r
2r = C/n
π r = πl/2n
2r = l/n nShapes (2*pi)/nCylinders (cylinderHeight/4)-1
This means that the cone will be arrayed to fit a certain number (nCylinders) within 360°. The radius is a function of the height which was defined through trial and error to ensure limited overlap.
pg. 10
The following definitions are needed to understand the geometries involved in the model (R, C, l): R can be calculated with basic trigonometry, the value of one angle and one length of a right sided triangle drawn from the perpendicular height of the larger cone to it’s point is known. The hypotenuse of the triangle is the height of the smaller cone given as the variable cylinderHeight.
//Global Variables: cylinderHeight nCylinders
n
The main parameter to define is the radius of the smaller cone’s base in relation to the circumference of the larger cone’s base and the total number of smaller cones to ensure an even fit around the circumference.
so:
π
r = ( *cylinderHeight) / (2*nCylinders)
C
Part 1 - Feature Modelling & Descriptive Geometry
<< Model 4 Variations
Figure 02. nCylinders = 7 cylinderHeight = 3000
Figure 03. nCylinders = 20 cylinderHeight = 3000
Michael Clarke
pg. 11
Digital Representation_Envisioning Architecture
Geometric Machines, constructing ruled surfaces >> Model 5: Constructing a 2D ruled surface As an introduction to using Bentley Generative Components we began with explorations into ruled surfaces, continuing themes from the feature modelling. I have chosen to construct a cube to explore ruled surfaces. This gives me twelve edges, easily controlled through variables to define the constructs for simple 2D curves or double curvature from one plane to another. Constructing the cube: //Global Variables: double depth (set at 5) double height (set at 5) double width (set at 5) integer npoints (minimum value of 3 set at 6) The basic cube is a set of eight points, each individually defined as a point by cartesian coordinates, giving the X, Y and Z values as either 0 or one of the respective variables controlling the overall size of the cube. In this way they form the construction points for the entire model which can be varied in any dimension. Although there are other ways of doing this such as defining lines by direction and length and endpoints, there are only eight and this was the quickest and simplest way. The lines in between are simply twelve, lines by points, with the start and end point defined for each (fig.01). In the drawing, all the dimensions are set to 5.
height
depth
Each line then becomes a construction line for a series of points, defined as points along a line by number. The number of points in each case is defined as the global variable npoints. These will become the final construction points for the next step in the model (fig 02).
width
01.
02.
Part 1 - Geometric Machines
<< Model 5 cont.
5
5
4
The next step is adding construction lines for the ruled surfaces. By connecting any of the last set of points to each other we can begin to build up a series of curves which can then define point grids and ultimately a series of polygons approximating the surface (see model 6). Not every set of points will connect to each other to form a surface, they may be parallel or due to the way points are constructed in generative components not form curves. Points will connect in sequence, the first on one line to the first on the next etc. As an example of this see a very basic ruled surface in a single plane with the numbers of each point labelled (figures 03 & 04).
4 3 3
2 2
1 1
5&0 4 3 2
0
1
2
3
4
5
0
1 0
03.
04.
Michael Clarke
Digital Representation_Envisioning Architecture
>> Model 6: Simple 3D ruled surfaces This is the same model as model 5, just continuing it to show how the ruled surfaces can be created. Using two of the cubes edges in different planes as the construction lines. Constructing the cube: //Global Variables: double depth (set at 5) double height (set at 5) double width (set at 5) integer npoints (minimum value of 3 - set at 10) First the points are joined as two sets, one set to the other with each line acting sequentially as before (fig 01). Then the construction cube is hidden (fig 02). The next step is applying a point grid to the wireframe 3D curve in order to construct a surface instead of lines. Again I have used the points by number along a curve. The line input this time is the collection of lines that make up our ruled grid. The command applies a number of points (defined as the variable nPoints also) to each line (fig 03). The final step is to add a set of polygons, this time by point grid. This applies a quadrilateral polygon to each point in the grid providing there is always a point to the right and to the top of it. In figure 04, points A and B would have a polygon applied whereas point C has no additional point above and therefore would not become the origin for a polygon. The resulting surface for applying the polygon to the entire point grid is shown in figure 05.
01.
02.
Part 1 - Geometric Machines
C
B
A
03.
04.
05.
Michael Clarke
Digital Representation_Envisioning Architecture
>> Model 6, additional curved surfaces: These two pages show drawings and illustrations of additional surfaces that can be constructed using the same model. The first page shows 4 surfaces that combine, each one is twisted through 90째 as it rises from the ground or base plane. The variables are as follows: double depth (set at 5) double height (set at 5) double width (set at 5) integer npoints (minimum value of 3 - set at 10) I imagined this as a very solid yet lightweight structure, possibly metal panelled as a sculpture or pavilion. I like the contrast of solid elements with a form that is fluid and suggests folding, almost like a fabric. The opposite page shows a more open, collection of forms more akin to tensile fabrics and cables, a possible space for exploring or playing with the changing light within the structure. Side elevation
Aerial view
Plan view
Part 1 - Geometric Machines
>> Model 6 variation //Global Variables: double depth (set at 5) double height (set at 5) double width (set at 9) integer npoints (minimum value of 3 - set at 26)
Michael Clarke
Digital Representation_Envisioning Architecture
>> Model 7: Twisted tower Continuing the ruled surfaces, I decided to try and expand on the twisted squares variation of the previous model. This time I started with a different way of doing the model and added multiple layers to look at potential high rise design. Constructing the model: //Global Variables: heightInc intAngle nPoints nRules squareRadius The first step is to draw out the points that define the planes within the tower with a set of nominal values initially. Essentially the model is in three tiers, largely identical stacked one on top of the other, the process for the second is the same as the first and so on. A set of 4 points at the base are defined in a single step as a points list by cylindrical coordinates. This needs the following inputs with their values at this stage as shown: Coordinate System - BaseCS Radius - random value of 10 Theta - SeriesByCount (90, 360, 4) This means that the initial point is placed at 90°, it places the final point at 270° after the first (360°) and there are 4 points in total giving us a square with a diagonal distance between points of 20 or double the radius. z - translation - set to 0 for the base. The following three planes are given a z translation and the degrees are rotated by 45° each time. The variables intAngle and heightInc were then created, heightInc set at twenty replacing the z-translation and intAngle was set at 45° and put into the SeriesByCount formula as follows: SeriesByCount(intAngle, intAngle+270, 4) for the base plane and then each plane thereafter was given an incremental multiplier i.e SeriesByCount((intAngle*2 ),(intAngle*2)+270, 4). The initial values are x2, x3 and x4 for each plane. Each set of points is then joined with a polyline by vertices always starting at the first point in the list (fig 01).
01.
02.
03.
04.
Part 1 - Geometric Machines
<< Model 7 cont. Each polygon is divided by a number of points along the curve given by nRules. nRules has a minimum value of 5 which would place a point on each corner (twice at the first point as the polyline is closed), it then steps in increments of 4 ensuring there is always a symmetrical distribution of points across the polygon (fig 02. nRules is set to 21). The points from the previous step are joined by lines as with the previous models, from the base plane to the plane above and so forth until the top is reached, giving three line sets (fig 03). The next step is the same as for previous models, a point grid is defined across the lines using points along a curve for the entire set (fig 04). The number of points used is controlled by nPoints set here at 10. For aesthetic reasons I have edited the original points at this stage changing the intAngle multipliers from x2, x3 and x4 to x1.5, x2 and x2.5, softening the rotation between each layer. A grid of polygons is then applied to the 3 point grids in the same way as model 6. The result is shown in figure 05 although I have added the variable squareRadius to control the tower baseplate (set here to 5) and changed the heightInc to ten to suit. The final stage is purely for aesthetics. I individually altered each of the initial 4 planes radius to taper the tower. The base plate is still set to squareRadius, the second tier is set to squareRadius/1.2, the third is the squareRadius/1.5 and finally squareRadius/2 for the fourth tier. The wireframe drawing is shown in figure 06 and the rendered polygonal model in figure 07 for clarity.
05.
06.
07.
Michael Clarke
Digital Representation_Envisioning Architecture
Objects and Feature Types Generative Components allows the creation of features which can then be used quickly in future models without all of the additional construction that is normally required. It can be a quick and efficient way of compiling more complex models. I have tried to use features in a couple of ways, first taking some of the ruled surfaces I created in the last section and arraying them and secondly altering the surface of these with a new feature to replace the set of polygons that make up each surface. I will first explain each feature and then how I have used it in a new model. fx
Point point30
GraphVariable nPoints
>> Model 8: Creating a ruled surface feature The first feature I created to save time was saving the ruled surfaces I made earlier. This means now that the only inputs required are two curves and the number of points needed that controls how many polygons will fill the surface. Although I used two lines to create the feature as can be seen in the input parameters, the data type for each has been changed to ICurve to ensure that features such as arcs or bspline curves still work. //feature name RuledSurface //input parameters line06: ICurve (repl.) line04: ICurve (repl.) nPoints: double
Line line06
Point point14
Line line04
Point point12
Line line29
01.
note: nPoints could be controlled by a global Variable instead of a fixed value. Figure 01 shows the feature creation with the symbolic diagram for each part of the model. This is only part of the earlier model, I have hidden the section that creates the lines in the first place. I will not explain here how the ruled surface iis created, it is the same process as model 6. The blue highlighted boxes are the inputs, which can be related back to the input parameters listed above. The green boxes are all the potential outputs of the model which are all visible in the drawing behind. However, the only item I want is the polygon in the last box so all others are ticked as construction. This means that I can now use this feature with any two lines to create a ruled surface made up of polygons. Figures 02 and 03 show simple examples of using the feature, 02 for a hyberbolic parabaloid and 03 for a more organic ruled surface.
pg. 20
02.
03.
Polygon polygon10
Part 1 - Objects & Feature Types
depth width
<< Model 9: Hyberbolic Vaults I liked some of the forms I was able to create combining the ruled surfaces within a cube that I constructed in model 6. Two surfaces in particular combined well that could possibly be used to create an arch or the underside of a bridge or a vaulted roof so I decided to create these as a feature based on a co-ordinate system. All I would need to do then is place any number of co-ordinate systems in a model as origins for these. In addition I kept the variables from model 6 allowing me control over the width, depth and height of my feature as well as the number of polygons across itâ&#x20AC;&#x2122;s surface. //feature name HyperbolicVault height
//input parameters baseCS: CoordinateSystem (repl.) depth: double All of these inputs can be given a variable width: double in a model instead of a fixed value. This height: double means the only new features to add for a nPoints: double series of arches is the coordinate system.
}
nPoints
CoordinateSystem
Michael Clarke
pg. 21
Digital Representation_Envisioning Architecture
>> Model 10: Vault series, arraying a created feature This is the model using the feature created in model 9. I have only made a very simple one dimensional array of the feature to start with and I will then develop the model with further arrays and additional feature types or objects. //global variables height - set to 20 depth - set to 3 width - set to 10 nPoints - set to 20 nBays - set to 4 //constructing the model line01 - By StartPointDirectionLength StartPoint - baseCS Direction - baseCS.XDirection Length - width*nBays
HyperbolicVault01
coordinateSystem01 - By SpacingAlongCurve Curve - line01 Spacing - width HyperbolicVault01 - ByDefault (as set out in model 9) CoordinateSystem - coordinateSystem01 Depth - depth Height - height Width - width nPoints - nPoints
line01
coordinateSystem01 z baseCS (base coordinate system)
pg. 22
y
x
Michael Clarke
pg. 23
Digital Representation_Envisioning Architecture
>> Model 11: Decorative Stone - using a polygon as the basis for a feature This is a feature based upon a polygon that I hope to use to replace the polygons in some of the ruled surfaces from the previous models. In particular on the vaults I created in model 10. //global variables heightRatio //constructing the model line01 - ByPoints StartPoint - polygon01.Vertices[1] EndPoint - polygon01.Vertices[3] line02 - ByPoints StartPoint - polygon01.Vertices[0] EndPoint - polygon01.Vertices[2] point05 - AtCurveCurveIntersection Curve0 - line01 Curve1 - line02 direction01 - ByCrossProduct Origin - point05 XDirection - line01 YDirection - line02 line03 - By StartPointDirectionLength StartPoint - polygon01.Vertices[0] Direction - direction01 Length - polygon01.Length*heightRatio lines 04,05 and 06 are the same as 03, substitute the [0] in the StartPoint for [1],[2],[3] respectively line07 - ByPoints StartPoint - line03.EndPoint EndPoint - line06.EndPoint point06 - ByDistanceAlongCurve Curve - line07 DistanceAlongCurve - line07.Length/2 line08 - ByPoints StartPoint - line04.EndPoint EndPoint - line05.EndPoint point07 - ByDistanceAlongCurve Curve - line08 DistanceAlongCurve - line08.Length/2 pg. 24
line09 - By StartPointDirectionLength StartPoint - line03.EndPoint Direction - direction01 Length - polygon01.Length*heightRatio lines 10,11 and 12 are the same as 09, substitute the line03. Endpoint with line04, 05, 06 respectively. note, another way would be to have one line at each corner and use itâ&#x20AC;&#x2122;s midpoint rather than two separate lines as shown here.
line14 curve02
arc04 line10
line16
line04 point07 line08
arc03 line11
arc01 - ByCentreStartSweepPoint CentrePoint - line09.StartPoint StartPoint - line09.EndPoint SweepPoint - point06
line05
line02
arc02 - ByCentreStartSweepPoint CentrePoint - line12.StartPoint StartPoint - line12.EndPoint SweepPoint - point06 arc03 - ByCentreStartSweepPoint CentrePoint - line11.StartPoint StartPoint - line11.EndPoint SweepPoint - point07
line01 direction01 point05 arc01 line09 line03
polygon01 point06
arc04 - ByCentreStartSweepPoint CentrePoint - line10.StartPoint StartPoint - line10.EndPoint SweepPoint - point07 lines 13, 14, 15 and 16 are constructors for composite curves that can close off each end of the shape, they run left to right along the base of the polygon and between the arc endpoints at each end of the shape. See the list in the constructors below for clarity.
line07
arc02 line12
line13
line06
curve01 line15
curve01 - CompositeCurve Curves - {line03,line09,arc01,line13,arc02,line12,line06,line15} curve02 - CompositeCurve Curves - {line04,line10,arc04,line14,arc03,line11,line05,line16} bsplineSurface01 - Ruled StartCurve - curve01 EndCurve - curve02 UCurveDisplay - 4 VCurveDisplay - 4
This means I can now replace any polygon in a model with the shape above with only two inputs: The polygon itself; A value for heightRatio - which will determine the thickness of the object and how large the rounded edges are. The edges could be determined by a different variable to the height ratio for greater control although for simplicity I have not done that here. The image shows the heightRatio set at 0.02.
bsplineSurface01
Part 1 - Objects & Feature Types
<< Model 12: Decorative vaults - using the created feature I have taken the feature I created opposite and used it in place of the polygons on model 9. The images to the left clearly show the rolled edges to each polygon aligning to form detailing across the form. Due to the feature constructed in a such a way that it is always extruded in the direction of the polygon’s normal however, the alignment is not perfect and if you zoom right into the model you can see displacement between the lines. The global variables are set to the same as model 9, however the additional variable needed for the new feature, heightRatio, has been added with a value of 0.02.
>> Overleaf, Model 13: Hyperbolic Cathedral The next page shows an extension of these two feature types into a church like space. The central space is this model with the detailed ‘stone’ feature. Two either side are two additional arrays of the ‘HyperbolicVault’ feature. The coordinate system for each was created in the same way but with the starting point translated in both the positive and negative y direction by the variable width, meaning the arrays touch. In addition I have scaled down the height of the two side arrays by a half so that the height is now controlled by: height/2 meaning they will always relate to the height of the central space.
Michael Clarke
pg. 25
Digital Representation_Envisioning Architecture
Objects & Feature Types
Michael Clarke
Digital Representation_Envisioning Architecture
pg. 28
Part 1 - Scripting & Coding: Iteration, Functions and Objects
Scripting & Coding: Iteration, Functions and Objects This chapter begins to look at using scripting, in particular using Processing, to code iterative or recursive functions that are difficult to create without huge amounts of construction geometry or copying and pasting. A relatively simple script can reproduce a set of commands quickly and efficiently. The capability of a script or code to do this can be increased with objects or classes that can themselves be plugged in, in much the same way as created features in Generative Components. The ease of reading codes and their flexibility makes it a powerful tool and easy to take parts of code from different models and combine them to the desired result. In this way, many different codes can be found online available to share and change through downloads and uploads and this is often the quickest way of doing something. Where I have used other peopleâ&#x20AC;&#x2122;s scripts in the following models I have clearly highlighted itâ&#x20AC;&#x2122;s use, written around and in-between my own.
Michael Clarke
pg. 29
Digital Representation_Envisioning Architecture
>>Example File from the processing website The reason I have shown the example file is that to explore scripting I have chosen to work with an existing file as a base that I can build upon. I like fractal patterns and geometries and it is a mathematical system that can be very complex and organic in appearance with a set of simple rules in very similar ways to creating curved surfaces from straight lines as in the previous chapters. This kind of thought is also the basis for parametric software and object class coding that I have been using in this module. The model on this page is a simple tree in two dimensions, a line is drawn, at the end of each line two lines branch out at an angle. The code keeps drawing additional branches, each time scaled down by a specific ratio, until it reaches a limiting factor, in this case if the branch it draws is less than 2 pixels long the code stops. The code is explained in greater detail on the opposite page. The original code is in black and the authorâ&#x20AC;&#x2122;s comments in grey. Where I feel points need further clarification i have added additional comments in red. It is necessary to define each part of the code in full to understand how it can be used and manipulated. A nice feature of this model is that the mouse position on the screen determines the angle between the branch and itâ&#x20AC;&#x2122;s supporting branch going from figure 01 through to figure 04 as the mouse moves from left to right.
01.
03.
This only maps a single tree in two dimensions and although an iterative function can be rationalised and improved. I am aiming to recreate this in 3 dimensions with additional variables and recursive loops over the next few pages, making use of some basic object orientated programming as well.
04.
pg. 30
02.
Part 1 - Scripting & Coding: Iteration, Functions and Objects
// Convert it to radians theta = radians(a); // Start the tree from the bottom of the screen. The coordinate system starts in the top left corner and positive directions are down and right in processing, therefore ‘height’ will be a value at the bottom of the screen translate(width/2,height); // Draw a line 120 pixels line(0,0,0,-120); // Move to the end of that line. The line has a start point coordiante (x1,y1) and an endpoint coordinate (x2,y2) therefore the line is written as (x1,y1,x2,y2). The coordinate system is translated to the line endpoint. translate(0,-120); // Start the recursive branching! This calls the object or class ‘branch’ which is defined below branch(120);
//GLOBAL VARIABLES float theta; void setup() { // Sets up the window size that the programme will run in size(640, 360); // Draws all geometry with smooth (anti-aliased) edges. For example curves will look like curves instead of a series of straight lines smooth(); } void draw() { // Everything in the draw command is repeated over and over again unless told to stop, the background tool will draw a background each time meaning only the latest iteration of the information within the draw command will be shown on the screen. The value following the background is an RGB value equating to black background(0); // Changes the number of times the screen is refreshed per second from the default of 60 frames per second to 30 frameRate(30); // Sets the colour of all lines from now on to white. Note a single value for an RGB value equates to the same value for all three parts meaning it will be grayscale. For example (255) is the same as (255, 255, 255) stroke(255); // Let’s pick an angle 0 to 90 degrees based on the mouse position. mouseX is the position of the mouse in the x direction relative to the programme window. Width is an inbuilt command in processing that calls the screen width set up in the size() command, in this case 640. The command overall sets a value of 90° as a limit so that when the mouse is at the very right hand side of the screen a will equal 90 float a = (mouseX / (float) width) * 90f;
// Rotate (the entire coordinate system) by theta rotate(theta); // Draw the branch. As the orientation is now rotated, the y direction is no longer up but at the angle theta, therefore -h becomes the length of the line in that direction line(0, 0, 0, -h); // Move to the end of the branch translate(0, -h); // Ok, now call myself to draw two new branches!! This time h will be 2/3rds of it’s original size branch(h); // Whenever we get back here, we “pop” in order to restore the previous matrix state popMatrix(); // Repeat the same thing, only branch off to the “left” this time! Note the angle is -theta instead of positive pushMatrix(); rotate(-theta); line(0, 0, 0, -h); translate(0, -h); branch(h); popMatrix();
} // The first line names the object and defines its input parameters, in this case a float value labelled h void branch(float h) { // h is then defined and will become the branch length // Each branch will be 2/3rds the size of the previous one h *= 0.66; // h *=0.66 is the same as h=h*0.66
} }
// All recursive functions must have an exit condition!!!! // Here, ours is when the length of the branch is 2 pixels or less if (h > 2) {
// Save the current state of transformation (i.e. where are we now) This means the current origin of the programme, i.e the base coordinate system pushMatrix();
Michael Clarke
pg. 31
Digital Representation_Envisioning Architecture
TREE MODEL without comments import processing.opengl.*;
>> Changing the number of trees created Each image shows the model in a single condition in both plan and perspective views. All of the images here have the branch angle (theta) set to 30째 and the branch reduction ratio (h) to 0.6 so that each branch is 3/5 of the size of the branch supporting it. This series of images shows the effects of changing the variable ntrees as follows:
float theta; float beta; float ntrees; float trunklength; float basebranchlength; void setup() { size(1024, 860, OPENGL); trunklength = 250; basebranchlength = 200; }
01. ntrees = 1 02. ntrees = 2 03. ntrees = 3 04. ntrees = 4 05. ntrees = 5 06. ntrees = 10
void draw() { rotateX(mouseY*0.01); rotateY(mouseX*0.01); background(255); frameRate(30); stroke(100);
01.
02.
float a = 90f; theta = radians(a);
03.
float b = 360f; beta = radians (b); ntrees = 5; translate(width/2,height/2,0); line(0,0,0,0,0,-trunklength); translate(0,0,-trunklength); for (int i=0; i<ntrees; i++){ branch(basebranchlength); rotate (beta/ntrees); } }
04.
pg. 32
05.
06.
Part 1 - Scripting & Coding: Iteration, Functions and Objects
background(255); // Now set to white frameRate(30); stroke(100); // Now set to a grey
MAKING IT 3D - Model 14 All code borrowed from the example file including comments will be in grey, all new code in black and all new comments in red.
// Tree branching angle // As we are using the mouse to control the view it would get confusing to have it control the branching angle also. This is now a value that can be changed by manually typing. float a = 90f; // Convert it to radians theta = radians(a);
TREE MODEL // OPENGL is a 3D rendering library that can be used by Processing, all it needs to run is the line below and the term ‘OPENGL’ as the third input to the size() command (see below) import processing.opengl.*; // Variables, I have added some in addition to theta to control the number of trees, a bounding angle and some length values float theta; float beta; float ntrees; float trunklength; float basebranchlength;
// Total number of trees and total angle for polar array float b = 360f; beta = radians (b); ntrees = 5; // Start the tree from the centre of the screen translate(width/2,height/2,0); // Draw a line for the trunk line(0,0,0,0,0,-trunklength); // Move to the end of that line translate(0,0,-trunklength);
void setup() { size(1024, 860, OPENGL); // values can be assigned to variables in setup. I have not assigned all the variables here, for ease of explanation they may be combined where they are needed trunklength = 250; basebranchlength = 200; } void draw() { // To rotate the model and view it, this is a very basic way and fairly crude but does the job. Essentially the model is rotated in the x direction as the mouse moves in the y direction and vice versa. The 0.01 multiplier is to give the user control over the rotation otherwise it would be far too fast to make use of rotateX(mouseY*0.01); rotateY(mouseX*0.01);
// Iterations for total number of trees within a circle enclosed in for loop for (int i=0; i<ntrees; i++){ // Start the recursive branching! The initial length of the branches is now controlled by a variable branch(basebranchlength); // Each iteration is rotated by 360°/the number of trees required rotate (beta/ntrees); }
BRANCH CLASS // This is largely the same component although I have edited the lines to now draw in 3 dimensions. For a uniform draw that resembles the original example model I have used the value h for all three dimensions of the line end point coordinate. The resulting model will change for any change in h or change in the values of the branch end points, these variables are shown over the next few pages. void branch(float h) { h *= 0.60; // All recursive functions must have an exit condition!!!! // Here, ours is when the length of the branch is 2 pixels or less if (h > 2) { // Save the current state of transformation (i.e. where are we now) pushMatrix(); // Rotate by theta rotate(theta); // Draw the branch line(0, 0, 0, -h, -h, -h); // Move to the end of the branch translate(-h, -h, -h); // Ok, now call myself to draw two new branches!! branch(h); popMatrix(); // Whenever we get back here, we “pop” in order to restore the previous matrix state
BRANCH CLASS without comments void branch(float h) { h *= 0.60; if (h > 2) { pushMatrix(); rotate(theta); line(0, 0, 0, -h, -h, -h); translate(-h, -h, -h); branch(h); popMatrix(); pushMatrix(); rotate(-theta); line(0, 0, 0, -h, -h, -h); translate(-h, -h, -h); branch(h); popMatrix(); } }
// Repeat the same thing, only branch off to the “left” this time! pushMatrix(); rotate(-theta); line(0, 0, 0, -h, -h, -h); translate(-h, -h, -h); branch(h); popMatrix();
} } }
Michael Clarke
pg. 33
Digital Representation_Envisioning Architecture
>> Changing the branch object Each image shows the model in a single condition in both plan and perspective views. All of the images here have ntrees set to 5 and the branch reduction ratio (h) to 0.6 so that each branch is 3/5 of the size of the branch supporting it. This series of images shows the effects of changing the branch angle - variable theta as follows: 01. theta = 15° 02. theta = 30° 03. theta = 45° 04. theta = 60° 05. theta = 75° 06. theta = 90°
pg. 34
01.
02.
03.
04.
05.
06.
Part 1 - Scripting & Coding: Iteration, Functions and Objects
<< Changing the branch reduction ratio Each image shows the model in a single condition in both plan and perspective views. All of the images here have ntrees set to 5 and the branch angle theta set to 15째. This series of images shows the effects of changing the branch ratio h as follows: 07. h = 0.2 08. h = 0.4 09. h = 0.6 As the loop stops running when branches get below two pixels in length the tree in figure 01 with the greatest reduction in length between each branch (each branch is only a fifth of the one supporting it) has a very limited number of branches. When the reduction in length is much smaller the loop can run more times producing a tree with a greater number of branches. An additional control for limiting the number of branches could be to change the if statement: if h>2 controlling the minimum length of each branch.
07.
08.
09.
<< Changing branch orientation The trees so far have been uniform branching in all dimensions. That is the end point of each branch has been given by (-h,-h,-h) from the start point on both branching in positive and negative theta angles. What happens if we change one branch so that some of the values are positive. Figure 10 changes one branches x coordinate to h, figure 11 changes one branches y coordinate to h and figure 12 changes one branches z coordinate to h. The code for drawing the line that makes each branch is given by: 10. line(0, 0, 0, h, -h, -h); 11. line(0, 0, 0, -h, h, -h); 12. line(0, 0, 0, -h, -h, h);
10.
11.
12.
Michael Clarke
pg. 35
Digital Representation_Envisioning Architecture
pg. 36
Part 2 - Burning Man Festival Art Pavilion Explorations
Part 2: Burning Man Festival Art Pavilion Explorations “Once a year, tens of thousands of participants gather in Nevada’s Black Rock Desert to create Black Rock City, dedicated to community, art, self-expression, and self-reliance. They depart one week later, having left no trace whatsoever. Burning Man is also an ever-expanding year-round culture based on the Ten Principles.” - extract from http://www.burningman.com/
The festival does not have music events or booked entertainers but instead becomes a city where everyone is encouraged to interact and participate. Money is only allowed to buy coffee or ice, everything else must be brought with you or gifted at the festival with other participants. There are a set of rules to follow to ensure that everyone is involved and that there is no trace left on the desert playa once the festival has finished. A large part of the festival is community artwork in the form of large sculptures or pavilions as well as the burning man himself and the ‘temple’, a major construction each year. In addition, ‘mutant vehicles’ or art cars are the only motorised vehicles on site and have to pass strict guidelines. The festival committee offer grants for people to build their art structures each year and a funding committee decide on applicants entries. I have been asked to design my own art’s pavilion or theme camp with the potential to submit for a funding grant.
Michael Clarke
pg. 37
Digital Representation_Envisioning Architecture
>> A very brief overview of my project and the background research I started the year looking at the work of Frei Otto and Buckminster Fuller, in particular focusing on their analogue and digital form finding experiments. I was asked to try to explore and combine their experiments into a form finding process of my own using both physical models and parametric explorations using Grasshopper for Rhino. I began with research into minimal path systems that led me into my own research in the fields of emergence, self organisation and self assembly, fractal geometry, reaction diffusion systems and crystal growth. My early digital experiments looked at bunching and thread attractions into singular systems. I was encouraged to take this further through potential uses for tube networks other than structure, in particular when looking at Burning Man Festival. A key problem at the festival is the storage of grey water and potable water as well as water transportation. I began by looking at evaporative cooling methods using thread networks and salt crystallisation, and capillary action to transport large amounts of water around and through my pavilion, ultimately as thermal mass. Burning man festival is all about user interactivity, and the experiential nature of spaces both at day and at night. I have begun to look at a pavilion made entirely from tube networks transporting water constantly through them using siphoning to create a fluid sculpture that will also provide relief from the heat. At night the structure will come alive through the addition of florescent dyes to the water.
pg. 38
Part 2 - Burning Man Festival Art Pavilion Explorations
<< Structural stability The problem with a structure constructed entirely from polypropylene tubing is that it can’t support it’s own weight so I need to look into a way of supporting my water carrying tubes. As the form of the building is still to be confirmed I thought it best to focus on a potential structure for my digital representation explorations, one that I hope can influence my form in the future. In my last design studio critique I was encouraged to look at pumping concrete through some of the tubes as a support system that could then become a framework for the tube networks carrying the water and the dye and encourage movement and exploration through and around a structure built for it’s effect on the user’s experience. I am currently conducting physical experiments into the best forms and sizes of tubing for the concrete to be strong enough so in the following model and experiments I have tried to keep it as flexible as possible but loosely based around a structure developed by Ecologic Studio called Fibrous Room. They have used rotating and twisting tubes filled with concrete to create an installation indoors, see the photos to the left.
Michael Clarke
pg. 39
Digital Representation_Envisioning Architecture
>> Model 15: Helical tube arrays As I do not yet know the form of my proposal I have modelled this potential structural component relative to any isocurve on a surface, therefore allowing me in the future to simply move points or call up certain parameters to place a structural network that I can then hang my water tubes off. As a simple explanation, the concrete tubes component I am aiming to create will be a series of hyperboloids of revolution arcing and twisting across a surface. This could then become a feature and placed wherever structural support or rigidity is needed using a surface, an isocurve on that surface and a coordinate system along the iso curve as inputs. The model uses Generative components and some internal scripting. I will explain each step over the next few pages and then finish with some images for potential forms that could be helped by the structural system.
pg. 40
Part 2 - Burning Man Festival Art Pavilion Explorations
<< Steps 01,02 // GlobalVariables nRings = 5; bsplineCurve04 bsplineCurve03
The first step is to create a generic bspline surface to form the basis of the model. This will come to be the desired form of my proposal but for now is the result of random point placement and 4 bsplineCurves constructed from these points. BSplineSurface01 - FromRailsAndSweptSections
point15
Rail0: ICurve - bsplineCurve02 Rail1: ICurve - bsplineCurve04 Section0: ICurve - bsplineCurve01 Section1: ICurve - bsplineCurve03
bsplineCurve05
These can be any 4 curves - it is just to construct a simple arbitrary surface. The reason I have used curves constructed by Points is that by moving any point in the model (shown with a cross in figure 02) it changes the surface.
bsplineSurface01
The next step is key as it defines which line across the surface will become a support base as opposed to empty surface free for the water tubes.
bsplineCurve02
bsplineCurve01
BSplineCurve05 - IsoCurveFromSurface Surface: ISurface (repl.) - bsplineSurface01 Parameter: double (repl.) - 0.5 Direction: DirectionOption - DirectionOption.U The IsoCurve is the section through the surface at any distance along the surface (given by Parameter) and will be a value between 1 and 0. Reparametricising a curve is to change itâ&#x20AC;&#x2122;s start and end values to 0 and 1 as inputs for an additional command. The direction is an option between U or V. This is simply which axis on the surface to cut through, like x and y on a cartesian coordinate system only mapped onto the surface itself (See figure 02.) Finally it needs a set of points along the IsoCurve that will form the final part needed to create a new coordinate system that will allow us to construct the model on the surface. Point15 - ByNumberAlongCurve Curve: ICurve (repl.) - bsplineCurve05 NumberAlongCurve: int - nRings (5.00) I initially gave the number of points to be controlled by a variable (nRings) however, I need to call the specific points out later which means this value cannot be changed once I construct the rings that will hold the structural pipes but it adds some flexibility at the beginning.
Michael Clarke
pg. 41
Digital Representation_Envisioning Architecture
>>Steps 03,04 // GlobalVariables nRings = 5; angleInc = 360/nRules offAngle = 30 nRules = 10
coordinateSystem01[4] coordinateSystem01[3]
The next stage is to place a new coordinate system that will allow us to set up rings of points to form our hyperboloids of revolution. It is important that this coordinate system is created relative to the surface to ensure that our point rings will be placed in a plane normal to the surface they are arranged on.
coordinateSystem01[2]
bsplineCurve05
CoordinateSystem01 - ByOriginCurveTangentSurfaceNormal Origin: IPoint (repl.) - point15 Surface: ISurface - bsplineSurface01 Curve: ICurve (repl.) - bsplineCurve05
coordinateSystem01[1] point15 bsplineSurface01
Next we need a set of points around each coordinate system, as the rotation will vary from one to the next I have done the points as 5 separate arrays and this is why nRings can no longer be a variable but needs to become a fixed value. Point14 - ByCylindricalCoordinates CoordinateSystem: CoordinateSystem (repl.) coordinateSystem01[0] Radius: Double (repl.) - 1 Theta: Double (repl.) - SeriesByCount(angleInc, 360, nRules) ZTranslation: double (repl.) - 0 This places a point array at the first of the new coordinate systems (notice the [0] calling out the first item in the list). The array radius is set currently to a nominal value of 1. A point is drawn each time in a series which has the arguments (start number, final number, number count). This means it will go in a full circle, starting at angleInc (which is 360째/nRules), rotating each time so that nRules number of points will fit into the final number of 360째. However this always draws the ring in the XY plane and we need it in the current YZ plane so we need to edit the coordinate system.
pg. 42
coordinateSystem01[0]
point14
Part 2 - Burning Man Festival Art Pavilion Explorations
<< Steps 05,06 // GlobalVariables angleInc = 360/nRules offAngle = 30 nRules = 10 radius = 0.5
coordinateSystem02[4] coordinateSystem02[3]
Notice nRings has been removed from the variables, we are now working with five fixed coordinate systems. Step 5 needs to rotate the coordinate system so that the XY plane becomes the plane normal to the surface with its own normal a tangent to the isoCurve.This is very easy to do:
coordinateSystem02[2] point19
point18 coordinateSystem02[1]
point17
point16
coordinateSystem02[0]
point14
CoordinateSystem02 - ByUniversalTransform CoordinateSystem: CoordinateSystem (repl.) coordinateSystem01 //The inputs can be any translation in three dimensions, any rotation and any scalar value. All translations are set to 0, all scalar options are set to a factor of 1, only the Y rotation is changed by 90째: YRotation: double (repl.) - 90 Now our first array of points can be constructed, notice there is also now a variable for the radius: Point14 - ByCylindricalCoordinates CoordinateSystem: CoordinateSystem (repl.) coordinateSystem02[0] Radius: Double (repl.) - radius (0.5) Theta: Double (repl.) - SeriesByCount(angleInc, 360, nRules) ZTranslation: double (repl.) - 0 To create the other rings I have copied point 14 and changed the coordinate system each time to the next one in the list e.g [0], becomes [1] etc. but as we need it to twist between each ring there is a slight change in the code for Theta. This adds an offset angle to the whole array. To keep it twisting I have multiplied the offset angle at each new ring. Point16 - Theta - SeriesByCount (angleInc+offAngle, 360+offAngle, nRules) Point17 - Theta - SeriesByCount (angleInc+(2*offAngle), 360+(2*offAngle), nRules) Point18 - Theta - SeriesByCount (angleInc+(3*offAngle), 360+(3*offAngle), nRules) Point19 - Theta - SeriesByCount (angleInc+(4*offAngle), 360+(4*offAngle), nRules)
Michael Clarke
pg. 43
Digital Representation_Envisioning Architecture
>>Step 07 // GlobalVariables angleInc = 360/nRules offAngle = 30 nRules = 10 radius = 0.5 This is the biggest and most complex stage in the entire model and forms the central axis of our pipes. It is very easy to connect an entire set of points to another set, however if you start trying to do multiple sets, Generative Components wonâ&#x20AC;&#x2122;t do it. We cannot select a bsplineCurve and input point14, point 16, point17, point18 and point19 as the controls, instead this will create 5 separate curves that run around each ring. Instead we need to individually call on each point in an array and link it to the next. This is a time consuming process and if we change the number of lines at any point, is no longer valid. This can be solved with a small bit of iterative code though, each time calling a point from each array, drawing the curve and then doing it for the next point in the array.
bsplineCurve06
point19
bsplineCurve05 (original isoCurve shown dashed in centre
point18 point17
point16
bsplineCurve06 - ByFunction Function = function (int num, Point pt1, Point pt2, Point pt3, Point pt4, Point pt5) point14
{ for (int i = 0; i <= num; ++i) { BSplineCurve bs01 = new BSplineCurve(this); bs01.ByPoints({pt1[0+i],pt2[0+i],pt3[0+i],pt4[0+i], pt5[0+i]}); } }; FunctionArguments = {nRules, point14, point16, point17, point18, point19};
pg. 44
Part 2 - Burning Man Festival Art Pavilion Explorations
<<Step 08
point19
// GlobalVariables nRings = 5; angleInc = 360/nRules offAngle = 30 nRules = 20
point18 point17
point23
This step is relatively straightforward now that we have done it once. All we need to do now is copy the point arrays and reverse the offset direction and then copy the bsplinecurve list and input the new point lists as the function arguments.
point22
point16
Point 14 remains the same for both directions
point21 bsplineCurve06
point20 point14
bsplineCurve07
Point20 - ByCylindricalCoordinates CoordinateSystem: CoordinateSystem (repl.) coordinateSystem02[1] Radius: Double (repl.) - radius (0.5) Theta: Double (repl.) - SeriesByCount(angleInc-offAngle, 360-offAngle, nRules) ZTranslation: double (repl.) - 0 Theta then remains as before only negative each time:
point14
Point21 - Theta - SeriesByCount (angleInc-(2*offAngle), 360-(2*offAngle), nRules) Point22 - Theta - SeriesByCount (angleInc-(3*offAngle), 360-(3*offAngle), nRules) Point23 - Theta - SeriesByCount (angleInc-(4*offAngle), 360-(4*offAngle), nRules)
bsplineCurve07 - ByFunction Function = function (int num, Point pt1, Point pt2, Point pt3, Point pt4, Point pt5) { for (int i = 0; i <= num; ++i) { BSplineCurve bs01 = new BSplineCurve(this); bs01.ByPoints({pt1[0+i],pt2[0+i],pt3[0+i],pt4[0+i], pt5[0+i]}); } }; FunctionArguments = {nRules, point14, point20, point21, point22, point23};
Michael Clarke
pg. 45
Digital Representation_Envisioning Architecture
>>Step 09 // GlobalVariables angleInc = 360/nRules offAngle = 30 nRules = 20 radius = 0.25 radiusSmall = 0.01 The final remaining stage is just to give a thickness to the â&#x20AC;&#x2DC;concreteâ&#x20AC;&#x2122; tubes (Figure 01). Again this is a very simple step: BSplineSurface02 - SweepCircleAlongPath Path: ICurve (repl.) - bsplineCurve06 Diameter: double (repl.) - radiusSmall*2 BSplineSurface03 - SweepCircleAlongPath Path: ICurve (repl.) - bsplineCurve07 Diameter: double (repl.) - radiusSmall*2 Figure 02. shows multiple instances overlaid on top of each other illustrating what happens to the model when varying the isocurve parameter and direction - each instance is labelled.
01.
Direction: U Parameter: 0.9
Direction: V Parameter: 0.5
Direction: U Parameter: 0.5
Direction: U Parameter: 0.1
Direction: V Parameter: 0.1
02.
pg. 46
Part 2 - Burning Man Festival Art Pavilion Explorations
<< Any surface // GlobalVariables angleInc = 360/nRules offAngle = 40 nRules = 20 radius = 0.25 radiusSmall = 0.01 This is a quick illustration to show how it can be used for any surface, this is actually the same model but the surface control points have been altered.
Michael Clarke
pg. 46
Digital Representation_Envisioning Architecture
pg. 48
Part 2 - Burning Man Festival Art Pavilion Explorations
Further Exploration There are many things I would like to take further with this model and new possibilities to try out when I know more about my own project. Once I have a bit more knowledge on the material performance and the limiting factors it would be good to see if I could use this combined with curvature analysis tools to put limits to the iso curves, thereby limiting the form. I would also like to look further into my water tube carrying networks and how they may be linked to the structural model I have explored. It would be interesting to define points randomly along the concrete structures and use these as weave points and fixing points for the water tubes. Or in complete contrast strictly define a pattern that can be draped over the structure. The water tubes could fall into the space, form curtains, walls or screens. Entire walkways could even be hung from the concrete tubes . I imagine a space filled with constantly shifting light bouncing off these spiralling supports that encourages you to follow the fluid movement wherever it goes. In terms of the geometry of the supports it would be good to look at additional scripting to be able to use the variable nRings so that all points are called no matter how many rings. It would also be good to go into greater detail for example I have learnt throughout this module controlling radii in relation to angles and I could use this to make sure that there is no overlap of tubes at each ring and that a component could be manufactured as a ring with enough holes for each tube to pass through evenly spaced. I would then need to explore the end conditions and meeting points of several supports. I would finish by taking a look at a larger scale and think about the placement of the supports in relation to the rest of the festival and the immediate context - can they draw people in or raise the eye level up, how can they influence my overall plan? I was beginning to look into growth scripts and averaging vectors in order to direct movement. In processing I could set up a series of vectors relating to the festival plan and split my plan up from a central space spiralling out in the average direction of the local context.
Michael Clarke
pg. 49
Digital Representation_Envisioning Architecture
pg. 50
Page No.
Appendix A Model 1 : Using straight lines to define a curve through 90째
06
Model 2: Using straight lines to define a curve through 360째 / generating polygons
07
Model 3 : Using a revolution to define a 3D shape that fits perfectly within a polar array
08
Model 4 : Using cone geometry to dictate a polar array
10
Model 5 : Constructing a 2D ruled surface
12
Model 6 : Simple 3D ruled surfaces
14
Model 7 : Twisted tower
18
Model 8 : Creating a ruled surface feature
20
Model 9 : Hyberbolic Vaults
21
Model 10: Vault series, arraying a created feature
22
Model 11: Decorative Stone - using a polygon as the basis for a feature
24
Model 12: Decorative vaults - using the created feature
25
Model 13: Hyperbolic Cathedral
25
Model 14: Scripting and coding a 3-dimensional branching structure
32
Model 15: Helical tube arrays
40
Michael Clarke
pg. 51