Paul N Jeffries

avatar

Jun 242014
 

Everything that we have covered so far could have been achieved, with perhaps a little more hard work and head-scratching, using grasshopper without scripting. However there are certain kinds of algorithm that cannot be achieved within native grasshopper without the use of scripting or specialist plug-ins.

Perhaps the most prominent category of these algorithms are those which rely on recursion in order to generate forms with self-similarity such as fractals, L-systems and so on.

In computer science, ‘recursion’ is a term used to refer to functions whose definition includes a call to itself. For example:

C#5_1

(Whatever you do, don’t try to actually run this snippet – this is an example of infinite recursion and it will keep going ‘forever’ – until your computer runs out of memory and crashes!)

When a recursive function is called, it will perform a set of actions which includes calling itself – which will then perform a set of actions which includes calling itself – which will then perform a set of actions which includes calling itself and so on.

This probably seems like a very strange thing to want to do, but it is actually very useful for a large number of applications. For example, when the computer is parsing your code in the first place, it will recursively break each line down into smaller and smaller chunks until it reaches individual commands that it can then understand and execute.

Geometrically it is ideally suited to generative fractal patterns, where the overall pattern contains many smaller copies of itself. In this example we are going to use it to create a simple fractal branching pattern where a line sprouts two more lines from one end, each of which will then sprout two more lines, each of which will then sprout two more lines and so on.

C#5_2

To begin, create a new C# component as well as a line parameter component and three sliders. On the C# component, set up four inputs as follows: firstly an input called ‘ln’ with it’s type hint set to ‘Line’, which will be used to put in our starting line. Connect the line to this. Next, an input called ‘ang’, which will control the angle of our branches and an input called ‘fact’, which will control the length of our branches – both of these should be of type ‘double’ and should be controlled by two of the sliders. Finally, an input called ‘it’ which will control the number of times the fractal structure will branch. This should be an integer type – set the last slider up accordingly and connect it to the input.

C#5_3

Looking at the script, our RunScript function should now look something like this:

C#5_4

However to begin with we’re not going to touch RunScript. In order to use recursion we’re going to need to define our own function that we can later on call within itself. We’re also going to need somewhere to store our outputs that we can populate from that other function. So, in the white space below RunScript, write:

C#5_5

Here we are declaring two things: a list of lines called outList and a new subroutine called ‘Branch’. Because outList is not declared inside a function its scope is not limited to any one function – we can access it from anywhere inside this component.

The Branch subroutine has pretty much the same inputs as our component itself – a Line ln, two doubles called ang and fact and an integer called it.

Back in RunScript, let’s initialise our outList and set it up to be output to A and hook up our Branch subroutine to the component’s inputs:

C#5_6

Now, when our component starts, Branch() will be called. However, it won’t do anything yet – let’s change that.

Let’s begin by making Branch generate the new lines that branch out of the original. In your Branch function, write the following:

C#5_7

This is a multi-step process, but is really very simple. In order to determine the direction of our branches, we need to find the direction of our starting line. We do this by extracting the front and end points of our line – accessed through the ‘From’ and ‘To’ properties. We then subtract the start from the end point to get the vector that describes the direction and length of the line. Points and Vectors have overloaded operators, meaning that you can use certain mathematical symbols (+,-,* etc.) with them as if they were numbers, in this case to perform vector mathematics.

C#5_8

From this vector we can now calculate the vectors that will describe the path of our branching lines. We do this by first making a copy of vAB, then rotating it by our input angle ‘ang’ and then finally by scaling it by our scale factor ‘fact’. To rotate the vector we use the built-in Rotate() function. This takes in two parameters: the first of which is the angle and the second is the axis about which the rotation will take place. In this case we are only working on the XY plane so we can just rotate about the Z axis – if you wanted to create a 3d branching structure you could do so by replacing this with something else. To represent the Z axis, we create a new vector with components (0,0,1) – i.e. a unit vector pointing directly up along the Z axis.

C#5_9

