This is the third in-class practice making an urban model using control structure in Rhinoceros. In this urban model, we also created empty space for central park, and we selected a spot where the buildings are much taller as the downtown area.
Here is the Python Code:
import rhinoscriptsyntax as rs import random citySizeX = 1000 citySizeY = 2000 lotSizeX = 40 lotSizeY = 50 offsetDist = 7.5 masterHeight = 30 def makeBuilding (lot, buildingHeight): origin = rs.CurveStartPoint (lot) #rs.AddPoint (origin) #this command will show the origin point on each rectangle #pt=[1,2,3]([x,y,z]) - (0,1,2), so: py[0]=1/pt[1]=2/pt[2]=3 midPoint = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, 0] rs.AddPoint (midPoint) plan = rs.OffsetCurve (lot, midPoint, offsetDist) roof = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, buildingHeight] facade = rs.ExtrudeCurveStraight (plan, midPoint, roof) rs.CapPlanarHoles (facade) rs.DeleteObjects (rs.AllObjects ()) #addRectangle needs to define plane in its parameter plane = rs.WorldXYPlane () rs.AddRectangle (plane, citySizeX, citySizeY) #// division, when it is only one /, the results could be non-integer, and it produce an error "float" nrLotsX = citySizeX // lotSizeX nrLotsY = citySizeY // lotSizeX print (nrLotsX) #make rooms for parks in our city: ptPark = rs.GetPoint ("Please select park location:") ptCenter = rs.GetPoint ("Please select center location:") #in range, the results are always one less than the last range #for example, (0,7), the results are 0,1,2,3,4,5,6 #range inside another range: for j in range (0, nrLotsY): for i in range (0, nrLotsX): print (str(i) + "," + str(j)) #the command above will print a list of i and j pairs #the command below will produce a roll of #i lots and a column of #j lots newPlane = rs.MovePlane (plane, [i*lotSizeX,j*lotSizeY,0]) #with the command below, a lot of rectangles will be produced at the same place, so we need to move them with the command above newLot = rs.AddRectangle (newPlane, lotSizeX, lotSizeY) #if lot is close enough to ptPark, don't make building ptLot = rs.CurveStartPoint (newLot) distPark = rs.Distance (ptLot, ptPark) #when the distance between ptLot and ptPark is bigger than our setting, it will make building: if (distPark > 200): newHeight = random.uniform (60,200) distCenter = rs.Distance (ptLot, ptCenter) #suburbanFactor = distCenter * .2 suburbanFactor = 2000/(distCenter**.5) centerHeight = newHeight makeBuilding(newLot, newHeight + suburbanFactor)