Rhinoscript:exercises:pseudoparametric objects
From ksteinfeWiki
Contents |
Overview
In this exercise, rather than getting to know a formal structure of code we'll be exploring a more general algorithmic strategy for formmaking - the pseudoparametric object.
I use the term "pseudoparametric" here quite loosely, and only mean to describe some algorithmically generated geometry which may be created based on a discrete set of parameters. Structured in this way, one can repeatedly create and re-create this "object" again and again, each time tweaking the parameters slightly, in order to arrive at an entire "family" of forms (this family is sometimes referred to as the "solution space", but that's a topic for another exercise).
Prerequisites
To complete this exercise, you'll need a solid understanding of:
As well as:
The Pseudoparamertic Form
A pseudoparametic object, when written in code, ought to consist of a single Sub or Function which accepts some number of arguments, and produces some set of geometry based on those arguments. Varying any of the arguments ought to change the resulting geometry in some significant and intelligent way. On it's own, this Sub or Function does nothing - it needs to be called, or utilized in some other area of the code in order to work.
As an example, let's re-work a non-pseudoparametric bit of code into a pseudoparametric form.
The Non-Parametric Code
Below is a mathematic monster created by Nopawan Pansiri at Pratt. You can see from the code and image below that it plots out a series of points in something like a circle, based on two parameters - gamma and res. This is done completely within one subroutine, called "Main".
It's worth noting that in this form, we might try and get to know how the variables gamma and res effect the resulting form through a process of running the script, changing the variables by hand, and then running the script again.
Option Explicit
Call Main()
Sub Main()
Dim gamma, res
gamma = 3
res = 40
Dim theta
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)
Rhino.addPoint(array(x,y,z))
Next
End Sub
Reworked into a parametric form
Now, let's re-work Nopawan's script into a more "parametric" form. Below, I've separated the functionality of her code into two subroutines: "Main" and "ConchRow". You can see that the subroutine "ConchRow" is doing most of the heavy lifting here, and plots out a set of points based on variables (again called gamma and res). This time, however, instead of getting defined within the subroutine in which they're used, these variables are "passed in" via subroutine arguments. Notice how the two variables "gamma" and "res" are never initiated with the keyword Dim, as this is implied by the argument structure of subroutines.
You can see from the images below that exploring the consequences of altering the variables becomes much easier in this form. Rather than running the script again and again, we can simply Call the subroutine multiple times, each time with different arguments.
Option Explicit
Call Main()
Sub Main()
Call ConchRow(1,40)
Call ConchRow(2,40)
Call ConchRow(3,40)
End Sub
Sub ConchRow(gamma, res)
Dim theta
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)
Rhino.addPoint(array(x,y,z))
Next
End Sub
Recursed
Taking this a step further, we can see more clearly the beauty of Nopawan's simple script. Rather than call the "ConchRow" subroutine multiple times "manually", we can do so using a loop structure.
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)
Dim theta
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)
Rhino.addPoint(array(x,y,z))
Next
End Sub
axo view:
top view:
Exploring Parameters Algorithmically
In addition, with a bit more elbow grease, we can really see the benefits of working parametrically. Below, I've added two more parameters to our "ConchRow" subroutine: one for controlling a multiplier I've added to the z-coordinate of each point, and another for controlling an "offset" factor, which displaces the overall composition in space. Varying these two extra parameters at the same time gives us a little family portrait of Nopawan's algorithm.
Option Explicit
Call Main()
Sub Main()
Dim tMult, xOff
For tMult=0.0 To 1.0 Step 0.1
Dim g
Rhino.EnableRedraw(False)
For g=0.2 To 3 Step 0.2
Call ConchRow(g,40, tMult, tMult*50)
Next
Rhino.EnableRedraw(True)
Next
End Sub
Sub ConchRow(gamma, res, thetaMult, xOff)
Dim theta
For theta = 0 To Rhino.Pi()*2 Step (Rhino.Pi()*2)/res
Dim x,y,z
x = (gamma * sin(gamma) * cos(theta))+xOff
y = gamma * cos(gamma) * cos(theta)
z = gamma * sin(theta*thetaMult)
Call Rhino.AddPoint(array(x,y,z))
Next
End Sub