Now that we have the vectors that provide the direction and size of our branching lines, all we need to do is find the end point of those branches by adding the vector to the end point of our initial line. We can then create a new line between the end point of the old line and the new end-point and we have got our branch. Now all we need to do is add it to our outList so that it will be output from the component.

C#5_10

If you close the script, you should see that from our initial line we have created a ‘Y’ shape. However it only branches once no matter what value we put into ‘it’ because we have not yet implemented the recursion.

C#5_11

Fortunately, recursion is much easier to implement than it is to understand. All we need to do is to add a call to our branch function at the end of the function itself, passing in our new branches instead of the starting line:

C#5_12

So, now each branch will generate two more branches, each of which will generate two more branches, each of which will generate two more branches… and so on. The problem that we have now is that this will continue infinitely – if you let this script run then it will keep going until you run out of memory and then it will crash your computer. To prevent this from happening we need to stop the recursion after a certain number of branches. Note that when we call Branch() in the sample above we are also passing in ‘it – 1’ rather than ‘it’ – so each time we branch ‘it’ in the new function will be one smaller than ‘it’ was in the parent function. We now just need to stop the function from executing once ‘it’ reaches zero by wrapping the whole thing in an if statement.

C#5_13

Now by adjusting the slider which controls it we can control the number of levels of recursion.

C#5_14

We can control the form of the resulting fractal by adjusting the scale factor and the branching angle to generate a range of different patterns.

C#5_15 C#5_16 C#5_17

Note that this is only one example of what is possible with recursion.  You could generate any fractal pattern you like using the same basic structure but changing the geometric operations being performed.  Recursion is also a useful tool whenever trying to program any system that needs to branch (whether geometrically or conceptually) – for example parsing text or mathematics, finding connecting paths through a network and so on.

The example file for this session can be downloaded here:

AADRL C# Example 5 – Fractal Branching

Jun 052014
 
C#4_9

In this session, we will be examining how to build up a custom surface from scratch in C#.  We will first generate a grid of points with randomised z-coordinates.  We will then create curves that pass through columns of those points and eventually loft between these curves to create a surface.

To begin with, create a new C# component and set up three inputs.  These will be called ‘x’, ‘y’ and ‘s’ and should all have their type hint set to ‘int’.  The x and y inputs will be used to control the number of points in the grid in the x and y directions.  The s input will provide a seed value for our random number generator – more on that in a minute.  Plug sliders set to suitable ranges into these inputs.  In the example below, I’ve used the same slider for both x and y so that I will get a square grid.

C#4_1

Also add an additional output, B, to the component.

The code for this example is shown below:

C#4_2

Let’s go through line by line and see what each bit does.

The first thing that we do is declare and initialise an instance of System.Random. This is a class built into the .NET framework that acts as a random number generator.  We will use it later in order to randomise the z coordinates of our points.

C#4_3

As a constructor argument we give it our s input.  To explain what this does it is necessary to explain a little bit how random number generators work.  In a literal sense; they actually don’t work in that the numbers that they output are not genuinely random.  It is not possible (without special hardware, at least) for a computer to actually generate numbers which are truly random.  Instead, an algorithm is used which outputs a sequence of numbers which appear to be random.  To set it off, the generator needs a seed value which acts as an initial input to the generation algorithm and determines the sequence of numbers which will be produced.  If you put the same seed value in twice, you will get the same sequence of numbers out the other end each time.

Generally you want the sequence of numbers to be different each time you run the generator, so for most applications a seed value is used which is unlikely to be repeated (for example; the current system date and time).  However, for parametric design purposes we usually want consistent outputs and so we specify a particular value that we can control as a seed.

Next, we’ll create a new list to hold the curves that we’re going to create:

C#4_4

Not much to say about that, so we’ll move on to the next step – generating a grid of points.  To do this we use two for loops, one inside the other:

