colidescope

/live/ circle-packing

Circle Packing with OOP

Introduction

This demo describes how we can use dynamic systems and agent-based models to further abstract the relationship between a set of input parameters and a set of solutions in a design space. To create such a system we define a collection of agents who follow a set of rules or behaviors over a series of time steps. These behaviors dictate how the agents interact with other agents and their environment, and how these interactions affect the internal state of the agents.

Working with agents

In computer science, such systems are often called agent-based models and we can easily implement them using Object-oriented programming (OOP). To do so we create a class which defines the structure of the agent, with local variables that define its states and a set of methods which define its behaviors. Then we create a set of instances of this Class and let the instances play out their behaviors over a series of time steps. Because such a system has to play out over multiple time steps, it is called a dynamic system, as opposed to static systems which can be computed directly in one step.

Agent-based systems are often used to model complex behaviors in nature, which are also typically defined by the interaction of a large number of agents who are driven by a relatively simple set of rules. Examples of such systems include the flocking of birds, the organization of ants, the growth of slime mold, and the construction of termite mounds. These types of systems are often called emergent because of their ability to develop highly complex behaviors and structures from a set of relatively simple behaviors.

description

Flocking is a typical complex behavior which can be simulated through agent-based programming


This session will introduce you to the concept of agent-based behavior and how it can be used to create a packing model in Python.

With agent-based behavior, we can model complex systems based on the interactions of many agents following a set of simple rules. In a way, this is similar to recursion as it allows us to break our problem into smaller parts, and explore different solutions to the problem by varying the way those parts get executed.

In the demo, we will start to build the packing-based layout model by implementing a custom Python Class to represent each space in the layout. These spaces will be the agents in our system, and we will program different behaviors for them using their methods. The two main behavior we will implement are:

  • collide - this will cause the agents to move away from each other if they overlap
  • attract - this will cause agents to move toward each other based on a desired adjacency.
⚠️ You need a premium account to access this content.

Downloads

⚠️
⚠️
You need a premium account to access this content.
05-01-02-end.gh

⚠️ You need a premium account to access this content.

Downloads

⚠️
⚠️
You need a premium account to access this content.
05-01-04-end.gh

⚠️ You need a premium account to access this content.

Downloads

⚠️
⚠️
You need a premium account to access this content.
05-01-05-end.gh

CHALLENGE

In the demo we created the basic framework for a new Class called “Room”, which creates an object with a given center point and radius, and a basic “collision” method for checking its distance to another object and moving them away from each other if they are too close. In this tech challenge, you will implement a complementary method called “cluster” which will move the object closer to a specified “neighbor” object.

Download and open the starting Grasshopper file. This model has been extended with several new features:

  • Line 10: When an object is initialized, an empty list called “neighbors” is created to store the object’s neighbors.
  • Line 13: An addNeighbor() method has been implemented in the Room class which adds a given object to the instance’s list of neighbors.
  • Line 35: An empty method called cluster() has been created. The method contains a single line with the pass keyword which will do nothing but is necessary so that the code does not throw an error due to an empty method. This is where you will implement the object’s cluster behavior for this week’s challenge.
  • Line 48: A loop has been added which iterates over each room object and uses its addNeighbor() method to add the previous room in the list to it’s list of neighbors.
  • Line 58: Within the optimization loop which runs the collision behavior for each pair of rooms, another loop has been added to run the “cluster” behavior for each room and its neighbors.

For this week’s challenge, replace the pass keyword in the cluster() method of the Room class with code to enable the clustering behavior between two objects. After you’ve properly completed the method, you should see the objects cluster together in the canvas. This is driven by the objects trying to move closer to their neighbors, while still avoiding overlaps due to the collision() method:

packing

Left: final position of objects with only “collision” implemented Right: final position of objects with “collision” and “cluster” implemented

Once you’ve completed the challenge, capture a screenshot of your Rhino/Grasshopper/Python windows so that the additional code is visible. Name the file with your UNI and/or name, and use this link to upload your file..

Hint

The cluster() method should be very similar to the collision() method, with a few minor differences:

  • After measuring the distance between center points, the movement behavior should be triggered if the distance is greater than the sum of radiuses.
  • The vector for moving the objects should be based on the gap between them (the distance minus the sum of radii) instead of the overlap (sum of radii minus the distance)
  • Based on how you calculate the initial vector, make sure that you are moving the right object in the right direction so that the objects end up moving toward each other.