Computational Design

Page 1

COMPUTATIONAL REIMAGINING
ARCHITECTURE JINGWEN GU DESIGN:
DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs import math import random

# converts radial vector to cartesian vector def radialToCartesian(angle, distance):

# angle: (float) the degrees from origin

# distance: (float) the distance from origin

rads = angle*math.pi/180 # converts degrees to radians return rs.CreatePoint(math.cos(rads)*distance, math.sin(rads)*distance,0)

# r(psi) for logarithmic spiral def logRPsi(angle, a, k):

#angle: (float) angle in degrees

#a: (float) linear coefficient

#k: (float) exponential coefficient return a*math.e**(k*angle*math.pi/180)

# outputs cartesian coordinates for logarithmic spiral based on angular input def logSpiral(angle, a, k):

#angle: (float) angle in degrees

#a: (float) linear coefficient

#k: (float) exponential coefficient return radialToCartesian(angle, logRPsi(angle, a, k))

# recursive function to create spiral patterns with distribution and scale conforming to geometric series def spiral(levels, geom, origin, numArms, numNodes, ang0, ang_step, rotation, scale, a, k, prob, geoms):

# levels: (int) the remaining number of recursions

# geom: (Guid) the base geometry

# origin: (Point3d) origin of spiral

# numArms: (int) the number of spiral arms

# numNodes: (int) the number of nodes per arm

# ang_step: (int) angular difference increment step

# ang0: (int) base angle

# rotation: (float) the rotation of each node with respect to the previous node

# scale: (tuple[float, float, float]) the scale factors of each node with respect to the previous node

#a: (float) linear coefficient

#k: (float) exponential coefficient

#prob: (float) probability of generating fractal

#geoms: (list[Guid]) list of created geometries

if levels != 0:# if there are no more recursions to do, return input geometry

arm_angle = 360/numArms # the angle between 2 neighboring arms

for armIndex in range(numArms): angle = arm_angle*armIndex # current angle (Psi)

newGeom = geom # create 0-th node in each arm translation = rs.CreatePoint(0,0,0) for nodeIndex in range(numNodes): angle = (angle+ang0+nodeIndex*ang_step)%360 # angular difference of sample points increment geometrically

translation = logSpiral(angle,a,k) # translation from origin centerPt = rs.VectorAdd(origin, translation) # center point of new geometry print(translation)

newGeom = rs.CopyObject(newGeom,translation) # copy node to next position with updated angle and distance

newGeom = rs.RotateObject(newGeom, centerPt, rotation) # rotate new node

newGeom = rs.ScaleObject(newGeom, centerPt, scale) # scale new node geoms.append(newGeom)

if(random.random() < prob*nodeIndex/numNodes):

spiral(levels-1, newGeom, rs.CurveAreaCentroid(newGeom) [0], numArms, numNodes-nodeIndex, ang0, ang_step, rotation, scale, a*0.1, k, prob, geoms)

# rs.ScaleObject(newGeom, centerPt, [0.7,0.7,1])

spiral(levels-1, newGeom, centerPt, numArms, (int)(numNodes/3), ang0, ang_step, rotation, scale, a, k, prob, geoms) # recursively create smaller spirals

# portal function to start fractal recursion def crvFractalSpiral(levels, numArms, numNodes, ang0, ang_factor, rotation, scale, a, k, prob):

geom = rs.GetObject(“input prototype geometry”, rs.filter.curve) # request input geometry as curve geoms = [] centroid = rs.CurveAreaCentroid(geom)[0]

spiral(levels, geom, centroid, 1, numNodes, ang0, ang_factor, rotation, scale, a, k, prob, geoms)

# for geom in geoms:

# rs.RotateObject(geom, centroid, 180, None, True)

crvFractalSpiral(3, 4, 60, 15, 0, 15, [1.05,1.05,1], 0.2, 0.053468, 0.3)

DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs import random

# creates a new layer of patterns based on list of modules def modularPatterns(levels, modules, origin, centroids, numPts, numModules):

distances = [] # list of distances from origin to all centroids

distX = [] # list of x component of distances

distY = [] # list of y component of distances for i in range(numModules): # iterate over modules to store distances distances.append(rs.Distance(origin, centroids[i])) # distance between module centroid and origin

