COMPUTER
AIDED
ARCHITECTURAL DESIGN
Workshop 14 Notes,
Week of November 21 , 2016
Array on Surface, Solar Shading Example With Vectors (DRAFT
NOTES IN PROGRESS)
Within this set of workshop notes are several examples of
copying and translating an object onto a surface using vectors with a
surface's "uv" coordinates. A more complex example
illustrates the movement of a series of solar panels to the altitude
and azimuth position of the sun.
PART I. ARRAYING OBJECT ON A SURFACE
1. Array on Surface
1.1 Create "Rectangular Plane: corner to corner surface" from the
"Surface Creation" palette (second row, first icon), turn the control
points on, and with the Gumball tool translate the lower-left and
upper-right corner points upward so as to create a simple saddle shape.

1.2 Create a torus at the origin of the XYPlane from the
"Solid Creation" palette (third row, first icon) and also place a point
at the origin.

1.3 Open Grasshopper and from the "Params" tab create the following
parameters:
From the parameters tab "startPt" (first row, first icon).
From
the parameters tab and below the geometry pull-down sub-tab, create
parameters for "Srf",(7th row, first icon ), and
"Geo" (
8th row, second icon )
From the parameters tab and above "Input"
sub-tab create integer "int" sliders for "numRows" and
"numCols"
with current value 3 and value range 1 to 40.

1.4 connect the paramters for geometry to the Rhino model:
Right-click on the "Geo" parameter and set it to the torus.
Rick-click on the "srf" parameter and set it to the simple
saddle.
Rick-click on the "startPt" parameter and set it to the point at the
origin.
1.5. Select a Python component from the "Math" tab,
and crreate corresponding input ports for the parameters of 1.4.
"Geo" port with type hint "ghdoc Object when
geometry (rhinoscriptsyntax)"
"surf" port with type hint "Surface"
"startPt" port with type hint "Point3d"
"numRows" port with type hint "int"
"nunCols" port with type hint "int"

1.6. Zoom up to the "Python" component and create an output port "b"

1.7 Within the Python component itself, create the following script as
found in the Grasshopper file arrayObjOnSurf.gh:

Note that in the function "getSurfaceParamPt":
Line 11 creates a "pt" variable at some "u" value from 0 to 1 for
"i/numRows", and a "v" value 0 to 1 for "ii/numCols", and "0".
The value range of these points address the two directions "u" and "v"
on the surface where the total value range is 0 to 1 in each direction.
Line 13 takes this "pt" variable and gets a parametric surface pt and
assigns it to "surfPt".
Line 15 in turn takes "surfPt and and evaluates it to
determine a
3D point in full Cartesian coordinate space and assigns it to "curPt".
Lines 16 and 17 return the total number of 3D points via the list
"ptList"
Note that in the function "transObjectToSurface":
Line 22 gets each curPt from the list of of 3D points on the surface
and
Line 23 creates a translation vector from the original "startPt" to the
given surface curPt.
Line 24 uses the translation vector to translate a copy of the torus to
the given point.
1.8 The resulting surface now is juxaposed the torus in a 4 x 4 array.

1.9 Reducing the scale of the torus and adding 7 rows and 7
columns yields the following result:

PART II: EXTRACURRICULAR EXAMPLES
2.0 Adjust the torus rotation to the surface normal.
Note that in the figure above all the torus figures are juxposed with
the saddle surface in the same orientation as the original torus.
However, in the following figure, the torus has been rotated to be
normal (e.g., perpendicular) to where it located relative to the saddle
surface.

The script in the Grasshopper file arrayObjOnSurfaceNormal1.gh
has been modified from part 1 to incorporate a series of normalized
vectors for the saddle surface (see lines 19 through 21 below). These
surface normal vecturs are returned from procedure "getSurfaceParamPts
in line 23 below.

3.0 Creating a "Boolean" parameter.
3.1 From the "Params" tab and above the "input" area, add a
"boolean" parameter (1st row, second icon) to the Grasshopper canvas
window.
3.2 Add a corresponding input port named "surfNormal" and give it the
type hint "bool".

3.2 Connect the parameter to the input port.
3.3 In the script from part 2, comment out (or remove) line
57 as in the file arrayObjOnSurfaceNormal2.gh.

3.5 Note that togging the "boolean" symbol off reverts the torus copies
to be normal to the x-y plane.