C#4_5The outer loop goes through each possible x-coordinate (represented by the variable i) up to our x input variable.  For each individual value of i the inner loop will run, which goes through each possible y-coordinate (represented by the variable j) up to our y input variable.  This will give us a complete set of x and y coordinates describing an x-by-y-size grid with a spacing of 1 unit between each row and column.

We are later going to create a curve that goes through all the points in a column, so within the outer loop we create a list of points called colPoints in which to temporarily store all of the points in that column.  Within the inner loop we add a new Point3d to the end of that list, using i as the x-coordinate and j as the z-coordinate.  For the z-coordinate we use the random number generator rng we created earlier.  There are multiple ways of getting a new random number from System.Random – the NextDouble() function we use here will output the next number in the generated sequence expressed as a double between 0 and 1.

We next use Curve.CreateInterpolatedCurve to create a new curve through the current column of points and we store that new curve in our curves list.  We give it a degree of 3 because we want the curve to be smooth – check out the very first Rhino session notes for a refresher on how curve degrees work.

C#4_6The last } here closes the outer loop.  Note that because we declared our colPoints list inside this loop once the current loop is over it will go out of scope and will be deleted, along with all the points it contains.  That’s OK – we don’t need it anymore.  Our curve that we’ve created was also declared inside the loop and we can no longer access it using that variable name, but because we placed a reference to it in the curves list (which was declared outside) the object itself will not be deleted and we will still be able to use it.

The next (and penultimate) step is to loft through all of the curves in order to create our surface using Brep.CreateFromLoft.

C#4_7Note that the output type from CreateFromLoft is a Brep[].  ‘Brep’ is short for Boundary Representation and is a general class that can represent surfaces, polysurfaces, solids etc.  The [] after the type name indicates that this is an array of Breps.  This is because, even though in this case the loft operation will only create a single surface, it is possible, depending on the input curves, for this function to create multiple polysurfaces.

The first input parameter is our list of curves, which will be lofted to create the surface.  For the next two we enter Point3d.Unset – these arguments allow us to specify points at which to begin and end our loft surface.  We don’t want to do that, but we can’t leave these inputs blank so we instead use Point3d.Unset to let the function know that we only want to use the curves.  The next input is the LoftType enum, which offers us the same options for creating different types of loft that we would get if we were manually using the Rhino ‘Loft’ command.  The final input is a boolean that determines whether the lofted surface should be closed – i.e. whether the end of the surface should loop back round to the start and join up.  We don’t want that, so this is false.

Finally, we output our generated curves and brep to the A and B outputs respectively:

C#4_8That’s it!  Close the code and we should have a freshly generated randomised surface:

C#4_9

Try adjusting the seed value and see how each value produces a very different result, but that we can return to an earlier option by setting the same seed again.

If your surface looks a bit crappy in the grasshopper preview, try adjusting the Preview Mesh Quality option.  Higher quality settings will look much better and display more detail, but will take longer to generate a rendering mesh from the surface (graphics cards cannot draw NURBS surfaces directly – they must be meshed before they can be rendered).

C#4_10

The definition file for this example can be downloaded here:

AADRL 2014 C# Example 4

 

May 142014
 

Example 3B: Dividing and Constructing Curves

In the previous example we used a standard Divide Curve component to obtain evenly spaced points along our input curves.  However, for the sake of completeness and also to demonstrate the way that curves can be manipulated in code, let us now modify our script so that this part of the definition is also done by our script.

So, from the end point of the last example, delete the Divide Curve components and plug the input curves directly into our script component’s x and y parameters.  You will need to edit x and y so that they use Item Access rather than List Access (since we are now only putting in one thing to each input) and change their type hints from Point3d to Curve.  Also add a new input called ‘n’.  Set its type hint to integer – this is going to be our input to control the number of divisions along the curve.  Add a slider with its rounding set to integer to provide an input for this parameter.

C#3_1

Now we need to include the code to subdivide the line.  Since we are going to want to do exactly the same thing to both of our curves but we don’t particularly want to have to write out the same bit of code twice, we will create a new function to do this that we can reuse.

