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)

Exercise Four – Hierarchy, Composition and Transformation

 

 

 

 

 

This is Exercise Four: Hierarchy, Composition and Transformation. For this exercise, we were asked to create a record of the objects created by our program in the form of a data structure.

Here is the Python Code:


import rhinoscriptsyntax as rs
import random as r

lotSizeX = 60
lotSizeY = 100

roomSizeX = 6
roomSizeY = 10
roomSizeH = 3.5

offsetDist = 0.25
thickness = 0.1
Crv = []

def makeBlock (room, blockHeight):
    #find curves where the block will be created.
    origin = rs.CurveStartPoint (room)
    midPoint = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, 0]
    plan = rs.OffsetCurve (room, midPoint, offsetDist)
    #extrude the exterior facades
    roof = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, blockHeight]
    Crv.append (plan)
    facade = rs.ExtrudeCurveStraight (plan, midPoint, roof)
    #find and extrude the inner facades
    innerPlan = rs.OffsetCurve (plan, midPoint, thickness)
    innerFacade = rs.ExtrudeCurveStraight (innerPlan, midPoint, roof)
    #create surface between exterior and inner facades, and copy it to the top
    bottomFacade = rs.AddLoftSrf ([plan, innerPlan])
    topFacade = rs.CopyObject (bottomFacade, (0,0,blockHeight))
    #explode the exterior facades and find the one that will have a window
    facade2 = rs.ExplodePolysurfaces (facade, False)
    wall = facade2[1]
    #join the facades together to create solid wall
    thickWall = rs.JoinSurfaces ([facade, innerFacade, bottomFacade, topFacade], True)
    #find the center point of the surface, and create a sphere on it.
    point = rs.SurfaceAreaCentroid (wall)[0]
    sphere = rs.AddSphere (point, 0.5)
    #booleandifference between the wall and the sphere to create the window hole.
    openWall = rs.BooleanDifference (thickWall, sphere)
    rs.DeleteObjects (facade2)
    #create floor slab and copy it to the ceiling
    floor = rs.ExtrudeCurveStraight (plan, [0,0,0], [0,0,thickness])
    floorSlab = rs.CapPlanarHoles (floor)

    ceiling = rs.CopyObject (floor, (0, 0, blockHeight - thickness))
    #booleanunion all the solid walls together to create the block wanted.
    block = rs.BooleanUnion ([openWall, floor, ceiling])
    
    rs.DeleteObjects (plan)
    rs.DeleteObjects (innerPlan)

    return block

rs.DeleteObjects (rs.AllObjects ())

#we need to define the workplane before create a rectangle.
plane = rs.WorldXYPlane ()
C = rs.AddRectangle (plane, lotSizeX, lotSizeY)

nrRoomsX = lotSizeX // roomSizeX
nrRoomsY = lotSizeY // roomSizeY

#use three "for" loop to create blocks in three directions.
for y in range (0, nrRoomsX):

    for x in range (0, nrRoomsX):
        
        for z in range (0, nrRoomsX):
            #print (str(x) + "," + str(y) + "," + str(z))
            #we also need to move the workplane so that to crate a new rectangle at the new place.
            newPlane = rs.MovePlane (plane, [x*(roomSizeX+roomSizeY),y*roomSizeY,z*roomSizeH])
            newRoom = rs.AddRectangle (newPlane, roomSizeX, roomSizeY)
            Crv.append (newRoom)
            #make the block with the defined makeBlock function.
            block = makeBlock (newRoom, 3)
            
            #find the center point which will be used to rotate the blocks
            pl = rs.AddPlanarSrf (newRoom)
            pt = rs.SurfaceAreaCentroid (pl)[0]
            rs.DeleteObjects (pl)
            
            #use "if" to define which blocks are going to be rotated
            #use variable to create connection between functions!!
            if x == 0:
                rotation = -90
            if x == 1:
                rotation = 0
            if x == nrRoomsX-1:
                rotation = 90
            if r.random () < .25:
                rs.RotateObjects (block, pt, rotation, False)

            #use random to randomly delete 25% of the blocks.
            if r.random () < .25:
                rs.DeleteObject (block)

#delete the previouslly created curves.
rs.DeleteObjects (Crv)
rs.DeleteObjects (C)

Exercise Three – Solids and Surfaces

This is Exercise Three: Solids and Surfaces. For this exercise, we were asked to create one or more Python functions that manage one or more three‐dimensional elements that must be created from geometric operations with invocation of commands to create solids or surfaces.

Here is the Python Code:

 


import rhinoscriptsyntax as rs
import random as r

lotSizeX = 60
lotSizeY = 100

roomSizeX = 6
roomSizeY = 10
roomSizeH = 3.5

offsetDist = 0.25

Crv = []

def makeBlock (room, blockHeight):
    #create a list to save the surfaces.
    blocksrf = []
    #create blocks and explode them into six surfaces.
    origin = rs.CurveStartPoint (room)
    midPoint = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, 0]
    plan = rs.OffsetCurve (room, midPoint, offsetDist)
    roof = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, blockHeight]
    Crv.append (plan)
    facade = rs.ExtrudeCurveStraight (plan, midPoint, roof)
    rs.CapPlanarHoles (facade)
    facade2 = rs.ExplodePolysurfaces (facade, True)
    blocksrf = facade2
    #select and save one surface into a list.
    wall = facade2[3]
    #find the center point of the surface, and create a sphere on it.
    point = rs.SurfaceAreaCentroid (wall)[0]
    rs.AddPoint (point)
    sphere = rs.AddSphere (point, 0.5)
    #extrude the surface so that to make booleandifference between it and the sphere.
    thickness = 0.1
    extrusionCurve = rs.AddLine ([0,0,0],[0,thickness,0])
    wall = rs.ExtrudeSurface (wall, extrusionCurve)
    rs.BooleanDifference (wall, sphere)
    #join the six surfaces back to a block and give it an ID, and return it.
    joinedblock = rs.JoinSurfaces (blocksrf)
    return joinedblock

