This is the final Capstone Project for which we have completed various exercises during the semester. My capstone project is to create metabolism architecture by recreating the Nakagin Capsule Tower.
![](https://sites.psu.edu/chengyananmetabolismproject/files/2018/04/capsule-2g6jefv-300x293.png)
![](https://sites.psu.edu/chengyananmetabolismproject/files/2018/04/floor-1lwqqvp-300x298.png)
![](https://sites.psu.edu/chengyananmetabolismproject/files/2018/04/repeat-floor-xihb5t-300x298.png)
![](https://sites.psu.edu/chengyananmetabolismproject/files/2018/04/repeat-building-2mux9zf-300x286.png)
![](https://sites.psu.edu/chengyananmetabolismproject/files/2018/04/mirror-building-1jccd5u-300x281.png)
Here is the Python Code:
import rhinoscriptsyntax as rs
import random as r
rs.DeleteObjects (rs.AllObjects ())
#number of capsules I want in XYZ directions
nrCapsulesX = 4
nrCapsulesY = 2
nrCapsulesH = rs.GetInteger ("How many floors for building 1?",8)
nrCapsulesX2 = 4
nrCapsulesY2 = 2
nrCapsulesH2 = rs.GetInteger ("How many floors for building 2?",10)
Probability = rs.GetReal ("How many capsules should be mirrored?", .8, 0, 1)
#capsule dimension: 2.5m x 4m x 2.5m, window: 1.3m diameter
#In feet: 8.2ft x 13.1ft x 8.2ft 4.4 ft
CapsuleSizeX = 8.2
CapsuleSizeY = 13.1
CapsuleSizeH = 8.2
#Base dimension: 20 x 99 x 40 x 119 x 60
#Core size: 19.8 ft
# x X(the X equals to two times of the X of capsules so they touch each other)
# x H(the H will change according to how many floors the building has)
CoreSizeX = 16.4
CoreSizeY = 2*CapsuleSizeX
CoreSizeH = nrCapsulesH*CapsuleSizeH+40
CoreSizeH2 = nrCapsulesH2*CapsuleSizeH+40
#wall thickness & floor thickness
offsetDist = 1.2
thickness = offsetDist
#sphere diameter(window) 1.3 meters - 4.4 ft - raius 2.2 ft
radius = 2.2
#distance from the second building
mygap = 33
#height difference between the two building.
DifHeight = CoreSizeH2-CoreSizeH
#we need to define the workplane before create a rectangle.
plane = rs.WorldXYPlane ()
#make the base.
B = rs.AddPolyline (([-22,12,12], [-6,30,12], [75,30,12], [90,0,12], [8,-35,12], [-22,12,12]))
Base = rs.ExtrudeCurveStraight (B,[0,0,0], [0,0,12.6])
#make base columns.
#ColumnPtsBase = [[-18,12,0],[-4,24,0],[73,24,0],[86,0,0],[5,-31,0]]
#ColumnPtsTop = [[-18,12,12],[-4,24,12],[73,24,12],[86,0,12],[5,-31,12]]
Column1 = rs.AddCylinder ([-18,12,0],[-18,12,12],2,True)
Column2 = rs.AddCylinder ([3,26,0],[3,26,12],2,True)
Column2a = rs.CopyObject (Column2,[17.5,0,0])
Column2b = rs.CopyObject (Column2,[35,0,0])
Column2c = rs.CopyObject (Column2,[52.5,0,0])
Column3 = rs.AddCylinder ([73,24,0],[73,24,12],2,True)
Column4 = rs.AddCylinder ([86,2,0],[86,2,12],2,True)
Column4a = rs.CopyObject (Column4,[-13,0,0])
Column4b = rs.CopyObject (Column4,[-30,-12,0])
Column4c = rs.CopyObject (Column4,[-48,-20,0])
Column4d = rs.CopyObject (Column4,[-66,-20,0])
Column5 = rs.AddCylinder ([3,-18,0],[3,-18,12],2,True)
#make the core.
C = rs.AddRectangle (plane, CoreSizeX, CoreSizeY)
Core1 = rs.ExtrudeCurveStraight (C, [0,0,0], [0,0,CoreSizeH])
rs.CapPlanarHoles (Base)
rs.CapPlanarHoles (Core1)
#find the corner points of the core, so that I can use two diagonal ones to define the mirror axis.
Cps = rs.BoundingBox (Core1)
Cp1 = Cps[0]
Cp2 = Cps[2]
Cp3 = Cps[1]
Cp4 = Cps[3]
#copy to a second core.
C2 = rs.ExtrudeCurveStraight (C, [0,0,0], [0,0,CoreSizeH2])
rs.CapPlanarHoles (C2)
Core2 = rs.MoveObject (C2,[mygap,0,0])
Cps2 = rs.BoundingBox (Core2)
Cp5 = Cps2[0]
Cp6 = Cps2[2]
Cp7 = Cps2[1]
Cp8 = Cps2[3]
#create the top pf the building.
topPlan = rs.MoveObject (C,[0,0,CoreSizeH] )
top = rs.ExtrudeCurveStraight (topPlan, [0,0,0], [0,0,15])
rs.CapPlanarHoles (top)
#after creating a box, I find its corner points by boundingbox.
Btop = rs.BoundingBox (top)
#make a general definition of midpoint so I can use it several times.
def midpoint (Pa,Pb):
midpoint = [Pa[0]+(Pb[0]-Pa[0])/2, Pa[1]+(Pb[1]-Pa[1])/2, Pa[2]+(Pb[2]-Pa[2])/2]
return midpoint
mid1 = midpoint (Btop[2],Btop[6])
mid2 = midpoint (Btop[0],Btop[4])
#create the top part of the core.
#use the midpoint function to find midpoints of the cube so to create a slanted surface.
SP = rs.AddPolyline ((Btop[3],mid1, Btop[5], mid2, Btop[3]))
SlantPlane = rs.AddPlanarSrf (SP)
#use the slanted surface to split the top part and delete the unwanted part.
CutTopinfo = rs.SplitBrep (top, SlantPlane)
rs.DeleteObject (top)
CutTop = CutTopinfo [0]
rs.DeleteObject (CutTopinfo [1])
#copy it to the second building and make it capable of moving as the height of the second building changes.
CT = rs.CopyObject (CutTop,[mygap,0,0])
CutTop2 = rs.MoveObject (CT,[0,0,DifHeight])
rs.CapPlanarHoles (CutTop2)
#use definition function to define the capsule objects.
#the plan in the functions will be the reactangles created later at the locations of the capsules.
def makeCapsule (plan, CapsuleHeight):
#find the origin point of the plan to find the middle point of the plan and ceiling point.
origin = rs.CurveStartPoint (plan)
midPoint = [origin[0] + CapsuleSizeX / 2, origin[1] + CapsuleSizeY / 2, 0]
ceiling = [origin[0] + CapsuleSizeX / 2, origin[1] + CapsuleSizeY / 2, CapsuleHeight]
#make exterior facade of the wall of the capsules.
facade = rs.ExtrudeCurveStraight (plan, midPoint,ceiling)
#offset the plan to find the inner facades of the walls.
innerplan = rs.OffsetCurve (plan, midPoint, offsetDist)
innerFacade = rs.ExtrudeCurveStraight (innerplan, midPoint, ceiling)
#close the gap between exterior facade and the inner facade.
bottomFacade = rs.AddLoftSrf ([plan, innerplan])
topFacade = rs.CopyObject (bottomFacade, (0,0,CapsuleHeight))
#explode the facade and fine the one that will have the window on it.
facade2 = rs.ExplodePolysurfaces (facade, False)
wall = facade2[1]
#join the exterior and inner facades to make the wall of capsules.
thickWall = rs.JoinSurfaces ([facade, innerFacade, bottomFacade, topFacade], True)
#find the center point of the wall so to create a sphere on it.
#then extract the sphere from the wall and leave the window hole.
point = rs.SurfaceAreaCentroid (wall)[0]
sphere = rs.AddSphere (point, radius)
openWall = rs.BooleanDifference (thickWall, sphere)
#delete the exploded facades.
rs.DeleteObjects (facade2)
#make floor and ceiling from the plan.
floor = rs.ExtrudeCurveStraight (plan, [0,0,0], [0,0,thickness])
floorSlab = rs.CapPlanarHoles (floor)
ceiling = rs.CopyObject (floor, (0, 0, CapsuleHeight - thickness))
#join all the wall, floor and ceiling together to gert the wanted capsule.
Capsule = rs.BooleanUnion ([openWall, floor, ceiling])
rs.DeleteObjects (plan)
rs.DeleteObjects (innerplan)
return Capsule[0]
Crv = []
def makebuilding (gap, core, nrH):
#Use three "for" loops, one inside another, to define the location of each capsule.
#Under each "for" loop, append the created objects into a list,
#so that I would get capsules in a "row", a "floor", and the whole "building".
Cps = rs.BoundingBox (core)
Cp1 = Cps[0]
Cp2 = Cps[2]
Cp3 = Cps[1]
Cp4 = Cps[3]
Building = []
#creates another unstructured list for all the capsules, so that I can use it to make changes only to the capsules.
Allcapsules = []
for h in range (0, nrH):
Floor = []
for y in range (0, nrCapsulesY):
Row = []
for x in range (0, nrCapsulesX):
#we need to move the workplane so that to crate a new rectangle at the new place.
#Find the location of all the capsules.
newPlane = rs.MovePlane (plane, [x*CapsuleSizeX-CapsuleSizeX+gap,y*CapsuleSizeY-CapsuleSizeY/2,h*CapsuleSizeH+24.6])
newCapsule = rs.AddRectangle (newPlane, CapsuleSizeX, CapsuleSizeY)
#append the created rectangles into a list and I will delete them at the end.
Crv.append (newCapsule)
#make the block with the defined makeBlock function.
CAPSULE = makeCapsule (newCapsule, CapsuleSizeH)
Row.append (CAPSULE)
Allcapsules.append (CAPSULE)
#find the location of the capsules again so to use them again.
MovePlane = rs.MovePlane (plane, [x*CapsuleSizeX-CapsuleSizeX+gap,y*CapsuleSizeY-CapsuleSizeY/2,h*CapsuleSizeH+24.6])
RotatePlane = rs.AddRectangle (MovePlane, CapsuleSizeX, CapsuleSizeY)
#make rectangles at the locations and make planar surfaces so that to find the center points which will be used to rotate the blocks.
pl = rs.AddPlanarSrf (RotatePlane)
pt = rs.SurfaceAreaCentroid (pl)[0]
rs.DeleteObjects (pl)
#move the capsules a little bit so they won't overlay on each other when I mirror them.
#rotate the second row of capsules so that they all face the back side.
if y == 1:
rs.MoveObjects (CAPSULE, (0,CoreSizeY-2*CapsuleSizeY+CapsuleSizeY/2,0))
rs.RotateObjects (CAPSULE,pt,180,False)
Floor.append (Row)
#move the middle two capsules forward so that they don't overlay with the core.
rs.MoveObjects ([Floor[0][1], Floor[0][2]], (0,-CapsuleSizeY/2,0))
rs.MoveObjects ([Floor[1][1], Floor[1][2]], (0,CapsuleSizeY/2,0))
if r.random () < Probability:
rs.MirrorObjects ([Floor[0][0],Floor[0][1]], Cp1, Cp2, False)
if r.random () < Probability:
rs.MirrorObjects ([Floor[1][0],Floor[1][1]], Cp3, Cp4, False)
Building.append (Floor)
#the result of appending lists under "for" loop:
# Builing[[[0,1,2,3],[4,5,6,7]],[[8,9,10,11],[12,13,14,15]]]
#Real: Builing[[[0,1,2,3],[0,1,2,3]],[[0,1, 2, 3],[ 0, 1, 2, 3]]]
# row row row row
# floor floor
# building
#Building[0][0][1]-[building],[floor],[row]-1st floor, 1st row, 2nd object
#Building[0][0][2]-[building],[floor],[row]-1st floor, 1st row, 3rd object
#use random to radomly mirror some of the capsules.
#use the diagonal points of the core to mirror the designated capsules.
return Allcapsules
#use the function to create two sets of buildings.
B1 = makebuilding (0, Core1,nrCapsulesH)
B2 = makebuilding (mygap, Core2,nrCapsulesH2)
#mirror the second set of building so that they don't overlay.
mid3 = midpoint (Cp5,Cp7)
mid4 = midpoint (Cp6,Cp8)
Bldg2 = rs.MirrorObjects (B2, mid3, mid4, False)
rs.DeleteObjects (Crv)