wiki.ksteinfe.net
Personal tools
 

Rhinoscript:exercises:pseudoparametric object rewind

From ksteinfeWiki

Contents

Overview

In this exercise, we'll be extending the pseudoparametric formmaking strategy, and utilizing a more generalizable structure for storing data: the 2d array. As a vehicle for this exploration, we'll take on what on it's face may seem like a simple task: to draw lines across the pseudoparametric monster we've been developing. Easy at first, but then we'll see how to transpose those lines - to make them move across the implied surface of our object in the perpendicular direction.

Prerequisites

To complete this exercise, you'll need a solid understanding of:

As well as:

Drawing Lines

You may recall from a previous exercise that in order to draw a curve to rhino, we have to store a set of point locations as an array. Naturally, we can't draw a cruve through points which we haven't determined the location of yet. The same, of course holds true here - let's re-work the code we left off with in the pseudoparametric object exercise so that it draws curves rather than points.

You can see in the code below that we may do so by just altering the "ConchRow" subroutine so that each call to this Sub produces a single rhino curve rather than a series of points.

Option Explicit
Call Main()
Sub Main()
	Dim g
	For g=0.2 To 3 Step 0.2
		Call ConchRow(g,40)
	Next
End Sub

Sub ConchRow(gamma, res)
	ReDim arrPoints(0)
	Dim theta, n
	For theta = 0 To Rhino.Pi()*2 Step (Rhino.Pi()*2)/res
		Dim x,y,z
		x = gamma * sin(gamma) * cos(theta)
		y = gamma * cos(gamma) * cos(theta)
		z = gamma * sin(theta)
		ReDim Preserve arrPoints(n)
		arrPoints(n) = array(x,y,z)
		n = n+1
	Next
	Rhino.AddCurve(arrPoints)
End Sub

2544486849_d580a96613_o.jpg

Implementing a Function Structure

Another approach (and one better suited to our needs) would be to implement a Functionrather than a Sub. Recall that a Function acts just like a Sub, in that it accepts some number of arguments and executes a series of commands. The difference is that a function also gives something back to the context which calls it - it "returns" some piece of data.

We can change the "ConchRow" Sub into a Function as you see below. Now, "ConchRow" computes an array of points, and rather than plotting anything at all to rhino, it simply *returns* this array. Then, whatever context calls the function "ConchRow" can do whatever it likes with this array.

In this case, we simply call the AddCurve method using this data, and plot the curve to rhino - same as before.

Option Explicit
Call Main()
Sub Main()
	Dim g
	For g=0.2 To 3 Step 0.2
		Dim rowPoints
		rowPoints = ConchRow(g,40)
		Rhino.AddCurve(rowPoints)
	Next
End Sub

Function ConchRow(gamma, res)
	ReDim arrPoints(0)
	Dim theta, n
	For theta = 0 To Rhino.Pi()*2 Step (Rhino.Pi()*2)/res
		Dim x,y,z
		x = gamma * sin(gamma) * cos(theta)
		y = gamma * cos(gamma) * cos(theta)
		z = gamma * sin(theta)
		ReDim Preserve arrPoints(n)
		arrPoints(n) = array(x,y,z)
		n = n+1
	Next
	ConchRow = arrPoints
End Function

2544486849_d580a96613_o.jpg

Line Transpose

Now, the fun part. Looking at the resulting form in rhino, it's easy to begin to imagine the surface implied by the collection of the curves which this code produces. But what if we want to draw curves in the other direction - perpendicular to the curves we now see on the screen?

Well, right away you should be able to see the difficulty in such a task - our subroutine is structured the wrong way 'round. At the moment, each call to the "ConchRow" subroutine produces a curve in one direction (based on a set of points) - something like a "row", like the name implies. But what we want is a curve in the other direction (based on a set of points the other way) - something like a "column". Short of producing a "ConchColumn" subroutine which is capable of computing the points the other way around (this would be a difficult set of equations to work out), the best solution is something like the one we used to plot lines in the first place.

Storing 2d Data

Recall when we first learned to plot lines that, in order to plot a line, we had to first compute and store the position of all the points which define it. The same holds true here - before we plot any single "column line" we first have to compute and store the position of all of it's points. In that our only way of computing points is by *row* - that means we have to compute and store *every single point* in the entire shape before we plot any lines at all. Storing every single point in this composition in a structured way means that we *must* use a two dimensional array - one array for storing rows of points, and another for storing *rows of rows* or columns of points. This may sound like a pain, but in the end learning to do this will prove open up a variety of new possibilities for us.

Option Explicit
Call Main()
Sub Main()
	ReDim arrRows(0)
	Dim n
	n = 0
	
	Dim g
	For g=0.2 To 3 Step 0.2
		ReDim Preserve arrRows(n)
		arrRows(n) = ConchRow(g,40)
		n = n+1
	Next
End Sub

Function ConchRow(gamma, res)
	ReDim arrPoints(0)
	Dim theta, n
	For theta = 0 To Rhino.Pi()*2 Step (Rhino.Pi()*2)/res
		Dim x,y,z
		x = gamma * sin(gamma) * cos(theta)
		y = gamma * cos(gamma) * cos(theta)
		z = gamma * sin(theta)
		ReDim Preserve arrPoints(n)
		arrPoints(n) = array(x,y,z)
		n = n+1
	Next
	ConchRow = arrPoints
End Function


Walking 2d Data

You might notice that the code above runs just fine - but does nothing. Actually, it does do something - it computes all the points in our composition and stores those points in a 2d array called arrRows - but then does nothing *with* this data. To do something with this data, we have to walk the 2d array we've created.

Just for tidiness, I'll chop out some of the code in our "Main" subroutine (the part that constructs the 2d array) and place it in a new Function called "ConchGrid".

Walking to Plot Points

Let's start simply and just plot all the points out to rhino.

This gets us *exactly* what we had to begin with... but the order of operations is different. Now, rather than plotting as we go, we compute the position of each point, store that position in an array, and only after *all* the points are computed do we plot something to rhino.

Option Explicit
Call Main()
Sub Main()
	Dim arr2dConch
	arr2dConch = ConchGrid()
	
	Dim n,m
	For n=0 To Ubound(arr2dConch)
		For m=0 To Ubound(arr2dConch(n))
			Rhino.AddPoint(arr2dConch(n)(m))
		Next
	Next
	
End Sub

Function ConchGrid()
	ReDim arrRows(0)
	Dim n
	n = 0
	
	Dim g
	For g=0.2 To 3 Step 0.2
		ReDim Preserve arrRows(n)
		arrRows(n) = ConchRow(g,40)
		n = n+1
	Next
	ConchGrid = arrRows
End Function

Function ConchRow(gamma, res)
	ReDim arrPoints(0)
	Dim theta, n
	For theta = 0 To Rhino.Pi()*2 Step (Rhino.Pi()*2)/res
		Dim x,y,z
		x = gamma * sin(gamma) * cos(theta)
		y = gamma * cos(gamma) * cos(theta)
		z = gamma * sin(theta)
		ReDim Preserve arrPoints(n)
		arrPoints(n) = array(x,y,z)
		n = n+1
	Next
	ConchRow = arrPoints
End Function

2544486917_0f8807008d_o.jpg

Walking to Plot Rows

If you understand the structure above, you'll see that plotting lines in rows (as we did before) is easy.

Just looking at the "Main" subroutine (and using the other subs from the code above), below I've created a temporary array called arrTemp and stored a row of points extracted from the 2d array arr2dConch. Once this temporary array is all filled up, I plot it to rhino using the AddCurve method.

Sub Main()
	Dim arr2dConch
	arr2dConch = ConchGrid()
	
	Dim n,m
	For n=0 To Ubound(arr2dConch)
		ReDim arrTemp(Ubound(arr2dConch(n)))
		For m=0 To Ubound(arr2dConch(n))
			arrTemp(m) = arr2dConch(n)(m)
		Next
		Rhino.AddCurve(arrTemp)
	Next
	
End Sub

2544486849_d580a96613_o.jpg

Walking to Plot Columns

From there, it's a simple trick of reversing the way I'm walking. Compare these two "for" loops with the ones above, and you'll see what's going on.

Sub Main()
	Dim arr2dConch
	arr2dConch = ConchGrid()
	
	Dim n,m
	For n=0 To Ubound(arr2dConch)
		ReDim arrTemp(Ubound(arr2dConch(n)))
		For m=0 To Ubound(arr2dConch(n))
			arrTemp(m) = arr2dConch(n)(m)
		Next
		Rhino.AddCurve(arrTemp)
	Next
	
End Sub

2545314366_5476102124_o.jpg