distX.append(origin[0]-centroids[i][0]) # x displacement of module centroid from origin

distY.append(origin[1]-centroids[i][1]) # y displacement of module centroid from origin

# upper & lower bounds of distance data

distance_max = max(distances) # maximum distance distance_min = min(distances)*0.99 # minimum distance, adjusted to avoid division by 0

distance_span = distance_max-distance_min # length of distance domain

distX_span = max(distX)-min(distX) # length of x component domain

distX_avg = sum(distX)/numModules # mean of x component

distY_span = max(distY)-min(distY) # length of y component domain

distY_avg = sum(distY)/numModules # mean of y component for i in range(numModules): # iterate over modules to create new layer of geometries

newDistance = 0.25+(distance_max-distances[i])/(2*distance_span) # inversely map distance list to [0.25,0.75] interval prevPts = rs.DivideCurve(modules[i],numPts) # points on previous layer

centroids[i] = rs.PointAdd(centroids[i], ((distX[i] - distX_avg)/ distX_span,(distY[i] - distY_avg)/distY_span,0)) # attract centroid towards origin based on distance, closer modules are less attracted modules[i] = rs.ScaleObject(modules[i], centroids[i], [newDistance,newDistance,1], True) # scale module about new centroid to create new layer of modules

newPts = rs.DivideCurve(modules[i],numPts) # points on new layer for k in range(2): # shift new point sequence to create curl newPts.insert(0,newPts.pop()) for j in range(numPts): # connect points on previous and new layers # rs.AddCurve([prevPts[j], (prevPts[j+1] if j< numPts-1 else prevPts[0]), newPts[j]]) rs.ObjectLayer(rs.AddCurve([prevPts[j], newPts[j]]),”crvs”) if levels != 0: # recursion to next layer modularPatterns(levels-1, modules, origin, centroids, numPts, numModules)

def createPatterns(numRows, numCols, rowInt, colInt, levels, origin, numPts): pts = [] # 2D pt list modules = [] # module list # modules2 = []

originX = round(origin[0]) # x coord of origin

originY = round(origin[1]) # y coord of origin

extremes = [(0,0,0),(0,numRows*rowInt,0),(numCols*colInt,0,0),(numCols*colInt,numRows*rowInt,0)] # 4 vertices of point matrix

extreme_dist = [] # distances between vertices and origin for extreme in extremes: # max distance between all points and origin must be one of the four vertices extreme_dist.append(rs.Distance(extreme,origin)) # store vertice distance in list

dist_max = max(extreme_dist) # find max distance between point matrix and origin

dist_min = rs.Distance(origin,((originX if originX<numCols-1 else numCols-1),(originY if originY<numRows-1 else numRows-1),0)) # min distance between point matrix and origin

dist_span = dist_max-dist_min # length of distance domain for row in range(numRows): # iteratively initialize point matrix ptsRow = [] for col in range(numCols): coeff = (rs.Distance(origin, (col*colInt, row*rowInt, 0))-dist_ min)/dist_span # standardized distance to origin as coefficient to create attractor effect pt = rs.AddPoint((col+(random.random()-0.5)*coeff)*colInt,(row+(random.random()-0.5)*coeff)*rowInt,0) # jitter points with respect to distance from origin rs.HideObject(pt) ptsRow.append(pt) pts.append(ptsRow) for row in range(numRows-1): # iterate over point matrix to create grid modules for col in range(numCols-1): modules.append(rs.AddCurve([pts[row][col],pts[row+1] [col],pts[row+1][col+1],pts[row][col+1],pts[row][col]],1)) # modules2.append(rs.AddCurve([pts[row][col],pts[row+1] [col],pts[row+1][col+1],pts[row][col+1],pts[row][col]],3)) centroids = [] # list of module centroids for module in modules: centroid = rs.CurveAreaCentroid(module)[0] # module centroid centroids.append(centroid) modularPatterns(levels, modules, origin, centroids, numPts, len(modules)) # call recursive function to generate bone structure geometries

if __name__ == “__main__”: createPatterns(15,15,5,5,3,(17,17,0),16)

DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs

# creates snowflake fractal def flakesFractal(levels, origin, sides, factor, radius, stem, num, angles): circ = rs.AddCircle(origin, radius) # reference circle to create vertices rs.HideObject(circ) # hide reference circle angles = (num*360/sides+angles)%360 # rotation of current layer from original position rs.RotateObject(circ, origin, angles) # rotate circle to make sure vertices point away from 0-th origin vertices = rs.DivideCurve(circ,sides) # create vertices for i in range(sides): # pull vertices closer to origin to form spiral fact = factor**i

vertices[i] = (origin[0]+(vertices[i][0]-origin[0])*fact, origin[1]+(vertices[i][1]-origin[1])*fact, origin[2]+(vertices[i][2]-origin[2])*fact) for i in range(sides): # iterate over all vertices to create curve geometries nextPt = vertices[i+1] if i!=sides-1 else vertices[0] # next point in loop crv = rs.JoinCurves([rs.AddCurve([origin,vertices[i]]), rs.AddCurve([origin,nextPt]), rs.AddCurve([nextPt,origin,vertices[i]])],True) # closed curve between radii rs.ScaleObject(crv,rs.CurveAreaCentroid(crv)[0],[0.9,0.9,1]) # scale curves to create slits in between if(levels != 0 and i != sides-1 and (not stem or i == 0 or i == 1 or i == 2)): # recursively create fractals flakesFractal(levels-1, vertices[i], sides, factor, radius*factor**(sides-2), True, i, angles)

DESIGN COMPUTATION JINGWEN GU
if __name__ == “__main__”: flakesFractal(3,(0,0,0),17,0.9,5,False,0,0)

import rhinoscriptsyntax as rs import random

# creates a new layer of patterns based on list of modules def modularPatterns(levels, modules, origin, centroids, numPts, numModules, numRows, numCols,shades,levels_t):

distances = [] # list of distances from origin to all centroids

distX = [] # list of x component of distances distY = [] # list of y component of distances for i in range(numRows-1): # iterate over modules to store distances for j in range(numCols-1):

distances.append(rs.Distance(origin, centroids[(i,j)])) # distance between module centroid and origin

distX.append(origin[0]-centroids[(i,j)][0]) # x displacement of module centroid from origin

distY.append(origin[1]-centroids[(i,j)][1]) # y displacement of module centroid from origin

# upper & lower bounds of distance data

distance_max = max(distances) # maximum distance

distance_min = min(distances)*0.99 # minimum distance, adjusted to avoid division by 0

distance_span = distance_max-distance_min # length of distance domain

distX_span = max(distX)-min(distX) # length of x component domain

distX_avg = sum(distX)/numModules # mean of x component distY_span = max(distY)-min(distY) # length of y component domain distY_avg = sum(distY)/numModules # mean of y component index = 0 # index in distance lists for i in range(numRows-1): # iterate over modules to create new layer of geometries for j in range(numCols-1):

newDistance = 0.2+0.7*(distance_max-distances[index])/distance_ span # inversely map distance list to [0.2,0.9] interval prevPts = rs.DivideCurve(modules[(i,j)],numPts) # points on previous layer centroids[(i,j)] = rs.PointAdd(centroids[(i,j)], ((distX[index] - distX_avg)/distX_span,(distY[index] - distY_avg)/distY_span,0)) # attract centroid towards origin based on distance, closer modules are less attracted modules[(i,j)] = rs.ScaleObject(modules[(i,j)], centroids[(i,j)], [newDistance,newDistance,1], True) # scale module about new centroid to create new layer of modules newPts = rs.DivideCurve(modules[(i,j)],numPts) # points on new layer

for k in range(2): # shift new point sequence to create curl newPts.insert(0,newPts.pop()) for p in range(numPts): # connect points on previous and new layers # rs.AddCurve([prevPts[p], (prevPts[p+1] if p< numPts-1 else prevPts[0]), newPts[p]])

rs.ObjectLayer(rs.AddCurve([prevPts[p], newPts[p]]),”crvs”) insertion = levels_t-levels+2

DESIGN COMPUTATION JINGWEN GU

vertices = rs.CurveEditPoints(modules[(i,j)]) shades[(i,j)].insert(insertion,vertices[1]) shades[(i,j)].insert(insertion+1,vertices[3]) if(levels == 1): shades[(i,j)].insert(insertion+1,vertices[0]) rs.ObjectLayer(rs.AddCurve(shades[(i,j)],1),”shade”)

