ARCH 653 - Project 2: Geodesic Domes in Dynamo
Fig. 1 - 4v, 8v, and 16v frequency parametric geodome |
This exercise can be considered as part 2 of "ARCH 653 - Project 1: Modeling Parametric Geodesic Domes in Revit Using Eden Project As An Example". I will explain how to model a similar geodome (geodesic dome) to the one used Project 1, but this time we will be using coding and visual programming in Dynamo. Also, I will be showing some useful parametric controls using the powerful features of Dynamo.
Step 1: Modeling a geodome through coding
The same concepts from Project 1 were used in writing the code for modeling a geodome in Dynamo. The method used in this step was first developed by Vikram Subbaiah from Dynamo Community Forums at http://dynamobim.org/forums/forum/dyn/. I posted the complete code for modeling a 4v geodome below with documentation in green color to explain the details:
//The first step is to create an icosahedron. The variable R is used to define the radius, and it can have a value controlled by an Integer Slider:
r=R-(R*0.001);
rad=(r/Math.Sin(72))/(2*Math.Sin(36));
theta=List.DropEveryNthItem(0..396..36,2,0..1);
p1=Point.BySphericalCoordinates(CoordinateSystem.Identity(),90-Math.Atan(0.5),theta[0],rad);
p2=Point.BySphericalCoordinates(CoordinateSystem.Identity(),90-Math.Atan(-0.5),theta[1],rad);
g1=List.Flatten(List.AddItemToEnd(Point.ByCoordinates(0,0,r)<1>,(List.DropItems(List.Sublists(p1,0..1,1),-1))<2>),1);
g2=List.Flatten(List.AddItemToEnd(Point.ByCoordinates(0,0,-r)<1>,(List.DropItems(List.Sublists(p2,0..1,1),-1))<2>),1);
g3=Flatten(Transpose({List.DropItems(List.Sublists(p1,0..1,1),-1),List.DropItems(p2,-1)})<1>);
g4=Flatten(Transpose({List.DropItems(List.Sublists(p2,0..1,1),-1),List.DropItems(p1,1)})<1>);
s1=Surface.ByPerimeterPoints(List.Flatten({g1,g2,g3,g4},1));
//We will now make a sphere that also uses the variable R. The idea is to inscribe the icosahedron inside the sphere:
sp=PolySurface.BySolid(Sphere.ByCenterPointRadius(Point.Origin(),R));
//The first step is to create an icosahedron. The variable R is used to define the radius, and it can have a value controlled by an Integer Slider:
r=R-(R*0.001);
rad=(r/Math.Sin(72))/(2*Math.Sin(36));
theta=List.DropEveryNthItem(0..396..36,2,0..1);
p1=Point.BySphericalCoordinates(CoordinateSystem.Identity(),90-Math.Atan(0.5),theta[0],rad);
p2=Point.BySphericalCoordinates(CoordinateSystem.Identity(),90-Math.Atan(-0.5),theta[1],rad);
g1=List.Flatten(List.AddItemToEnd(Point.ByCoordinates(0,0,r)<1>,(List.DropItems(List.Sublists(p1,0..1,1),-1))<2>),1);
g2=List.Flatten(List.AddItemToEnd(Point.ByCoordinates(0,0,-r)<1>,(List.DropItems(List.Sublists(p2,0..1,1),-1))<2>),1);
g3=Flatten(Transpose({List.DropItems(List.Sublists(p1,0..1,1),-1),List.DropItems(p2,-1)})<1>);
g4=Flatten(Transpose({List.DropItems(List.Sublists(p2,0..1,1),-1),List.DropItems(p1,1)})<1>);
s1=Surface.ByPerimeterPoints(List.Flatten({g1,g2,g3,g4},1));
Fig. 2 - Icosahedron |
//We will now make a sphere that also uses the variable R. The idea is to inscribe the icosahedron inside the sphere:
sp=PolySurface.BySolid(Sphere.ByCenterPointRadius(Point.Origin(),R));
Fig. 3 - Sphere |
//This is a very important step. It is the triangulation function that will divide the triangles of the icosahedron into additional triangles. It is a good idea to place this in a separate Code Block as a Function:
def tri(sur:var)
{
c1=sur.PerimeterCurves();
p1=c1.PointAtParameter(0);
p2=c1.PointAtParameter(0.5);
s1=Surface.ByPerimeterPoints({p1[0],p2[0],p2[2]});
s2=Surface.ByPerimeterPoints({p1[1],p2[1],p2[0]});
3=Surface.ByPerimeterPoints({p1[2],p2[2],p2[1]});
s4=Surface.ByPerimeterPoints({p2[0],p2[1],p2[2]});
return={s1,s2,s3,s4};
};
//Once we have our triangulation function set up, we can triangulate the icosahedron
s2=tri(Flatten(tri(s1)));
c1=s2.PerimeterCurves();
Fig. 4 - Triangulation |
//Then we can get the points at each vertex:
p3=c1.PointAtParameter(0);
Fig. 5 - Triangulation points |
//Now we can project the points on the surface of the sphere:
p4=Flatten((p3.Project(sp,Vector.ByTwoPoints(Point.Origin(),p3)))<1><2>);
Fig. 6 - Projection of the points on the sphere |
//To create a geosphere, all we need to do is to make triangle surfaces out of the projected points:
s3=Surface.ByPerimeterPoints(p4);
Fig. 7 - Geosphere |
//The final step is to turn the geosphere into a geodome:
h1=Flatten(List.FilterByBoolMask(s3,s3.PointAtParameter(0.5,0.5).Z<0)<1>)[1];
We can make a simple adjustment to the code to make a 8v or a 16v frequency dome. The idea is to use the same recursive process illustrated in Project 1. To make a 8v frequency dome, simply replace this portion of the code:
s2=tri(Flatten(tri(s1)));
With this:
s2=tri(Flatten(tri(Flatten(tri(s1)))));
This concept can also be applied to make 18v frequency or higher frequency dome.
s2=tri(Flatten(tri(s1)));
With this:
s2=tri(Flatten(tri(Flatten(tri(s1)))));
This concept can also be applied to make 18v frequency or higher frequency dome.
Step 2: Placing custom Adaptive Component panels on the geodome
It would be very useful to automatically place triangular Adaptive Components representing panels throughout surface on the geodome. The design of the panels can be changed as a Revit Family file and their size and number will automatically update based on the radius (R) or the frequency (#v) of our geodome in Dynamo. This can be done by first getting the vertex points of each triangle in the geodome by using the Face.Vertices and the Vertex.PointGeometry Nodes in Dynamo. Once we do that, we can load our Adaptive Components from Revit into Dynamo using the Family Types and AdaptiveComponent.ByPoints Nodes. This step is illustrated in (Fig.10).
Fig. 9 - Adaptive Component panel in Revit with three Adaptive Points |
Fig. 10 - Placing panels on the geodome using Dynamo |
Step 3: Changing the color of each panel based on the sun's direction
I will briefly explain how we can color the geodome's triangle panels based on the sun's direction. We can get the Normal vector of each triangle panel by first getting the centroid point of each panel, then we can use the Surface.NormalAtPoint Node in Dynamo. If we have the sun direction, we can use the product of the sun direction vector and each triangle panel Normal vector for coloring each panel differently. This step is further illustrated in (Fig.11).
Fig. 11 - Panel color based on sun direction |
(Fig.12) below shows how the final result looks in Revit. There is still room for improvement, such as using conditional statements (IF,ELSE) to control the geodome through coding, adding structural beams using the BeamByCurve Node, or improving the coloring consistency. But for know, I hope that we all learned something that could help our future geodesic endeavors!
Fig. 12 - Final result in Revit |
Here is a video explaining the process: