Читать книгу Grasshopper: Visual Scripting for Rhinoceros 3D - David Bachman - Страница 9

Оглавление

2

Lists

A Simple List

As we saw in the previous chapter, wires in a Grasshopper script represent the flow of information between components. In each of the scripts of the previous section, there was a single piece of information passing through each wire. However, one of the things that makes Grasshopper powerful is that wires can simultaneously contain multiple pieces of information in a list. We illustrate this in our next example.

One of the primitive surfaces in Rhino is a torus, or donut shape, as in Figure 2.1. Unfortunately, at the time of this writing this has not been incorporated as a Grasshopper primitive surface. Perhaps the easiest way to make such a surface is to create a pipe around a circle, just as when we made a cylinder by piping a line segment in the previous chapter. Here we will use a different method as an illustration of a basic use of lists.

The torus in Figure 2.1 was made with the script of Figure 2.2. To create this script, start by dropping a Circle component (Curve tab, Primitive panel) on the canvas. Connect the “P” input to the output of an XZ Plane component (Vector tab, Plane panel). Then right-click on the “O” input of the XZ Plane component, and choose “Set one Point.” Select the point (3, 0, 0) in Rhino’s front view. Now, as shown in the figure, connect the output of the Circle component to the input of a PolarArray component (Transform tab, Array panel). By default this component creates 10 copies of its input that are obtained from the original by rotating around the Z-axis. You can change the number of copies at the “N” input, and the axis of rotation by choosing a different plane at the “P” input.


FIGURE 2.1. A torus generated by Grasshopper.

Next, connect the “G” output of the PolarArray component to the “C” input of a Loft component (Surface tab, Freeform panel). Notice that the new wire looks like a double-line, rather than a single one. This is a visual representation of a list of objects passing through the wire, rather than a single object. The Loft component expects such a list, and tries to create a surface through all of these input curves, in sequence. In the Rhino viewport you should see a surface that looks like a letter “C.” It is not quite a torus because the loft operation did not connect the first input curve to the last. To fix this, attach a Loft Options component (Surface tab, Freeform panel) to the “O” input of the Loft component. Then, right-click on the “Cls” input, and select “Set Boolean.” Change from the default setting to “True,” and the surface in the Rhino viewport should change to a complete torus.


FIGURE 2.2. A Grasshopper script that creates a torus.

Data Trees: Lists of Lists

A single wire can even contain a list of lists, called a data tree. We will use this idea to turn Grasshopper and Rhino into a 3D graphing calculator.

Suppose, for example, you want to graph the function f (x, y) = x2y2. First we’ll create a grid of points in the XY-plane, and then we’ll use the function f (x, y) to obtain Z-values for these points. Finally, we’ll feed this grid into a special Grasshopper component to create a surface.

To make a grid of points, begin with a Construct Domain component (Math tab, Domain panel). This component outputs an interval of real numbers, with the default being the interval [0,1]. As in Figure 2.3, connect its output to the input of two Range components (Set tab, Sequence panel). Each of these creates a list of N + 1 numbers in the given interval, where the default value of N is 10. Connect the outputs of both of these components to the X and Y inputs of a Construct Point component (Vec tab, Point panel). Notice the new wires are doubled, indicating the flow of a list of numbers through each, rather than a single number. When both lists are given to the Construct Point component, a point is created using the first element of both lists, then another point with the second elements, etc. The result is thus a diagonal line of points, as shown on the left in Figure 2.3.


FIGURE 2.3. Creating ten points in the unit square.

Now right-click on the N input of the second Range component and change its value to 15. The result is shown in Figure 2.4. As before, the first numbers coming in to the X and Y inputs are used to create a point, then the second numbers, etc. However, we run out of values of X before running out of Y values. To deal with this Grasshopper will simply repeat the last X input and match it to the rest of the Y inputs.

To create a grid of points, right-click on the output of the second Range component, and select “Graft.” This changes the output from a single list of 16 numbers to 16 lists, each with a single number. The fact that the output is a list of lists is now indicated visually by a wire that is a dashed double line (see Figure 2.5). Now the Construct Point component sees 16 lists coming in to the Y input and a single list coming in to the X input. As in the previous example, since these numbers are different it will replicate the data coming in to the X input as many times as it needs to in order to match it to each thing coming in to the Y input. Thus, the X list will be matched to everything in the first Y list (a single number), and then again to everything in the second Y list (another number), etc. The result will be an 11-by-16 grid of points, as shown in Figure 2.5.


FIGURE 2.4. Illustrating the effect of different sizes of input lists.

To make the result a little more interesting, connect the outputs of the Range component to the x and y inputs of an Expression component (Math tab, Script panel). Then, double-click on the Expression component and type “x^ 2-y^ 2.” Finally, connect its output to the Z input of the Construct Point component, as in Figure 2.6. The result is a grid of points on the graph of the equation z = x2y2.


FIGURE 2.5. Creating a grid of points in the unit square.


FIGURE 2.6. Creating a grid of points on the graph of x2y2.

As a final step, connect the output of the Construct Point component to the “P” input of a Surface From Points component (Surface tab, Freeform panel). This component expects a list of points, rather than a list of lists. To change the input data structure back to a single list, right-click on the “P” input and select “Flatten.” Finally, set the “U” input to 16, indicating that the surface to be created will come from rows of 16 points. As in Figure 2.7, you should now see the graph of the surface z = x2y2 in the perspective viewport.


FIGURE 2.7. Creating the graph of the equation z = x2y2.

A Useful Trick: Flipping Data Trees

In the previous section we saw how to create a grid of points by grafting one list of numbers onto another, creating a list of lists (i.e. a data tree) of points. In Figure 2.8 we pass such a data tree to an Interpolate component (Curve tab, Spline panel). This component creates a NURBS curve through the points of a list that is given to its V input. When a list of lists is fed to the V input, the component will create a list of curves. The first curve is determined by the first list of points, the second curve by the second list, etc.


FIGURE 2.8. Interpolated lines through a list of lists of points.

Sometimes a data tree is not organized correctly. In some cases you will want to restructure the data into a new list of lists where the first list consists of the first elements of the original data tree, the second list comes from all the second elements, etc. This can be accomplished with the Flip Matrix component (Set tab, Tree panel). The effect is shown in Figure 2.9.


FIGURE 2.9. A simple example showing the effect of flipping the data tree.

We use this idea to create an interesting family of curves on a torus. Consider the script of Figure 2.10. The script begins with a simple Circle component (Curve tab, Primitive panel). Here the R (Radius) input has been set to the value 2. Next, we pass to a Perp Frames component (Curve tab, Division panel) to create a list of 10 planes perpendicular to the original circle (more on this component in Chapter 4). These planes are then given to another Circle component, creating 10 smaller circles or radius one, with one circle in each plane. Each of these circles is sent to a Divide Curve component (Curve tab, Division panel), which creates a list of 10 points on each curve. At this point we have 10 lists of 10 points. The first list is comprised of the points on the first circle, the second list are the points on the second circle, etc.


FIGURE 2.10. A more interesting example using the Flip component.

If we were to send this data tree directly to an Interpolate component the result would be the same 10 circles of radius one. To create the more interesting set of curves shown in the figure, we first use the Flip Matrix component before passing the data tree to the Interpolate component.

Grasshopper: Visual Scripting for Rhinoceros 3D

Подняться наверх