3.6 Togging the "boolean" symbol to on returns the torus
copies to be normal to the surface.

4.0 Solar Shading Array (Extracurricular)
In this illustration, the Grasshopper file pthonSunVectorShaderArray.gh
detemines an array of panels is rotated to match the Sun position such
that they either 1) admits indirect daylight but not direct
sunling to penetrate the panels if the "shade" is on, or 2)
permits direct sunlight to penetrate the panels if the "shade" is off.
It draws upon an internal Rhino function that calculates a
vector representing the sun, translates the vector into "Altitude",
"Azimuth" and "Effective Angle" (see below) calculcations, and adjusts
the shader panels accordingly.
If a boolean variable for "shadeOn"
is set to "true" for spring soltice (March 20, 2016, then the panels
are pendendicular to the direction of the sun:.

If
the boolean variable for "shadeOn" is set to false for spring solstice,
then the panels are parallel to the direction of the sun:

If the sun angle is below the horizon, then the shader panels close so
as to minimize any light penetration:

4.1. The script is initiated with the following input parameters and
types
numRows = number of rows of the shader along the Y axis in the
figure above (int, 1 to 200)
numCols = number of columns of the shader along the X axis in
the figure above (int, 1 to 200)
width = the width of any given panel, (float, 0.1 to 100.0)
depth = the depth of any given panel (float, 0.1 to 100.0)
spacing = row-to-row and column-to-column spacing(float, 0.1
to 100.0)
latitude = latitude for Sun calculation (int, -180 to 180)
longitude = longitude for Sun calculation (int, -90 to 90)
year = year for Sun calculation (int, 0 to 3000)
month = month for Sun calculation (int, 1 to 12)
day = day for Sun calculation (int, 1 to 31)
hour =hour for Sun calculation (int, 0 to 23)
minute =minute for Sun calculation (int, 0 to 59)
second =second for Sun calculation (int, 0 to 59)
GMT-Offset = Greenwich Meant Time Offset (int, -24 to 24)
Shade toggle = determines if shaders are "on" or "off" (Boolean,
"true" or "false")
Correspondingly, input ports are created on a Python script component
within Grasshopper:

Note
that the Python script determines the "Altitude" and
"Azimuth" as
is typical of sun calculations. It also calculates a somewhat
unconventional "Effectve Altitude" of the sun relative to the ground
with respect to the southern elevation of the shader array. That is,
relative to alocation in the Northern Hemisphere, the Sun moves from
east to south to west. The "Effective Altitude" of the sun
relative to the southern elevation of a a building may be relatively at
a
higher angle in mid-morning then it is at mid-day, even if the
"Altitude" is higher at mid-day than it is at mid-morning relative to
the ground surface overall. (Note: the "Effective Altitude"
is not
typically used, but created here just for illustrative purposes. It is
determined by creating a vector from "Y and Z" components of a vector
from the
ground to the sun and measuring its angle with the vector 0, -1,
0.
The Python script is detailed below. It consists of a number of defined
functions
(e.g., "def copyObject", etc.) on lines 9 thorugh 101. The "#main" part
of the script on lines 104 through 128 calls the
defined functions and activates the script. The functions within the
script
on lines 9 through 70 address the calculation the sun position. The
remaining two functions
are "makeShadeUnit" and "makeShadeArray" on lines 72 through 101. The
function "makeShadeUnit"determines the size and angle of the
individual shading unit relative to the sun. The function
"makeShadeArray" copies the shade unit into an array. The details of
this script as a whole are
beyond the scope of these workshop notes. However, the comment lines
and variable names should help to explain how the script works.

4.2 Note that the script can be modified, as in the file pythonSunVectorShaderArray2.gh,
such that the Shader array is vertical rather than horizontal by
changing lines 96 and 97 above of the "def
makeShadeArray"
function as follows:

Thus, if the boolean variable for "shadeOn" is set to "false", then the
resulting shaders appear as follows:

Conversely, if the boolean variable for "shadeOn" is set to "true", the
resulting shaders appear as follows:

In addition, adding
lines 88 and 89 to the function "def makeShadeUnit" has the
impact of
causing the shaders to form a vertical plane if the sun angle is less
than 0 degrees or greater than 90 degrees (the sun is below the
horizon):
