Categories
game

Game Corner

Some games I developed

Salmon Headson

Mobile: https://play.google.com/store/apps/details?id=com.BitByDesign.SalmonHeadsOn

Desktop: https://bitbydesign.itch.io/salmon-headson

Platform Game (Work In Progress – currently have no name):

https://bitbydesign.itch.io/platformgame

Categories
bookreview

A Pattern Language

A Pattern Language, by Christopher Alexander is a classic book for many computational designers, and engineers with an interest in design, despite not having a single line of mathematical equations. Although the book is about design, unlike many other pretentious pompous architectural books, it is written in simple language, logical manner, break down design into rules. Christopher himself studied both architecture and mathematics. That would explains his keen observation for design and his sharp analytical mind for reasoning. Christopher is probably an advocate of localism and agrees with Nicholas Tassim that localism is the DNA for an anti-fragile society.

A Pattern language covers the design of basically everything, from urban planning, down to the nitty gritty decor in your house. Summarizing such a comprehensive book would be a daunting task. Nevertheless, I find the design advices from the book are interesting so I will try my best to summarize them by each chapter. The first part is more on town and community design

  • Network of learning
    Learning should scattered, enriched in the contact with many places and people in the city. Learning can be informal through workshops, museums, professionals take on the young helpers, the old teaching the youngs etc.
  • Web of Shopping (locations/placement)
    Alexander is against malls. Shop should be located where the consumers are, and at a distance from another shop of the same type.
Shopping Network
  • Minbus (transport/network)
    Mini bus to bring people from their house to the interchange. This would reach anyone in the city without intrusion
  • Life Cycle
    ( network of learning)
    Make certain that full cycle of life is represented and balanced in the community. Each community should include a balance of people if every stage of life.
  • Activity Node (transport/Network)
    To create such community, we can have different node of activity where there’s public square. The activity nodes can be spread about 300 yards apart.
Activity Node
  • Promenade(transport/Network)
    Promenade is crucial for the public life. It has to be big enough to host many people but not too big to be dead. The gradual formation of a promenade at the heart of every community, linking the main activity nodes.
  • Degrees of publicness (network/placement)
    Different people will have different preferences of their house to be public. Design twisting paths and cluster of houses so that there will be 3 kinds of home, the public, the private and one is of a degree in between.
  • Old people (learning/interaction)
    Allow old people to stay in a neighbourhood with other old people but not so isolated them from the younger people. Create dwellings for some 50 old people in every neighbourhood with a central core with cooking and nursing provided. Cottages near the core, further out from the core, mixed with other houses in the neighbourhood
  • University as marketplace (learning)
    Just like old time, marketplace could be a place for sharing ideas. It is a place open to people of all ages. Anyone can offer a class. The university marketplace has a central crossroads where its main building and offices are, and the meeting rooms and labs ripple out from this crossroads.
  • Necklace of community projects (learning)
    Allow the growth of shop size spaces around the local town hall. These shops can lease out at minimum rent to ad hoc community groups for political work, trial service, research and advocate groups.
  • Children in the city (learning)
    Create a network of traffics and spaces with homes and shops along it so children can roam free and watched.
  • Connected Play
    Common land, paths of at least 64 households should be connected by a swath of land that does not cross traffic to connect and kindle the friendship among children in the neighborhood
  • Carnival, Dancing in the street, public outdoor rooms
    “Man has the need for mad, subconscious processes to come into play, without unleashing them to such an extend that they become socially destructive”
    Set aside a space in the promenade for people to dance, unleash to the music or have a carnival as a town activity.
  • Public outdoor rooms
    In every neighbourhood, take a piece of common land into a common outdoor room, partially sheltered with a trellis with chairs and tables.

Categories
game

Procedural Generation in Games

In real world, architectural and urban designs are often the result carefully crafted and top down approach. But in game, the environment is sometimes created quickly using a framework system. I’m always amazed by the designs in game. The worlds in games are not only vast and beautiful, they are diverse and endless. They are so wonderful and real that makes us allude to the trippy idea we are all living in a simulation.

One of the most popular and well known technique game developer used is called procedural generation.

Procedural generation is a method of creating data algorithmically as opposed to manually, typically through a combination of human-generated assets and algorithms coupled with computer-generated randomness and processing power.