Below the RunScript subroutine that we have been writing in so far there is a blank section where you can add your own subroutines to the component.  Within this section, write the following:

C#3_2

This is a function called ‘SubdivideCurve’ which takes in a curve to subdivide (called ‘x’) and an integer number to subdivide the curve by (called ‘divisionNo’) and returns a list of Point3ds.  This is all determined by the top line which declares the inputs and outputs of the function.  (Some functions (such as ‘RunScript’) have their return type defined as void, which means that they are subroutines which don’t return anything.)

The code that will be run when this function is called is contained within the curly brackets below.

The first step is to declare an array of doubles called ‘tX’.  In C# an array is declared by a pair of square brackets after the type name.  If you wish the array to have a specific size you can include a number inside these brackets to create an array of the specified size.  Generally speaking it’s better to use lists rather than arrays for most things, since they can be resized dynamically and have a larger range of helper methods, however sometimes you have to use arrays because that’s what certain functions give you.  One such function is the one we are using here – the DivideByCount function of curves.

C#3_3

This function takes in the number of divisions and a Boolean which tells it whether or not to include the ends of the curve in the output (in this case we want it to, so the value we put in here is true).  What we get out of this function is an array of numbers (i.e. doubles)  which denote the positions of the division points along the curve.  However, it does not actually give us the points themselves.

The next step is to extract those points from the curve based on the parameters DivideByCount has just given us.  To do this we need to loop through the array of parameters and convert them into the actual points using the PointAt() function of curves.  We then add that point to a list for output.

C#3_4

You use the same approach to extract other information from curves.  For example rather than PointAt() we could use TangentAt() to get the tangent vector of the curve at the specified parameter, FrameAt() or PerpendicularFrameAt() to get a frame plane at that point and so on.

Finally, we use the return keyword to specify what we want our function to produce.  In this case we output our list of points that we have just populated.  After this line the function will end.

C#3_5

Now to use our new function in the RunScript function (otherwise, it will never be run!).  To do this we need to change the first two lines of the function to

C#3_6

This will call our new function, pass in our curves x and y and use n as the number of subdivisions.  The results of that function will then be stored in ptsX and ptsY.  The rest of the script can then run exactly as before – the only difference is that we are creating the subdivision points ourselves.

The complete script should now look like this:

C#3_7

As a final step let us add in an additional output to create a polyline along each side of our zig-zag to replace our original input curves.  Adding a new output is done in much the same way as adding a new input – zoom in until the ‘+’ and ‘-‘ icons appear and the click the bottom ‘+’ to add a new output.  Unlike the inputs you do not need to specify the type of your outputs – their type is always object, which will take whatever you want to assign to it.

Now, add the following to the bottom of RunScript():

C#3_8

The class Curve, as well as being the type used for defining curve objects, also has a set of static functions which make it easy to set up curves in various ways.  To view these, type “Curve.” – the intellisense window should show a list of available options.  The CreateInterpolatedCurve function works in the same way as the Interpolate grasshopper component – it will take in a set of points and a degree and create a curve with that degree that passes through all of those points.

In this case we use that function to create a curve using our ptsX and ptsY lists with a degree of 1 (meaning that the sections of curves between those points will be straight – for a more conventional curvy line we would use a degree of 3 instead).  Those curves, called polyX and polyY are then output to our new ‘B’ output parameter by first placing them into a list called ‘outputChords’.

C#3_9

The complete script should now look like this:

C#3_10

Mar 262014
 

Example 2B: Switching between two points, If statements

In the last session, we created our own version of the built-in line component.  Now let’s take that previous example and move it a bit beyond what we could have just done with the standard component.  Let’s make it so that the component is smart, and that if we give it a choice between two end points it will pick the one which is closest to the start.

Add a new point to the Rhino document and a new Point parameter in grasshopper that references it.  Now zoom in on the C# component until the tiny + and – symbols appear.  Click on a ‘+’ to add a new input parameter.

