You are currently reviewing an older revision of this page.
This example builds on List Of Points With A Loop Example so it is assumed you completed that before beginning here. Those results will be used as a starting point for this example.
For more examples refer to the GenerativeComponents Concepts page.
In order to describe more complex forms then a straight Line we can use simple Cosine and Sine equations to define the X, Y, Z position of the Point List. To do so we start with the Script from Example 2 with the loop structure in place and add variables of type double for xPos, yPos and zPos.
For now let’s start with xPos and yPos only to specify the Points to form a circle. This is achieved through trigonometry by using Cos for the xPos and Sin for the yPos. The expression below gives us a unit circle, meaning a circle of radius 1.
function (CoordinateSystem cs, int num) { for (int i = 0; i < num; ++i) { double xPos = Cos(360/num*i); double yPos = Sin(360/num*i); Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, 0 ); }
function (CoordinateSystem cs, int num)
{
for (int i = 0; i < num; ++i)
double xPos = Cos(360/num*i);
double yPos = Sin(360/num*i);
Point pt01 = new Point(this);
pt01.ByCartesianCoordinates(cs, xPos, yPos, 0 );
}
To control the radius we create a radius variable of type double as well and multiply the result of Sin and Cos function with the radius to scale the circle to the desired size.
function (CoordinateSystem cs, int num) { for (int i = 0; i < num; ++i) { double radius = 5; double xPos = Cos(360/num*i) * radius; double yPos = Sin(360/num*i) * radius; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, 0 ); }
double radius = 5;
double xPos = Cos(360/num*i) * radius;
double yPos = Sin(360/num*i) * radius;
The result looks like this for a radius of 5 and the number of points set to 25:
With a simple addition we can make a climbing spiral of fixed radius from the circle above. To do so we define the zPos to be a factor of the i variable.
function (CoordinateSystem cs, int num) { for (int i = 0; i < num; ++i) { double radius = 5; double xPos = Cos(360/num*i)*radius; double yPos = Sin(360/num*i)*radius; double zPos = i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } }
double xPos = Cos(360/num*i)*radius;
double yPos = Sin(360/num*i)*radius;
double zPos = i;
pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos );
To make the climbing rate independent from the number of points on the circle we may want to add a total height variable for the spiral and replace the i assignment for zPos with a step that is a fraction of the total height based on the number of points in the circle. The total height could also become another input variable.
zPos will be defined then by the height h divided by the number of steps times the current loop count i.
function (CoordinateSystem cs, int num, double h) { for (int i = 0; i < num; ++i) { double radius = 5; double xPos = Cos(360/num*i)*radius; double yPos = Sin(360/num*i)*radius; double zPos = h/num*i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } }
function (CoordinateSystem cs, int num, double h)
double zPos = h/num*i;
This will allow for changes in the point numbers without that affecting the overall height of the spiral. The spiral with height 20 and 25 points.
The spiral with the same height and 45 Point:
Now that we have a spiral of constant radius we may try to make the radius adjust based on the height of the point to create a more interesting outline. To achieve this we will replace the simple assignment radius = 5 with a Sine expression as well based on the i count. We may want to reduce the range of the Sine function to one that creates positive values only, so that there is no crossing over of the spiral over the central axis. For instance from 0-180 Sine goes from 0 up to 1 back to 0. The radius expression may look like this then.
double radius = Sin(180/num*i)*5;
Where 5 is the scaling factor again for the maximum radius when the sine function returns 1.
In the script it will be:
function (CoordinateSystem cs, int num, double h) { for (int i = 0; i < num; ++i) { double radius = Sin(180/num*i)*5; double xPos = Cos(360/num*i)*radius; double yPos = Sin(360/num*i)*radius; double zPos = h/num*i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } }
This creates a spiral like this with its start Point and its End Point at x and y = 0
If we think of the spiral defining a path on a possible surface for a tower for instance remotely similar to freeform towers such as Foster’s Swiss Re or Jean Nouvel’s tower in Barcelona, we may want to adjust the range 0-180 in such a way that the spiral does not start at 0 at the towers base. We could reduce the range to 80-180 for instance. To do so we will scale the loop range defined by I to cover the difference between 80 and 180 = 100 and then shift those results by 80 so the start value is 0+80 =80 and the end value 100+80=180
This gives us the expression:
double radius = Sin ( (100/num*i)+80 ) *5;
and integrated in the overall script:
function (CoordinateSystem cs, int num, double h) { for (int i = 0; i < num; ++i) { double radius = Sin ( (100/num*i)+80 ) *5; double xPos = Cos(360/num*i)*radius; double yPos = Sin(360/num*i)*radius; double zPos = h/num*i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } }
Produces the desired spiral that has a wide base that widens further in the beginning but towards the top converges to a point.
In the next step we will create a variable number of Spirals in a circular pattern to create a Point cloud we could use to define a surface. To achieve this we add a second for loop surrounding the inner loop that is used to start each spiral at a different point in the circle.
First we add the outer for loop using j as the counter variable to not conflict with i which we already use. Remember to adjust the closing brackets to come after the closing bracket of the inner for loop. To make the script more readable use the indention tool as shown in the previous example to shift the inner for loop to the right. Also another input argument was added to define the number of spirals around the perimeter of the tower, it is called spNum and is again of Type int.
The script should then look like this:
function (CoordinateSystem cs, int num, double h, int spNum) { for (int j = 0; j < spNum; ++j) { for (int i = 0; i < num; ++i) { double radius = Sin ( (100/num*i)+80 ) *5; double xPos = Cos(360/num*i)*radius; double yPos = Sin(360/num*i)*radius; double zPos = h/num*i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } } }
function (CoordinateSystem cs, int num, double h, int spNum)
for (int j = 0; j < spNum; ++j)
We need to now adjust our xPos and yPos definition to take the changing starting Point of the spirals into account. We essentially shift the value inside the Sine and Cosine function with each new spiral by a fraction of the overall 360 circle. Lets define this as the variable shift and define it again as a fraction of the overall circle 360 (360/spNum – where spNum is total number of spirals) multiplied by the spiral number counter from the outer for loop j.
double shift = 360/spNum*j;
We then have to add this shift value to the values in the Sine and Cosine expression – this will look like this:
double xPos = Cos((360/num*i) + shift)*radius; double yPos = Sin((360/num*i) + shift)*radius;
double xPos = Cos((360/num*i) + shift)*radius;
double yPos = Sin((360/num*i) + shift)*radius;
and in the overall script:
function (CoordinateSystem cs, int num, double h, int spNum) { for (int j = 0; j < spNum; ++j) { for (int i = 0; i < num; ++i) { double shift = 360/spNum*j; double radius = Sin ( (100/num*i)+80 ) *5; double xPos = Cos((360/num*i) + shift)*radius; double yPos = Sin((360/num*i) + shift)*radius; double zPos = h/num*i; Point pt01 = new Point(this); pt01.ByCartesianCoordinates(cs, xPos, yPos, zPos ); } } }
If we close the script editor and adjust our FunctionArguments to take a forth value to something like this {baseCS, 45, 20, 10} where the new value 10 stands for the number of spirals around the circle we get the following:
This example has shown how to create a simple List of Points in a spiral patterns. To use these points for definition of a surface or even a BSplineCurve we need to structure the Points differently then in a simple List, which is explained in the GC - Scripting Data Structures for Use with Features.