The term procedural refers to the process that computes a particular function. More familiar to the computational design world, fractals are geometric patterns which can be generated procedurally. Common used procedural uses are textures and meshes. Sound is often also procedurally generated and has applications in both speech synthesis and music.

Various uses of procedural process has been explored in different games.

Environment

The most obvious and widely used choice of procedural generation is the creation of environment like terrain or trees.

Trees are generated by the same algorithm with random tweaks to make it look diverse and realistic

File:Dragon trees.jpg

No man’s sky uses procedural generation to create the terrain, flora and fauna

No Man's Sky Beyond' Trailer Shows Off The Game's Online And VR In ...

This video below explains in details how you procedurally generate terrain

Personalities

Procedurally-generated content can add detail and depth to characters and story line . The personality manifests as various traits, which under the surface are simple numbers that alter the balance in a character’s decision. But because the systems revolve around relationships and behavior, these traits combine in fascinating, dramatic storyline at the center of medieval power dynamics in Crusader King II.

Another example is Sim. In Sim, you can create the characters each with its own set of traits. You can direct your Sim to do certain task but when letting on auto mode, your Sim will act its own with the inclination which suits its personality.

Game mechanics

Splunkey is a familiar but not so typical platform arcade game. Instead of forming a fixed set of levels, splunkey has a fixed set of rules for its mechanics and underlying system. The player will not be able to predict which challenge come next.

The level is almost unique with a pseudo random placement of enemies, shopkeepers, items, cave walls, and other elements. This gives the player an element of surprises and outcomes.

Exploration and Interation

The Cilivilization series is like a big board chess game, except the maps and the game conditions are totally different from one game to another. Each player is handed a different map at the start. Playing the game is like answering a series of questions where each question is totally different every time you are asked. The choice eventually lead to an unique and totally different series of interesting situation choices each time. You will never know which civilizations you will face at the start or which challenge are you going to fight against. The possibilities are endless.

AI

In this era of escalated innovation in AI, researchers has designed an AI called Angelina. Angelina can create game by herself using procedural generation. Angelina can generate various arcade games with textures and self created mechanics.

She has also participated in game jams and create different games based on a theme word or phrase.

You can explore games created by Angelina in the link below

https://gamesbyangelina.itch.io/

Source: Gamasutra, Wikipedia, NewsAtlas

Categories
FEA

Writing 2D FEA in Python Gh 4

From each element stiffness matrix, we can construct the global K stiffness matrix

def ConstructGlobalK(nodes, elements):
    rowCt = 2 * len(nodes)
    colCt = 2 * len(nodes)
    globalK = np.zeros((rowCt,colCt))
    for element in elements:
        k = element.GetElementStiffness()
        triplets = element.GetTriplets(k)
        for triplet in triplets:
            tripC = rs.PointCoordinates(triplet)
            globalK[tripC[0]][tripC[1]] = tripC[2]
    return globalK

 

However, we are not complete yet. We need to apply constraints so we can solve the displacement vector. Displacement of constrained nodes are always zero. Consider this equation, on the left hand we have a global stiffness matrix and displacement vector, the right side is the force vector.

  \begin{bmatrix} k_{1,1} & k_{1,2} & k_{1,3} & k_{1,4} & k_{1,5} & k_{1,6}\\ k_{2,1} & k_{2,2} & k_{2,3} & k_{2,4} & k_{2,5} & k_{2,6}\\ k_{3,1} & k_{3,2} & k_{3,3} & k_{3,4} & k_{3,5} & k_{3,6}\\ k_{4,1} & k_{4,2} & k_{4,3} & k_{4,4} & k_{4,5} & k_{4,6}\\ k_{5,1} & k_{5,2} & k_{5,3} & k_{5,4} & k_{5,5} & k_{5,6}\\ k_{6,1} & k_{6,2} & k_{6,3} & k_{6,4} & k_{6,5} & k_{6,6}\\ \end{bmatrix} \begin{bmatrix} u_1\\v_1\\u_2\\v_2\\u_3\\v_3 \end{bmatrix} = \begin{bmatrix} F_{x1}\\F_{y1}\\F_{x2}\\F_{y2}\\F_{x3}\\F_{y3} \end{bmatrix}

To constrain the node, the corresponding element of the matrix should be set to 1, and all elements in that row and column should be set to zero. There should not be any external forces acting on the constrained node in constrained direction.

  \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0\\ 0 & k_{2,2} & k_{2,3} & 0 & k_{2,5} & k_{2,6}\\ 0 & k_{3,2} & k_{3,3} & 0 & k_{3,5} & k_{3,6}\\ 0 & 0 & 0 & 1 & 0 & 0\\ 0 & k_{5,2} & k_{5,3} & 0 & k_{5,5} & k_{5,6}\\ 0 & k_{6,2} & k_{6,3} & 0 & k_{6,5} & k_{6,6}\\ \end{bmatrix} \begin{bmatrix} u_1\\v_1\\u_2\\v_2\\u_3\\v_3 \end{bmatrix} = \begin{bmatrix} 0\\F_{y1}\\F_{x2}\\0\\F_{x3}\\F_{y3} \end{bmatrix}

 

Below is the code for applying constraints

def ApplyConstraint(globalK):
    conIndices = GetConstraintIndices()
    rowSize = np.size(globalK, 0)
    colSize = np.size(globalK, 1)
    for i in range(rowSize):
        for j in range(colSize):
            for index in conIndices:
                if (i == index or j == index):
                    globalK[i][j] = 1.0 if i == j else 0.0
    return globalK

 

Recall

 \left [ K \right ] \left [ \delta \right ]  =  \left [ R \right ]

K – stiffness matrix; \delta – vector of displacements; R – vector of loads

We already have stiffness matrix and vector of loads. Now we can find the vector of displacements by solving the equation above

displacements = np.linalg.solve(globalK, loads)

 

Now we have solved the equations, we might want to visualize the result, finding the displacement vector in each node.

def GetNodeDisplacements(nodes, displacements):
    nodeDisps = []
    for i in range(0,len(nodes)):
        #this is actually add vector but add vector is not available in Rhino5 32bit
        v = rs.AddPoint( displacements[2 * i + 0], displacements[2 * i + 1], 0) 
        nodeDisps.append(v)
    return nodeDisps

There we have a list of displacement vectors correspond with each node. We can also calculate the stress

stresses = []
for element in elements:
    nodeIds = element.NodeIds
    delta = np.zeros(6)
    delta[0] = displacements[2 * nodeIds[0]]
    delta[1] = displacements[2 * nodeIds[0] + 1]
    delta[2] = displacements[2 * nodeIds[1]]
    delta[3] = displacements[2 * nodeIds[1] + 1]
    delta[4] = displacements[2 * nodeIds[2]]
    delta[5] = displacements[2 * nodeIds[2] + 1]
    sigma1 = np.dot(elasM, element.GetMatrixB(element.GetMatrixC()))
    sigma = np.dot(sigma1, delta)
    sigmaCal = sigma[0] * sigma[0] - sigma[0] * sigma[1] + sigma[1] * sigma[1] + 3 * sigma[2] * sigma[2]
    sigma_mises = math.sqrt(sigmaCal)
    stresses.append(sigma_mises)

With a list of displacement vectors and list of stress value, we can visualize the result in Rhino using grasshopper display tools

Setup display

Stress Display

stress

Displacement Display

Displacement display

Categories
FEA

Writing 2D FEA in Python Gh 3

As explained in the previous post, to calculate element stiffness, we need to find the 3 matrix: D, C and B

Let’s find D first

 \left [ D \right ] =  \cfrac{E}{1-\nu^2}   \begin{bmatrix}    1 & \nu & 0 \\   \nu & 1 & 0 \\    0 & 0 & \cfrac{1-\nu}{2}   \end{bmatrix}

def GetElascityMatrixD(matInfo):
   poisson = matInfo[0]
   youngModul = matInfo[1]
   matrix = np.zeros((3,3))
   matrix[0][0] = 1
   matrix[0][1] = poisson
   matrix[1][0] = poisson
   matrix[1][1] = 1
   matrix[2][2] = (1 - poisson)/2
   mult = youngModul/(1 - math.pow(poisson,2))
   elasM = mult * matrix 
   return elasM

 

Matrix B and C are element so I wrote the methods to calculate B and C in class Element

Recall

 \begin{bmatrix} 1 & x_i & y_i \\ 1 & x_j & y_j  \\ 1 & x_m & y_m  \\ \end{bmatrix} = \begin{bmatrix} C \end{bmatrix}

and B i the second matrix in this

  \begin{bmatrix} \varepsilon \end{bmatrix}  = \begin{bmatrix} \frac{\partial N_i}{\partial x} & 0 &\frac{\partial N_j}{\partial x} & 0 & \frac{\partial N_m}{\partial x} & 0 \\ 0 & \frac{\partial N_i}{\partial y} & 0 & \frac{\partial N_j}{\partial y} & 0 & \frac{\partial N_m}{\partial y} \\ \frac{\partial N_i}{\partial y} & \frac{\partial N_i}{\partial x} &\frac{\partial N_j}{\partial y} & \frac{\partial N_j}{\partial x} & \frac{\partial N_m}{\partial y} & \frac{\partial N_m}{\partial x} \end{bmatrix} \begin{bmatrix} u_i \\ v_i \\ u_j \\ v_j \\ u_m \\ v_m \end{bmatrix}

where

  \frac{\partial N_i}{\partial x} = \begin{bmatrix} C \end{bmatrix}^{-1}_{2,i}

  \frac{\partial N_i}{\partial y} = \begin{bmatrix} C \end{bmatrix}^{-1}_{3,i}

and element stiffness is

  \begin{bmatrix} k \end{bmatrix}^e = \begin{bmatrix} B \end{bmatrix}^T \begin{bmatrix} D \end{bmatrix} \begin{bmatrix} B \end{bmatrix} \frac{det(\begin{bmatrix}C\end{bmatrix})}{2}t

The methods of finding C, B and K are below. All of them are in element class

class Element:
    def __init__(self, elemNodes, nodeIds):
        self.Nodes = elemNodes
        self.NodeIds = nodeIds
    def GetMatrixC(self):
        col1 = []
        colx = []
        coly = []
        for i in range(len(self.Nodes)):
                col1.append(1)
                colx.append(self.Nodes[i].X)
                coly.append(self.Nodes[i].Y)
        matrixC = [col1, colx, coly]
        return matrixC
    def GetMatrixB(self, matrixC):
        C = matrixC
        IC = np.linalg.inv(C)
        B = np.zeros((3,6))
        for i in range(3):
            B[0][2 * i + 0] = IC[1][ i]
            B[0][2 * i + 1] = 0.0
            B[1][ 2 * i + 0] = 0
            B[1][2 * i + 1] = IC[2][i]
            B[2][2 * i + 0] = IC[2][i]
            B[2][2 * i + 1] = IC[1][i]
        return B
    def GetElementStiffness(self):
        C = self.GetMatrixC()
        B = self.GetMatrixB(C)
        D = GetElascityMatrixD(matInfo)
        BT = np.matrix.transpose(B)
        CDet = np.linalg.det(C)
        mult1 = np.dot( BT , D)
        mult2 = np.dot(mult1, B)
        K = mult2 * CDet * 1/2
        return K

We are going to use element stiffness to calculate global stiffness. For the ease of usage later on, we store element stiffness matrix together with its corresponding indices in the global stiffness matrix in a triplet. That means, for each element, we will have 3 triplets, each correspond to a vertex of that triangulated matrix. In that triplet, the first two items are nodeId positions, the last is its corresponding value in element stiffness. In this case, I use point3d as triple, it is not a point but simply a way to store 3 number all at once. Note that this GetTriplets method also nested inside Element Class

    #Calculate Stiffness Matrix
    def GetTriplets(self, K):
        triplets = []
        for i in range(0, 3):
            for j in range(0,3):
                t11 = rs.AddPoint( 2 * self.NodeIds[i] + 0, 2* self.NodeIds[j] + 0, K[2 * i + 0][2 * j + 0])
                t12 = rs.AddPoint( 2 * self.NodeIds[i] + 0, 2* self.NodeIds[j] + 1, K[2 * i + 0][2 * j + 1])
                t21 = rs.AddPoint( 2 * self.NodeIds[i] + 1, 2 * self.NodeIds[j] + 0, K[2 * i + 1][2 * j + 0])
                t22 = rs.AddPoint( 2* self.NodeIds[i] + 1, 2* self.NodeIds[j] + 1, K[2 * i + 1][2 * j + 1])
                triplets.append(t11)
                triplets.append(t12)
                triplets.append(t21)
                triplets.append(t22)
        return triplets