C#2_1

Name it ‘PtC’ and set its type hint to Point3d.  Connect our new point to it.

Change the code inside the script component to look like this:

Now lets look at what’s going on here, shall we?

Firstly, we calculate the distance between PtA and the other two points.  The ‘Point3d’ structure has a built-in function to find the distance between the given point and another one.  Functions are subroutines that give an output answer – more on those later.

Once we have these distance values stored we need to compare them and then choose which point to connect to PtA.  This is where if statements come in handy:

 

‘(distAB < distAC)’ is the conditional statement that is being evaluated.  If it is true (i.e. distAB is lower than distAC) then the first block of code will be executed and the code will then skip forwards to after the if statement.  If it isn’t true then the code skips the first block and goes down to ‘else’ and executes the second block of code.

Note that we declare myLine before we go into the if statement without actually assigning anything to it.  This is because variables are only valid inside the scope in which they are declared.  If we declared myLine inside the if statement we could not then use it outside it.

If we try this out by moving our points around you should find that the line now automatically jumps to the closest point.

 

This kind of thing can be very useful for getting your definitions to adapt to different circumstances in an intelligent manner.  We could achieve the same thing in native grasshopper by using a Dispatch or Pick ‘n’ Choose component in conjunction with a function component returning true or false and a bunch of other components computing the distance, but it can often be easier and neater to do it in code, especially when things get more complicated.

 

Example 3A: Creating a truss, Lists and Loops

For performing repetitive operations on a large number of inputs grasshopper has lists and trees, but it still cannot be used for many complex iterative operations that would be relatively easy to implement in code.

This next example takes in two lists of points and iterates through them to draw a zig-zag line between them, as you might want to do to create part of a truss structure.

Firstly we will create two lists of points by subdividing curves.  Draw two roughly parallel curves in Rhino and bring them into grasshopper via some Curve components.  Pass those curves into a pair of Divide Curve components to generate two lists of points.

Now we will bring those two lists into a C# component.  Create a new one and set the type hint for both x and y inputs to Point3d.  Since we are no longer bringing in single values we need to tell the component to treat x and y as lists of objects rather than individual objects.  To do this right click on each input and select the ‘List Access’ option.

If we take a look inside the script editor for that component now we will see that the type of x and y parameters have changed to List<Point3d>.  Lists are generic containers that can be used to hold any other type of object.  The type to be used is defined inside the angle brackets (‘<’ and ‘>’).  They function similarly to arrays but with extra functionality and with the bonus that they will automatically resize themselves when new items are added.  Get used to them because you are going to be using them a lot!

Plug the two lists of points into x and y and in the script editor add:

First of all I rename our inputs ptsX and ptsY by defining new Lists of Point3d variables and assigning x and y to them (the reason why I do this will become clear in example 3B).

Since we are going to create more than one line this time around we need to create a new list to hold them all in one place so that they can all be output to A as a group.  Lists are a type of object so to create one we need to use the new keyword.  We define the type it will contain inside the angle brackets after the type name (in this case, the list will hold lines).  Even though we are using the default constructor and aren’t entering any parameters to initialise the list with, we still have to include a pair of empty brackets when creating the new list.

Next we begin our loop – in this case a for loop, meaning that we are going to iterate a particular variable until a certain condition is met.  The brackets behind the ‘for’ are split into three sections separated by semicolons.

The first part tells the for loop what to iterate.  In this case we create a new integer variable called ‘i’ and set it to a starting value of 0.

Next we tell it when to iterate (and when to stop).  In this case we give it the condition to continue iterating while i is lower than the number of points in ptsX – which we retrieve by using the ‘Count’ property of that list.

This means that when i is larger than or equal to the number of points the loop will exit and continue with whatever is next in the script.  We do this so that the loop will execute once for each item in the list.

Finally, we tell the loop how to iterate.  In this case we use the ++ operator, which in C-like languages means ‘add one to’.  We could also have written this as i += 1 and gotten the same result – each time the loop has executed it will add 1 to the current value of i and start again (provided the condition we just gave it in the middle part is still true).

