Capstone Project – Recreating Nakagin Capsule Tower with Computer Programming

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.

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)

Leave a Reply

Your email address will not be published. Required fields are marked *