index += 1

if levels != 0: # recursion to next layer modularPatterns(levels-1, modules, origin, centroids, numPts, numModules, numRows, numCols,shades,levels_t)

def createPatterns(numRows, numCols, rowInt, colInt, levels, origin, numPts): pts = {} # 2D pt hashmap modules = {} # module hashmap centroids = {} # module centroids hashmap shades = {} # modules2 = []

originX = round(origin[0]) # x coord of origin

originY = round(origin[1]) # y coord of origin

extremes = [(0,0,0),(0,numRows*rowInt,0),(numCols*colInt,0,0),(numCols*colInt,numRows*rowInt,0)] # 4 vertices of point matrix

extreme_dist = [] # distances between vertices and origin for extreme in extremes: # max distance between all points and origin must be one of the four vertices extreme_dist.append(rs.Distance(extreme,origin)) # store vertice distance in list

dist_max = max(extreme_dist) # find max distance between point matrix and origin

dist_min = rs.Distance(origin,((originX if originX<numCols-1 else numCols-1),(originY if originY<numRows-1 else numRows-1),0)) # min distance between point matrix and origin

dist_span = dist_max-dist_min # length of distance domain for row in range(numRows): # iteratively initialize point matrix ptsRow = [] for col in range(numCols): coeff = (rs.Distance(origin, (col*colInt, row*rowInt, 0))-dist_ min)/dist_span # standardized distance to origin as coefficient to create attractor effect

pt = rs.AddPoint((col+(random.random()-0.5)*coeff)*colInt,(row+(random.random()-0.5)*coeff)*rowInt,0) # jitter points with respect to distance from origin

rs.HideObject(pt) pts[(row,col)] = pt for row in range(numRows-1): # iterate over point matrix to create grid modules for col in range(numCols-1): modules[(row,col)]=rs.AddCurve([pts[(row,col)],pts[(row+1,col)],p ts[(row+1,col+1)],pts[(row,col+1)],pts[(row,col)]],1)

centroids[(row,col)] = rs.CurveAreaCentroid(modules[(row,col)]) [0] # module centroid

shades[(row,col)] = [pts[(row,col)],pts[(row+1,col)],pts[(row,col +1)],pts[(row,col)]]

# modules2.append(rs.AddCurve([pts[row][col],pts[row+1] [col],pts[row+1][col+1],pts[row][col+1],pts[row][col]],3))

modularPatterns(levels, modules, origin, centroids, numPts, len(modules), numRows, numCols,shades, levels) # call recursive function to generate bone structure geometries if __name__ == “__main__”: createPatterns(15,15,5,5,3,(17,17,0),16)

DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs import random

# creates a new layer of patterns based on list of modules def modularPatterns(levels, modules, origin, centroids, numPts, numModules, numRows, numCols,shades,levels_t):

distances = [] # list of distances from origin to all centroids

distX = [] # list of x component of distances

distY = [] # list of y component of distances for i in range(numRows-1): # iterate over modules to store distances for j in range(numCols-1):

distances.append(rs.Distance(origin, centroids[(i,j)])) # distance between module centroid and origin

distX.append(origin[0]-centroids[(i,j)][0]) # x displacement of module centroid from origin

distY.append(origin[1]-centroids[(i,j)][1]) # y displacement of module centroid from origin

# upper & lower bounds of distance data

distance_max = max(distances) # maximum distance

distance_min = min(distances)*0.99 # minimum distance, adjusted to avoid division by 0

distance_span = distance_max-distance_min # length of distance domain

distX_span = max(distX)-min(distX) # length of x component domain

distX_avg = sum(distX)/numModules # mean of x component distY_span = max(distY)-min(distY) # length of y component domain distY_avg = sum(distY)/numModules # mean of y component index = 0 # index in distance lists for i in range(numRows-1): # iterate over modules to create new layer of geometries for j in range(numCols-1): newDistance = 0.2+0.7*(distance_max-distances[index])/distance_ span # inversely map distance list to [0.2,0.9] interval prevPts = rs.DivideCurve(modules[(i,j)],numPts) # points on previous layer centroids[(i,j)] = rs.PointAdd(centroids[(i,j)], ((distX[index] - distX_avg)/distX_span,(distY[index] - distY_avg)/distY_span,0)) # attract centroid towards origin based on distance, closer modules are less attracted modules[(i,j)] = rs.ScaleObject(modules[(i,j)], centroids[(i,j)], [newDistance,newDistance,1], True) # scale module about new centroid to create new layer of modules newPts = rs.DivideCurve(modules[(i,j)],numPts) # points on new layer

