Active Fractals

Sirenia Yookyung Kim
Data Mining the City
3 min readOct 2, 2019

Fractals can be found throughout nature; they are a complex network of patterns and relationships that portray the incremental growth of life. Found in snowflakes, trees, oceans and clouds, it can be used to understand rules and formulas that govern the environment at various scales.

Active fractals can be used as a model for the endlessly morphing network of modern behaviors in cities over time, from local to global scales. By defining the parameters and limits of fractal infrastructures, we can start to change spatial systems while still accommodating for individual variety and temporal growth.

FRACTALS IN NATURE — SHARED GEOMETRY
FRACTALS IN CITIES — SHARED SPACES

To begin visualizing this simple but complex spatial network, basic geometric shapes (sphere and cube) were used to represent the base module. Then, parameters and relationships between the geometry were defined. Additionally, randomness and time factors were applied to simulate the organic nature of fractals.

  • Agents: Spatial modules (Spheres & Cubes)
  • Environment: Varies (Confined in limits of Unity and my computer for this case)
  • Behavior: Similar, repeating patterns at multiple scales
  • Parameters: Shape, Size, Orientation, Rotation, Color, Speed, Spawn Probability
  • Global inputs and outputs: A set of spatial characteristics and patterns (physical or digital) can be input to help visualize and understand the system at different scales

Below are code snippets used for the simulation.

  1. Start Making the Children
private void Start(){//Make Multiple Childrenif (depth < maxDepth){StartCoroutine(CreateChildren());}//Randomize Rotation Angle and SpeedrotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);transform.Rotate(Random.Range(-maxTwist, maxTwist), 0f, 0f);if (materials == null){InitializeMaterials();}//Randomize Meshes and MaterialsgameObject.AddComponent<MeshFilter>().mesh = meshes[Random.Range(0, meshes.Length)];gameObject.AddComponent<MeshRenderer>().material = materials[depth, Random.Range(0, 2)];}

2. Loop Over One Child at a Time

private IEnumerator CreateChildren(){for (int i = 0; i < childDirections.Length; i++){if (Random.value < spawnProbability){yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));new GameObject("Fractal Child").AddComponent<Fractal>().Initialize(this, i);}}}

3. Define Characteristics and Behavior of Children

//Define characteristics and behavior of childrenprivate void Initialize(Fractal parent, int childIndex){meshes = parent.meshes;materials = parent.materials;depth = parent.depth + 1;childScale = parent.childScale;spawnProbability = parent.spawnProbability;maxDepth = parent.maxDepth;maxRotationSpeed = parent.maxRotationSpeed;maxTwist = parent.maxTwist;transform.parent = parent.transform;transform.localScale = Vector3.one * childScale;transform.localPosition = childDirections[childIndex] * (0.5f + 0.5f * childScale);transform.localRotation = childOrientations[childIndex];}

4. Change Orientation and Direction of Children

//Change direction of childrenprivate static Vector3[] childDirections = {Vector3.up,Vector3.right,Vector3.left,Vector3.forward,Vector3.back};//Change orientation of childrenprivate static Quaternion[] childOrientations = {Quaternion.identity,Quaternion.Euler(0f, 0f, -90f),Quaternion.Euler(0f, 0f, 90f),Quaternion.Euler(90f, 0f, 0f),Quaternion.Euler(-90f, 0f, 0f)};

5. Rotate Elements Over Time

private void Update(){transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);}

6. Change Material and Color

private void InitializeMaterials(){materials = new Material[maxDepth + 1, 2];for (int i = 0; i <= maxDepth; i++){float t = i / (maxDepth - 1f);t *= t;materials[i, 0] = new Material(material);materials[i, 0].color = Color.Lerp(Color.white, Color.cyan, t);materials[i, 1] = new Material(material);materials[i, 1].color = Color.Lerp(Color.white, Color.blue, t);}materials[maxDepth, 0].color = Color.red;materials[maxDepth, 1].color = Color.magenta;}

--

--