Now we have all the element stiffness information, we are ready to put them together to calculate the global stiffness and deformation

Categories
FEA

Writing 2D FEA in Python Gh 2

And….here we go, to the most complicated part of the code, calculation!

The ultimate goal of the structural FEA is to find out the deflection, and in computer terms, that would be the displacement of each node.

Link: https://podgorskiy.com/spblog/304/writing-a-fem-solver-in-less-the-180-lines-of-code

Since strain is a linear function of stress, displacement of each node is a linear function of applied forces. That is expressed by the equations below:

 \left [ K \right ] \left [ \delta \right ]  =  \left [ R \right ]

K – stiffness matrix; \delta – vector of displacements; R – vector of loads

The global stiff matrix is calculated from each element stiff matrix. In order to find the nodal displacement, we start with an equation of the work done by nodal forces:

  dA = (d\begin{bmatrix} \delta \end{bmatrix}^e)^T \begin{bmatrix} F \end{bmatrix}^e

After some mathematical manipulations, we have:

  \begin{bmatrix} k \end{bmatrix}^e = \begin{bmatrix} B \end{bmatrix}^T \begin{bmatrix} D \end{bmatrix} \begin{bmatrix} B \end{bmatrix} \frac{det(\begin{bmatrix}C\end{bmatrix})}{2}t

k is element matrix. D is elasticity matrix. B and C will be explained further.

 \left [ D \right ] =  \cfrac{E}{1-\nu^2}   \begin{bmatrix}    1 & \nu & 0 \\   \nu & 1 & 0 \\    0 & 0 & \cfrac{1-\nu}{2}   \end{bmatrix}

where v is poisson ratio.

Shape functions

If displacements of nodes are given, then displacement in any point of element can be obtained by the following equation

  \begin{bmatrix} u(x,y) \\ v(x,y) \end{bmatrix}   = \left [ N \right ] \left [\delta \right ]^e

  u(x,y)  = \begin{bmatrix} N_i &  N_j  & N_m \end{bmatrix} \begin{bmatrix} u_i \\ u_j   \\ u_m \end{bmatrix}
  v(x,y)  = \begin{bmatrix} N_i &  N_j  & N_m \end{bmatrix} \begin{bmatrix} v_i \\ v_j   \\ v_m \end{bmatrix}

where [N] is a matrix of functions of position (x, y). u and v are components of the displacement that can be interpolated dependently.  For simplicity, I take u and v as the global x vector and y vector, which i guess that’s why i have to put my geometry at the origin in order for the algorithm to work