for k in range(2): # shift new point sequence to create curl newPts.insert(0,newPts.pop()) for p in range(numPts): # connect points on previous and new layers # rs.AddCurve([prevPts[p], (prevPts[p+1] if p< numPts-1 else prevPts[0]), newPts[p]])

rs.ObjectLayer(rs.AddCurve([prevPts[p], newPts[p]]),”crvs”) insertion = levels_t-levels+2

DESIGN COMPUTATION JINGWEN GU

vertices = rs.CurveEditPoints(modules[(i,j)]) shades[(i,j)].insert(insertion,vertices[1]) shades[(i,j)].insert(insertion+1,vertices[3]) if(levels == 1): shades[(i,j)].insert(insertion+1,vertices[0]) rs.ObjectLayer(rs.AddCurve(shades[(i,j)],1),”shade”)

index += 1

if levels != 0: # recursion to next layer modularPatterns(levels-1, modules, origin, centroids, numPts, numModules, numRows, numCols,shades,levels_t)

def createPatterns(numRows, numCols, rowInt, colInt, levels, origin, numPts, frameIndex):

pts = {} # 2D pt hashmap modules = {} # module hashmap centroids = {} # module centroids hashmap shades = {} # modules2 = []

originX = round(origin[0]) # x coord of origin

originY = round(origin[1]) # y coord of origin

extremes = [(0,0,0),(0,numRows*rowInt,0),(numCols*colInt,0,0),(numCols*colInt,numRows*rowInt,0)] # 4 vertices of point matrix

extreme_dist = [] # distances between vertices and origin for extreme in extremes: # max distance between all points and origin must be one of the four vertices extreme_dist.append(rs.Distance(extreme,origin)) # store vertice distance in list

dist_max = max(extreme_dist) # find max distance between point matrix and origin

dist_min = rs.Distance(origin,((originX if originX<numCols-1 else numCols-1),(originY if originY<numRows-1 else numRows-1),0)) # min distance between point matrix and origin

dist_span = dist_max-dist_min # length of distance domain for row in range(numRows): # iteratively initialize point matrix ptsRow = [] for col in range(numCols): coeff = (rs.Distance(origin, (col*colInt, row*rowInt, 0))-dist_ min)/dist_span # standardized distance to origin as coefficient to create attractor effect

pt = rs.AddPoint((col+(random.random()-0.5)*coeff)*colInt,(row+(random.random()-0.5)*coeff)*rowInt,0) # jitter points with respect to distance from origin

rs.HideObject(pt)

pts[(row,col)] = pt for row in range(numRows-1): # iterate over point matrix to create grid modules for col in range(numCols-1):

modules[(row,col)]=rs.AddCurve([pts[(row,col)],pts[(row+1,col)],p ts[(row+1,col+1)],pts[(row,col+1)],pts[(row,col)]],1)

centroids[(row,col)] = rs.CurveAreaCentroid(modules[(row,col)])

[0] # module centroid shades[(row,col)] = [pts[(row,col)],pts[(row+1,col)],pts[(row,col +1)],pts[(row,col)]]

# modules2.append(rs.AddCurve([pts[row][col],pts[row+1] [col],pts[row+1][col+1],pts[row][col+1],pts[row][col]],3))

modularPatterns(levels, modules, origin, centroids, numPts, len(modules), numRows, numCols,shades, levels) # call recursive function to generate bone structure geometries

rs.Command(“_-ViewCaptureToFile”+” D:\DesignComputing_week3_1_ frame”+str(frameIndex).zfill(3))

rs.Command(“’_SelAll”)

rs.Command(“_Delete”)

def patternAnimation(numRows, numCols, rowInt, colInt, levels, start, end, numFrames,numPts):

translation = rs.VectorCreate(end,start)

print(translation)

translation = (translation[0]/numFrames,translation[1]/numFrames,translation[2]/numFrames)

print(translation)

for frameIndex in range(numFrames):

createPatterns(numRows, numCols, rowInt, colInt, levels, start, numPts, frameIndex)

start = rs.PointAdd(start,translation)

if __name__ == “__main__”: patternAnimation(15,15,5,5,3,(0,0,0),(50,50,0),240,16)

DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs import random

def basRelief(height,numRows,numCols,rowInt,colInt,randX,randZ,probMirror,crvInt):

crvs = [] startPts = [] endPts = [] srfs = [] x = 0

z = 0

zBase = [] for j in range(numRows): zBase.append(z)

z += rowInt*random.randint(1,3)

flip = True for i in range(numCols):

xDelta = colInt*random.randint(1,5)

x += xDelta colPts = []

if(random.random() < probMirror and i > 0):

crv = rs.ScaleObject(crvs[i-1],rs.CurveMidPoint(crv),(-1,1,1),True)

crv = rs.MoveObject(crv,(xDelta,0,0))

else:

z = 0

for j in range(numRows): colPts.append(rs.AddPoint(x+colInt*randX*(random.random()-0.5),0,z+randZ*rowInt*(random.random()-0.5)))

if z == height: break

z += rowInt*random.randint(1,3)

if z > height or j == numRows-2:

z = height

crv = rs.AddInterpCurve(colPts)

crvs.append(crv)

startPts.append(rs.CurveStartPoint(crv))

endPts.append(rs.CurveEndPoint(crv))

if(i > 0):

rail1 = endArc(startPts[i-1],startPts[i],flip)

rail2 = endArc(endPts[i-1],endPts[i],flip)

sweep = rs.AddSweep2([rail1,rail2],[crvs[i-1],crvs[i]])

srfs.append(sweep)

rs.HideObjects([rail1,rail2])

flip = not flip

srf = rs.JoinSurfaces(srfs)

bounds = rs.BoundingBox(srf)

contours = rs.AddSrfContourCrvs(srf,[(0,-100,0),(0,100,0)],crvInt)

depth = len(contours)*crvInt

for contour in contours:

start = rs.CurveMidPoint(contour)

rs.ExtrudeCurveStraight(contour,start,rs.PointAdd(start,(0,depth,0)))

rs.HideObjects(srfs)

# rs.HideObject(srf)

rs.HideObjects(crvs)

def endArc(pt1,pt2,flip):

x = (pt1[0]+pt2[0])/2

z = (pt1[2]+pt2[2])/2

origin = (x,0,z)

degs = 180 if flip else -180

return rs.AddArc(rs.PlaneFromPoints(origin,pt2,(origin[0],1,origin[2])),rs.Distance(origin,pt2),degs)

if __name__ == “__main__”:

rs.EnableRedraw(False)

basRelief(30,8,20,2,1,1,0.5,0.2,0.5)

rs.EnableRedraw(True)

DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU
DESIGN COMPUTATION JINGWEN GU

import rhinoscriptsyntax as rs import Rhino import scriptcontext as sc import System

import math

import random

def populateSrf(srf, uList, vList):

ptsUV = {} # list of uv pts

ptsXYZ = {} for i in range(len(uList)): for j in range(len(vList)): ptsUV[(i,j)] = (uList[i],vList[j])

return ptsUV

def uvTo3D(srf,ptsUV):

pts3D = {} for (i,j) in ptsUV: pts3D[(i,j)] = rs.EvaluateSurface(srf,ptsUV[(i,j)][0],ptsUV[(i,j)] [1])

return pts3D

# divides srf with division interval proportional to meridian distance from axis

def uByRadius(srf, axis, numU):

uOut = []

dists = []

axisSamplePts = rs.DivideCurve(axis,numU)

uDomain = rs.SurfaceDomain(srf,0)

vDomain = rs.SurfaceDomain(srf,1)

v = vDomain[0]

uList = uUniform(srf,numU)[0]

for u in range(numU):

dists.append(rs.Distance(rs.EvaluateSurface(srf,uList[u],v),axisSamplePts[u]))

factor = (uDomain[1]-uDomain[0])/sum(dists)

uCurrent = uDomain[0]

minDist = min(dists)

distSpan = max(dists)-minDist for i in range(numU): uOut.append(uCurrent)