rs.DeleteObjects (rs.AllObjects ())

#we need to define the workplane before create a rectangle.
plane = rs.WorldXYPlane ()
C = rs.AddRectangle (plane, lotSizeX, lotSizeY)

nrRoomsX = lotSizeX // roomSizeX
nrRoomsY = lotSizeY // roomSizeY

#use three for loop to create blocks in three directions.
for j in range (0, nrRoomsY):

    for i in range (0, nrRoomsX):
        
        for h in range (0, nrRoomsX):
            print (str(i) + "," + str(j) + "," + str(h))
            #we also need to move the workplane so that to crate a new rectangle at the new place.
            newPlane = rs.MovePlane (plane, [i*roomSizeX,j*roomSizeY,h*roomSizeH])
            newRoom = rs.AddRectangle (newPlane, roomSizeX, roomSizeY)
            Crv.append (newRoom)
            #make the block with the defined makeBlock function.
            block = makeBlock (newRoom, 3)
            #use random to randomly delete 25% of the blocks.
            if r.random () < .25:
                rs.DeleteObject (block)
#delete the previouslly created rectangles.
rs.DeleteObjects (Crv)
rs.DeleteObjects (C)

Exercise Two – Functions and Variables

 

 

 

 

 

 

 

 

This is Exercise Two: Functions and variables. For this exercise, we were asked to program a parametric description or convert our previous exercise into a parametric program by using variables and functions.

 

Here is the Python Code:


import rhinoscriptsyntax as rs
import random as r

lotSizeX = 60
lotSizeY = 100

roomSizeX = 6
roomSizeY = 10
roomSizeH = 3.5

offsetDist = 0.25

Crv = []

def makeBuilding (room, buildingHeight):
    origin = rs.CurveStartPoint (room)
    midPoint = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, 0]
    plan = rs.OffsetCurve (room, midPoint, offsetDist)
    roof = [origin[0] + roomSizeX / 2, origin[1] + roomSizeY / 2, buildingHeight]
    Crv.append (plan)
    facade = rs.ExtrudeCurveStraight (plan, midPoint, roof)
    rs.CapPlanarHoles (facade)
    return facade

rs.DeleteObjects (rs.AllObjects ())

plane = rs.WorldXYPlane ()
C = rs.AddRectangle (plane, lotSizeX, lotSizeY)

nrRoomsX = lotSizeX // roomSizeX
nrRoomsY = lotSizeY // roomSizeY
print (nrRoomsX)

for j in range (0, nrRoomsY):

    for i in range (0, nrRoomsX):
        
        for h in range (0, nrRoomsX):
            print (str(i) + "," + str(j) + "," + str(h))
            newPlane = rs.MovePlane (plane, [i*roomSizeX,j*roomSizeY,h*roomSizeH])
            newRoom = rs.AddRectangle (newPlane, roomSizeX, roomSizeY)
            Crv.append (newRoom)
            building = makeBuilding (newRoom, 3)
        
            if r.random () < .25:
                rs.DeleteObject (building)
                
rs.DeleteObjects (Crv)
rs.DeleteObjects (C)

Exercise One – Python Batch Program

 

 

 

 

This is Exercise One: Python Batch Program. For this exercise, we were asked to write a working batch program that generates a very simple drawing, such as a pattern of tiles, a type of window, a section of a pillar, a bathroom, etc, making use of the functions we have learned during the first three classes.

 

Here is the Python Code:


import rhinoscriptsyntax as rs
import math as m

#four points: 0,0 3,-y 6,0 3,y
#angle: 30degrees  rad=deg*pai/180
#y=3*tan30=1.73205

rs.DeleteObjects (rs.AllObjects())

#Assign coordinates to an object
obj = rs.AddPolyline (([0,0,0],[3,-1.73205,0],[6,0,0],[3,1.73205,0],[0,0,0]))

#Give coordinates of center point, and rotate
point = [0,0,0]
rs.RotateObject (obj, point, -60, None, copy=True)

point = [6,0,0]
rs.RotateObject (obj, point, 60, None, copy=True)

rs.SelectObjects(rs.AllObjects())

#Array
intx = rs.GetInteger ("Please insert number of diamonds", 18)
rs.Command ("arrayLinear " + str(intx) + " 0,0 6,0")


rs.SelectObjects(rs.AllObjects())

#angle: 30degrees
#Long=6, x=Long*sin30=3, y=Long*cos30=5.19615

intx = rs.GetInteger ("Please insert number of diamonds", 27)
rs.Command ("arrayLinear " + str(intx) + " 0,0 3,-5.19615")

Aobj = rs.AllObjects()

#rs.Command ("arrayPolar 0,0 6 360 Enter")

for i in range (1,6):
    angle = 360/6
    rs.RotateObjects (Aobj, [0,0,0], angle*i, None, True)