For three-node linear element, interpolation is linear. To interpolate function, we need to find an equation of the following form: (Note: think of i, j and m as each node of the triangle elememt)

  \left\{\begin{matrix} f_i = a_1 + a_2 x_i + a_3 y_i \\ f_j = a_1 + a_2 x_j + a_3 y_j \\ f_m = a_1 + a_2 x_m + a_3 y_m \\ \end{matrix}\right.

  \begin{bmatrix} a_1 \\ a_2  \\ a_3 \\ \end{bmatrix} = \begin{bmatrix} 1 & x_i & y_i \\ 1 & x_j & y_j  \\ 1 & x_m & y_m  \\ \end{bmatrix}^{-1} \begin{bmatrix} f_i\\ f_j \\ f_m \\ \end{bmatrix}

We denote C as \begin{bmatrix} 1 & x_i & y_i \\ 1 & x_j & y_j  \\ 1 & x_m & y_m  \\ \end{bmatrix} = \begin{bmatrix} C \end{bmatrix}

we therefore have:

  u(x,y) = \begin{bmatrix} 1 & x  & y \end{bmatrix} \begin{bmatrix} C \end{bmatrix}^{-1} \begin{bmatrix} u_i\\ u_j \\ u_m \\ \end{bmatrix}
  v(x,y) = \begin{bmatrix} 1 & x  & y \end{bmatrix} \begin{bmatrix} C \end{bmatrix}^{-1} \begin{bmatrix} v_i\\ v_j \\ v_m \\ \end{bmatrix}

  \begin{bmatrix} N_i & N_j  & N_m \end{bmatrix}  = \begin{bmatrix} 1 & x  & y \end{bmatrix} \begin{bmatrix} C \end{bmatrix}^{-1}

B is defined as the matrix in this equation:

  \begin{bmatrix} \varepsilon \end{bmatrix}  = \begin{bmatrix} \frac{\partial N_i}{\partial x} & 0 &\frac{\partial N_j}{\partial x} & 0 & \frac{\partial N_m}{\partial x} & 0 \\ 0 & \frac{\partial N_i}{\partial y} & 0 & \frac{\partial N_j}{\partial y} & 0 & \frac{\partial N_m}{\partial y} \\ \frac{\partial N_i}{\partial y} & \frac{\partial N_i}{\partial x} &\frac{\partial N_j}{\partial y} & \frac{\partial N_j}{\partial x} & \frac{\partial N_m}{\partial y} & \frac{\partial N_m}{\partial x} \end{bmatrix} \begin{bmatrix} u_i \\ v_i \\ u_j \\ v_j \\ u_m \\ v_m \end{bmatrix}

Apply partial differentiation to the above equation we have

  \begin{bmatrix} \frac{\partial N_i}{\partial x}  &\frac{\partial N_j}{\partial x}  & \frac{\partial N_m}{\partial x} \end{bmatrix}  = \begin{bmatrix} 0 & 1  & 0 \end{bmatrix} \begin{bmatrix} C \end{bmatrix}^{-1}

  \begin{bmatrix} \frac{\partial N_i}{\partial y}  &\frac{\partial N_j}{\partial y}  & \frac{\partial N_m}{\partial y} \end{bmatrix}  = \begin{bmatrix} 0 & 0  & 1 \end{bmatrix} \begin{bmatrix} C \end{bmatrix}^{-1}

Rearrange the equation above, we can deduce:

  \frac{\partial N_i}{\partial x} = \begin{bmatrix} C \end{bmatrix}^{-1}_{2,i}

  \frac{\partial N_i}{\partial y} = \begin{bmatrix} C \end{bmatrix}^{-1}_{3,i}

By finding C, we can find B.

Now we have known the equations for B and C. Let’s find them in the code in the next post!

 

Categories
FEA

Writing 2D FEA in Python Gh 1

I finally got to write my own FEA code. Always wanted to do so but dreadful because I’m easily distracted and need a good time to focus on this.

Without a background in engineering yet working in an engineering company, I hope writing FEA can help me understand the engineering math.

I mainly follow this article right here and translate it to python. I will eventually upload my code to git but for now I will copy paste the pieces of my code here.

https://podgorskiy.com/spblog/304/writing-a-fem-solver-in-less-the-180-lines-of-code

I use the platform I’m most familiar with, Rhino Grasshopper which have existing methods to define and use mesh. However, I have to use Rhino 5 32bit this time because I want to use numpy for matrix calculation. I have covered the installation in a post below

Inputs

To start a FEA we need boundaries conditions:

A good triangulated mesh

Nodes which are mesh vertices

Support Conditions (nodes that are restrained)

Loading Conditions (loading vectors, loadPts)

Material Info (Poisson Ratio and Young Modulus)

Below is my set up in grasshopper

Set Up

I position the mesh at origin

Set Up 2

Set Up

In order to calculate efficiently, we need to do some “prepping”. We will set up list of nodes, edges, list of loads, list of constraints and list of elements (an element is a triangulated face)

Nodes: The input nodes currently are point3d. However, for convenience, we often refer to the nodes using its index. Whenever the situation arise, I use index to call out the nodes.

Edges: I store the indexes of the line’s start point and end point in a value pair

def GetEdges(mesh):
   edges = [] #list of vertex indices that make up the edges

   for i in range(mesh.TopologyEdges.Count):
       vPair = mesh.TopologyEdges.GetTopologyVertices(i)
       vPairPython = (vPair.I, vPair.J)
       edges.append(vPairPython)
   return edges

Loads: For loads, I need to store them in an array twice the size of the nodes array. Alternate items of the array are X and Y coordinates of the load vector

def GetLoads(nodes, loadPts, loadVs):
     loads = [0] * (len(nodes) * 2)
     for i in range(len(nodes)):
        for j in range(len(loadPts)):
          loadV = loadVs[j]
          dist = rs.Distance(loadPts[j],nodes[i])
          if dist < 0.001:
             loads[2 * i + 0] = loadV.X
             loads[2 * i + 1] = loadV.Y
      return loads

Constraints: I define a class for constraint where type is indicated by integer (1 is for constraint, x, 2 is for y, 3 is for both), node is point3d.

class Constraint:
    def __init__(self, type, node):
        self.Type = type
        self.Node = node
def GetConstraints(supportBoundaries, supportConds, nodes):
    constraints = []

    for i in range(len(nodes)):
        for j in range(len(supportBoundaries)):
           if rs.PointInPlanarClosedCurve(nodes[i], supportBoundaries[j]) == 1:
                con = Constraint(supportConds[j], i)
                constraints.append(con)
    return constraints

Elements: I created Element object woth properties are Nodes and NodeIds

class Element:
      def __init__(self, elemNodes, nodeIds):
           self.Nodes = elemNodes
           self.NodeIds = nodeIds
def GetElements(mesh):
      faceCt = rs.MeshFaceCount(mesh)
      elements = []
      for i in range(faceCt):
         faceVerticeIDs = rs.MeshFaceVertices(mesh)[i]
         nodeIds = faceVerticeIDs[:-1]
         elemNodes = [nodes[nodeIds[0]], nodes[nodeIds[1]], nodes[nodeIds[2]]]
         element = Element(elemNodes, nodeIds)
         elements.append(element)
      return elements

To list out all of them we have:

edges = GetEdges(mesh)
loads = GetLoads(nodes, loadPts, loadVs)
constraints = GetConstraints(supportBoundaries,supportConds, nodes ) #(restraintType, id)
elements = GetElements(mesh)

 

And…you’re done setting up the items to start on doing some math. I will cover the calculation/matrix manipulations in the next post

Categories
Fashion

TechFashion

As things get crazy because of the virus right now, the world wide lockdown seem to boost some views for this blog which has always been hidden in this very small corner of the internet. And as i am almost 100% locked in the house now, I should dedicate a bit more time to this blog. I decided not only focus on the tech side but also more on the theory, information bits, partly because some tech requires me much more time and dedication to discover and master before I can write a proper post.

The topic today is about high tech in fashion. Although I am not so much a well dressed and highly fashionable girl, fashion design is nevertheless fascinating. Fashion is fast, quick and more approachable, more appealing to the mass. Due to its fast nature, (I find) fashion is more updated to the current culture. Unlike art, fashion design has to uphold certain basic function, which make it more relevant to architecture and interesting to study. I will start this series with MetGala 2016 as an introduction then introduce some high tech fashion designers subsequently

ManusxMachina Met Gala

The Met Gala, formally called the Costume Institute Gala and also known as the Met Ball, is an annual fundraising gala in the benefit of the Metropolitan Museum of Art’s Costume Institute in New York City. (Source: Wikipedia). Every year, an exhibition is held and a gala filled with celebrities is organized. In 2016, the Met Gala theme was ManusxMachina.

met 1

In the words of the curator, ManusxMachina explores how fashion designers are reconciling the handmade and the machine-made in the creation of haute couture and avant-garde ready-to-wear. ManusxMachina is not necessarily about “robotic clothing”, but rather about subtle hidden technologies:

“Traditionally, the handmade has been seen as being about luxury whereas the machine has been about progress and the future. On the other side, it’s been about mediocrity and dehumanization. Those values sometimes dont really hold up”

Hmm the statement draws some parallel to the architecture world. Since the industrial revolution, buildings starts being made by machine, with parts made from mass production. The machine-made standardised building quickly fill up and rapidly form the cities today. Are they seen as mediocrity and dehumanization too? Or are they seen as futuristic. Again, these values do not have to hold up. Technology should open us to more possibility and diversity in design, rather than sticking them to certain connotation.

For more details, check out the link below!

https://www.metmuseum.org/exhibitions/listings/2016/manus-x-machina

Issey Miyake

Issey Miyake is a Japanese designer. Besides designing sculptural clothing that make you look like an origami penguine, Issey Miyake has many recognisable works such as the triangulated folding bag and Steve Job’s turtleneck

Master Class: Issey Miyake          Bao Bao Issey Miyake Prism shopper tote            Steve Jobs: This is what it really takes to achieve great success

Miyake’s design process explores the fundamental relationship between the body, the cloth that covers it, and the space and room that is created between these elements, divesting itself of the labels of “East” or “West”. He is interested in making innovative improvements to the traditional techniques, breathing new life to historic techniques to respond to the demand of times.

Issey Miyake most notable works are:

Pleating: A technique that allows both flexibility of movement for the wearer as well as ease of care and production using light weight material.

APOC (A piece of cloth): A-POC create fabric and clothing from a single thread with a high degree of variation using computerized instructions.

Source: http://mds.isseymiyake.com/im/en/work/

Iris Van Herpen

Of course we cannot forget to mention Iris Van Herpen when it comes to high tech fashion. Iris Van Herpen is a Dutch fashion designer who is the pioneer in utilizing 3D printing as a garment construction technique. Her multi disciplinary technique has led to collaboration with various designers such as Jolan vander Weil, Neri Oxman and architects such as Philip Beesley and Benthem and Crowel Architects.

What I’m most impressed is not the technology she used but her design process where she incorporate the technology in the design process. The inspiration come directly from the designer’s interest and spring into idea through conceptualizing her own personal sensory, perception of the world. Using technology, Iris is able express and let that idea evolve into physical object by itself.

“When I work on my design, it’s about finding a moment for a woman rather than finding an identity”  “A lot of collections start from experiment and a lot of things start from a failure as well”

The results are absolutely stunning. “The designs are so ethereal yet futuristic, fragile yet fierce, delicate yet powerful.” (from an internet comment)

Ying Gao

Ying Gao is a Chinese Montreal based fashion designer. She has many exhinition around the world and featured in prestigious international media.

“Ying Gao questions our assumptions about clothing by combining fashion design, product design and media design. She explores the construction of the garment, taking her inspiration from the transformations of the social and urban environment. Design is the medium, situated in the technological and the textile realm : sensory technologies allow garments to become more poetic and interactive.”

Source: yingao.ca

Other designers you can search for include Junya Watanabe, Jean-Paul Gaultier, or Anouk Wipprecht

Categories
Installation

Install scipy and numpy in Rhino

Hi all,

After a painful process of installling numpy. I would summarize my process as below. Hope it is helpful to everyone.

  1. Download all the egss here. If the link do not work, google “numpy egg enthought”

http://code.enthought.com/.iron/eggs/index.html

Download all of them to your Downloads folder

  1. Follow the instruction here. Follow step 4, 5 ,6 under this link
“C:\Program Files (x86)\IronPython 2.7\ipy.exe” IronPython_numpy_scipy.py --install

It will return an “egginst” error. That’s because you do not have that module yet.

  1. Download ironpkg here

Copy the egginst folder to downloads

  1. Repeat step 2
  2. Modify settings in RhinoPython as step 3 in here
  1. Finally import clr, mtrand, numpy described in the link above. However, please note that this only works in Rhino5 32 bit.
Categories
Computer Vision

yOgA sTrUcT

Although I really enjoy learning, certain topic could be a long and arduous journey which often land me scrolling through the internet looking at dogs and cats or random youtube music videos. Thus, instead of researching or learning a computational topic in depth today, the designer in me decided to write some cheap quick and easy code but able to get something appear on my screen just for the cheap thrill of feeling like a “CoMpUtAtIoNaL DeSiGnEr”.

Beside being a computational designer, I am also a recent practitioner of yoga. While trying out new and more challenging poses, I often find the process of balancing as something iterative. Once finding the balance, the right spot, the pose become much easier and require much less strength. Inspired by the practice, I been trying to bring images of yoga poses photo to a 3D vector skeleton in Rhino.

I run the yoga pose image through two algorithm: poseNet and denseDepth. poseNet returns the human skeleton, with the “coordinates” of the joints. These coordinates are then mapped onto denseDepth image, return us the “brightness” of that pixels. All these numbers are then brought into Rhino and make up a 3D human skeleton.

Gratitude-Asana_Briohny-Smyth_Warrior2

Original Image

PoseNet - December 15th 2019 at 10.20.27 PM

PoseNet

Gratitude-Asana_Briohny-Smyth_Warrior2 Dense Depth

Dense Depth

Gratitude-Asana_DD MappedJts

Dense Depth with mapped joints (zoom in closely)

3D result…sorry for the exploded head hehe.

I understand that there are much better algorithm to do this such as densepose and the result looks very different from the image, but hey this is just an attempt for me to have some fun!

Design a site like this with WordPress.com
Get started