uCurrent += dists[i]*factor dists[i] = (dists[i]-minDist)/distSpan

return (uOut,dists)

def vByRadius(srf, axis, numV):

vOut = [] dists = []

axisSamplePts = rs.DivideCurve(axis,numV)

uDomain = rs.SurfaceDomain(srf,0)

vDomain = rs.SurfaceDomain(srf,1)

u = uDomain[0]

vList = vUniform(srf,numV)[0]

for v in range(numV): dists.append(rs.Distance(rs.EvaluateSurface(srf,u,vList[v]),axisSamplePts[v]))

factor = (vDomain[1]-vDomain[0])/sum(dists)

vCurrent = vDomain[0]

minDist = min(dists)

distSpan = max(dists)-minDist for j in range(numV):

vOut.append(vCurrent)

vCurrent += dists[j]*factor

dists[j] = (dists[j]-minDist)/distSpan return (vOut,dists)

def uUniform(srf, numU):

uOut = [] weights = []

uDomain = rs.SurfaceDomain(srf,0)

step = (uDomain[1]-uDomain[0])/numU

u = 0 for i in range(numU):

uOut.append(u)

u += step weights.append(0.5)

return (uOut,weights)

def vUniform(srf, numV):

vOut = [] weights = []

vDomain = rs.SurfaceDomain(srf,1)

step = (vDomain[1]-vDomain[0])/numV

v = 0 for j in range(numV):

vOut.append(v)

v += step weights.append(0.5)

return (vOut,weights)

DESIGN COMPUTATION JINGWEN GU

def jitterGrid(ptsDict, uWeights, vWeights, factU, factV): for (i,j) in ptsDict: ptsDict[(i,j)] = (ptsDict[(i,j)][0]+uWeights[i]*factU*(random.random()-0.5), ptsDict[(i,j)][1]+vWeights[j]*factV*(random.random()-0.5))

def generateModules(srf, ptsUV, pts3D, uWeights, vWeights, numU, numV, maxFact, maxDist, prob, mutateFact):

mutation = []

for

j in range(1,numV-3):

r = range(0,numU,2) if j%2!=0 else range(1,numU,2) for i in r:

u = ptsUV[(i,j)][0]

v = ptsUV[(i,j)][1]

factor = maxFact*uWeights[i]*vWeights[j]

left = i-1 if i>0 else numU-1

right = i+1 if i< numU-1 else 0

baseCrv = rs.AddCurve([pts3D[(left,j)], pts3D[(i,j-1)], pts3D[(right,j)], pts3D[(i,j+1)], pts3D[(left,j)]],1)

# topCrv = rs.AddCurve([pts3D[(left,j)], pts3D[(i,j-1)], pts3D[(right,j)], pts3D[(i,j+1)], pts3D[(left,j)]],3)

topCrv = rs.AddCurve([pts3D[(i,j+1)], pts3D[(left,j)], pts3D[(i,j-1)], pts3D[(right,j)], pts3D[(i,j+1)]],3)

rs.ScaleObject(topCrv, rs.EvaluateSurface(srf,u,v), rs.VectorScale((1.2,1.2,1.2),factor+0.1))

rand = random.random()

translation = rs.SurfaceNormal(srf, [u,v])

if rand*factor > prob:

translation = rs.VectorScale(translation,factor*maxDist*rand*mutateFact)

rs.MoveObject(topCrv,translation)

loft = rs.AddLoftSrf([baseCrv,topCrv])

cent1 = rs.CurveAreaCentroid(rs.AddCurve([pts3D[(left,j)], pts3D[(i,j-1)], pts3D[(right,j)], pts3D[(left,j)]],1))[0]

cent2 = rs.CurveAreaCentroid(rs.AddCurve([pts3D[(left,j)], pts3D[(right,j)], pts3D[(i,j+1)], pts3D[(left,j)]],1))[0]

center = ((cent1[0]+cent2[0])/2, (cent1[1]+cent2[1])/2, (cent1[2]+cent2[2])/2)

mutation.append((loft,rs.AddLine(center, rs.PointAdd(center,translation)),baseCrv)) else:

rs.MoveObject(topCrv,rs.VectorScale(translation,factor*maxDist*rand))

loft = rs.AddLoftSrf([baseCrv,topCrv])