The next part inside the curly brackets is the block of code that will be repeated by the loop.

We start by picking the points from the list that we want to use.  You can access a particular item from a list by enclosing its index (its position in the list, starting from 0) in square brackets after the name of the list.  In this instance, we are picking the points from ptsX and ptsY that are at position i – meaning that as the loop iterates and i increases we will retrieve every pair of points in the two lists.  We store the points in new variables called ptA and ptB and then draw a line between them the same way as we have done previously.

Once we have created our line we use the Add() subroutine to append that line to the back of our output list.

Finally, outside of the loop, we assign our output list to our output object A.

This example so far will create a ‘ladder’ between the two initial curves by joining equivalently numbered points.  Essentially we have replicated in code Grasshopper’s default data-matching option, where the first item in each list will be processed together, the second in each list also matched and so on.

The next step in creating the ‘zig-zag’ is to also join up the first list of points with an offset of the second list of points.  To do this with grasshopper components we could use the Shift List component to create an offset copy of the initial list.  However, in code we can do this in a more direct (and efficient) fashion.

Add the following to the end of the block of code inside the for loop:

This section of code finds the next (the ‘i+1th’) point in the list ptsY and then creates a line between it and our original ptA, then adds that line to our output.  This will create the diagonals of our zig-zag truss bracing.

However, if we now press ‘OK’ to close the script editor, we will see that something has gone wrong.  The script component has gone red and is no longer outputting any geometry at all!

To find out what has gone wrong hover your mouse either over the ‘out’ output or the small red error speech bubble that will have appeared in the top right of the component.  Doing so, you should get something like this:

Why are we getting this error?  Well, let’s imagine we have eleven points in each of our input lists, stored in locations 0-10.  When i = 10 in our code, ptA will be ptsX(10), ptB will be ptsY(10) and ptC will be ptsY(11), which will be something of a problem because there is no ptsY(11) – our index is outside the bounds of the list.

For our script to run successfully we will need to stop this from happening.  We can do this by placing an if statement around the piece of code we just added to make sure it is not trying to add a diagonal when i is already the last item in the list.

So, our complete script should now look like this:

Which should produce our zig-zag lines:

You can download the example grasshopper files for this session here:

C# Examples 2B & 3A.zip

Mar 192014
 

I’ve made some minor post-challenge tweaks and bugfixes to 7DArrrL, thus making the name even less accurate.  This new version fixes a couple of mistakes I made in my sleep deprived state and polishes off a couple of minor features that I didn’t have time to quite finish.  There are no major new content additions however and it’s basically the same as the same as the 7-day version with a little bit more love and care lavished on it.  Stay tuned, however, to possibly see it morph into a proper game one day.

download
(7DArrrL.zip – 7.85Mb – Requires Java)

Changes:

- Fixed bug where AI ships south of you will mistakenly head away from you rather than towards you (remember kids; always use Atan2 rather than Atan)
- Force generated by sails now uses relative rather than absolute wind speed.  Wind strength, drag factors etc. adjusted to compensate.
- Sails independantly rotate depending on wind direction
- Wind now starts in random direction
- AI ships now slightly more agressive and less stand-offish in combat
- Ships now sink faster and cannot steer while doing so.
- Game now restarts on death

 Day8(3)Day8

Mar 162014
 

(Note: I’ve since released a post-challenge bug-fix version of the game, which you can download here.  I’ve left the download below active for people who are particularly interested in seeing the 7-day version.)

7DArrrL is this year’s attempt at the 7DRL challenge.  It’s a semi-success; I didn’t have time to put in everything I wanted to (my initial plans were massively over-ambitious, I realised about half-way in) but it’s still a playable game, even if only as a high-score challenge/demo of the combat system.  Unfortunately the bits I didn’t get around to doing are mostly the bits that would have made it more of an actual Roguelike.  I quite like what I’v