# OPENRNDR & Processing - Coral growth

**URL:** <https://openrndr.discourse.group/t/openrndr-processing-coral-growth/77>\
**Category:** Tutorials\
**Created:** [April 2, 2020, 2:38pm UTC](https://openrndr.discourse.group/t/openrndr-processing-coral-growth/77 "2020-04-02T14:38:55Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [April 2, 2020, 2:38pm UTC](https://openrndr.discourse.group/t/openrndr-processing-coral-growth/77/1 "2020-04-02T14:38:55Z")

</div>

# Diffusion Limited Aggregation

A program that keeps a collection of circles. Initially there is only one located at the center of the screen. Circles of decreasing size are shot from the outskirts towards the center of the screen. When they touch any circle they freeze and become part of the collection. Read more about this algorithm at [http://paulbourke.net/fractals/dla/](http://paulbourke.net/fractals/dla/).

 ![P02_CoralGrowth-2020-04-02-15.54.51](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/dd3b4c0e0562c161568bb5e0280aeb33f45735c0.jpeg)

### Processing / Java

```auto
ArrayList<PVector> circles = new ArrayList<PVector>();
void setup() {
  fullScreen();
  noStroke();
  fill(40);
  background(220);
  circles.add(new PVector(0, 0, 120));
}
void draw() {
  background(255);
  translate(width/2, height/2);
  for (PVector p : circles) { 
    ellipse(p.x, p.y, p.z, p.z);
  }
  PVector newPos = PVector.fromAngle(millis() * 0.05).mult(width);
  float newDiam = circles.get(circles.size()-1).z * 0.98;
  boolean search = true;
  while (search) {
    newPos.sub(newPos.copy().normalize());
    for (int i=circles.size()-1; i>=0; i--) {
      PVector other = circles.get(i);
      float d = dist(other.x, other.y, newPos.x, newPos.y);
      float minDist = other.z * 0.5 + newDiam * 0.5 + 5;
      if (d < minDist) {
        newPos.z = newDiam;
        circles.add(newPos);
        search = false;
        break;
      }
    }
  }
}

```

### OPENRNDR / Kotlin

```auto
fun main() = application {
    configure {
        fullscreen = Fullscreen.CURRENT_DISPLAY_MODE
    }
    program {
        val circles = mutableListOf(Circle(0.0, 0.0, 60.0))

        extend {
            drawer.stroke = null
            drawer.fill = rgb(0.2)
            drawer.background(rgb(0.9))
            drawer.translate(drawer.bounds.center)
            drawer.circles(circles)

            var newPos = Polar(seconds * 5091, width * 1.0).cartesian
            var newRadius = circles.last().radius * 0.98
            var search = true
            while (search) {
                newPos -= newPos.normalized
                circles.lastOrNull { other ->
                    val d = (other.center - newPos).length
                    val minDist = other.radius + newRadius + 5
                    d < minDist
                }?.run {
                    circles.add(Circle(newPos, newRadius))
                    search = false
                }
            }
        }
    }
}

```

Differences to note:

| Topic | Processing | OPENRNDR |
| --- | --- | --- |
| define and initialize a collection | `ArrayList<PVector> circles = new ArrayList<PVector>();`  
 `circles.add(new PVector(0, 0, 120));` | `val circles = mutableListOf(Circle(0.0, 0.0, 60.0))` |
| drawing circles | expects width and height: initial size is `120.0` then multiplies diameters by `0.5` | expects radius: initial size is `60.0` |
| colors | defined using byte values (`0 ~ 255`) | defined using normalized values (`0.0 ~ 1.0`) |
| vector data type | `PVector` | `Vector2`, `Vector3` and `Vector4`, but in this case we use `Circle` for two reasons: one, we can use it with the method `drawer.circles()` to efficiently draw collections of circles and two, the code becomes more readable by using `.center` and `.radius` instead of `.x`, `.y` and `.z` |
| polar coordinates | `PVector.fromAngle(radians)` then call `.mult(radius)` to set the length | `Polar(degrees, radius).cartesian` |
| finding last circle colliding with the current moving circle | classic `for` loop with `break` when found | `lastOrNull` searches for the last colliding item. if found `?.run` a block of code to add a circle |
| center of the screen | `(width/2, height/2)` | `drawer.bounds.center` or  
 `(width/2.0, height/2.0)` |
| declaring variables | specify type: `float`, `boolean`, `ArrayList<PVector>` | use `var` (mutable) or `val` (inmutable) |
| time | `millis()` | `seconds` |

👇 Share your questions and comments below | 🔎 [Find other OPENRNDR & Processing posts](https://openrndr.discourse.group/search?q=Processing%20%23openrndr%3Atutorials)