return mutation

def addSkeleton(geom,axis,interval,scale,depth,thickness,numSpine,scaleGeom,extend):

srf = ScaleObjectEx(geom,rs.CurvePerpFrame(axis,rs.CurveDomain(axis) [0]),[scaleGeom,scaleGeom,1],True)

pts = []

contours = rs.AddSrfContourCrvs(srf, [rs.CurveStartPoint(axis),rs.CurveEndPoint(axis)], interval)

i = 0

while i < len(contours): crv = contours[i]

if rs.IsCurveClosed(crv):

pts.append(rs.DivideCurve(crv,numSpine))

start = pts[i][0]

crvIn = rs.ScaleObject(crv,rs.CurveAreaCentroid(crv)[0],rs.VectorScale([1,1,1],scale),True)

rib = rs.AddPlanarSrf([crv,crvIn])

rs.ExtrudeSurface(rib,rs.AddLine((0,0,0),rs.VectorScale(rs.SurfaceNormal(rib,[0,0]),thickness)))

i += 1 else:

contours.pop(i) for j in range(numSpine):

crvPts = []

for i in range(len(contours)):

crvPts.append(pts[i][j])

spine = rs.AddInterpCurve(crvPts)

spine = rs.ExtendCurveLength(spine,1,2,rs.CurveLength(spine)*extend*random.random())

outer = pts[0][j]

line = rs.AddLine(outer,rs.EvaluateCurve(axis,rs.CurveClosestPoint(axis,outer),0))

srf = rs.ExtrudeCurve(spine,rs.ScaleObject(line,rs.CurveStartPoint(line),rs.VectorScale((1,1,1),depth/rs.CurveLength(line)))) rs.ExtrudeSurface(srf,rs.AddLine((0,0,0),rs.VectorScale(rs.SurfaceNormal(srf,[0,0]),thickness)))

rs.DeleteObject(srf)

DESIGN COMPUTATION JINGWEN GU

def modularize(srf, axis, numU, numV, maxFact, maxDist, prob, mutateFact,jitterU,jitterV,interval1,interval2,scale1,scale2,depth1,depth2,thickness1,thickness2,numSpine1,numSpine2,scaleGeom1,scaleGeom2,scaleRecess,extend):

addSkeleton(srf,axis,interval1,scale1,depth1,thickness1,numSpine1,scaleGeom1,extend)

(vList,vWeights) = vByRadius(srf,axis,numU)

(uList,uWeights) = uUniform(srf,numV)

ptsUV = populateSrf(srf,uList,vList)

jitterGrid(ptsUV,uWeights,vWeights,jitterU,jitterV)

pts3D = uvTo3D(srf,ptsUV)

mutated = generateModules(srf,ptsUV,pts3D,uWeights,vWeights,numU,numV, maxFact, maxDist, prob, mutateFact)

for (loft,line,baseCrv) in mutated:

addSkeleton(loft,line,interval2,scale2,depth2,thickness2,numSpine2,scaleGeom2,extend)

ScaleObjectsEx([loft],rs.CurvePerpFrame(line,rs.CurveDomain(axis) [0]),[1,1,scaleRecess],False)

def ScaleObjectEx(object_id, plane, scale, copy=False): scale = rs.coerce3dpoint(scale, True)

if scale:

xform = Rhino.Geometry.Transform.Scale(plane, scale.X, scale.Y, scale.Z)

object_id = rs.coerceguid(object_id, True) id = sc.doc.Objects.Transform(object_id, xform, not copy) return id

if __name__ == “__main__”: srf = rs.GetObject(“enter srf”) axis = rs.GetObject(“enter axis”, rs.filter.curve)

rs.EnableRedraw(False) mutated = modularize(srf,ax-

# ScaleObjectsEx([srf],rs.CurvePerpFrame(axis,rs.CurveDomain(axis) [0]),[0.5,0.5,1],True)

rs.EnableRedraw(True)

DESIGN COMPUTATION JINGWEN GU
is,18,20,1.2,1,0.3,10,3,3,1,0.5,0.9,0.9,1,0.1,0.1,0.05,16,6,0.9,0.5,0.8,0.4) # addSkeleton(srf,axis,1,0.9,1,0.2,16)

Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.