# OPENRNDR & Processing - Additive wave example

**URL:** <https://openrndr.discourse.group/t/openrndr-processing-additive-wave-example/196>\
**Category:** Tutorials\
**Created:** [January 29, 2021, 2:29pm UTC](https://openrndr.discourse.group/t/openrndr-processing-additive-wave-example/196 "2021-01-29T14:29:18Z")\
**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:** [January 29, 2021, 2:29pm UTC](https://openrndr.discourse.group/t/openrndr-processing-additive-wave-example/196/1 "2021-01-29T14:29:18Z")

</div>

# Additive wave example

![2021-01-29-124047_640x360_scrot](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/6458839ed7b0ebc41a8bdca6c62d6db96eba17cb.png)

Following previous posts in which I compared OPENRNDR and Processing code, this time I “reinterpreted” the next Processing example:

### Processing / Java

> <https://github.com/processing/processing-docs/blob/b28911774c8aa8f537c8ef6d26ca09cf7891e20a/content/examples/Basics/Math/AdditiveWave/AdditiveWave.pde>

You can click “show original” above to compare it with the following code:

### OPENRNDR / Kotlin

> **imports**
>
> ```auto
> import org.openrndr.application
> import org.openrndr.color.ColorRGBa
> import org.openrndr.extra.noise.Random
> import org.openrndr.shape.Circle
> import kotlin.math.PI
> import kotlin.math.sin
> 
> ```

```auto
private data class SineWave(val freq: Double, val shift: Double, val amp: Double) {
    fun value(t: Double, x: Double) = amp * sin(t * freq + shift * x)
}
fun main() = application {
    program {
        val numPoints = 80
        val sineWaves = List(5) { SineWave(-5 rnd 5, 0 rnd PI * 2, 10 rnd 30) }
        extend {
            drawer.clear(ColorRGBa.BLACK)
            drawer.fill = ColorRGBa.WHITE.opacify(0.3)
            drawer.stroke = null
            drawer.circles(List(numPoints) { num ->
                val x = width * num / (numPoints - 1.0)
                val y = height * 0.5 + sineWaves.sumOf {
                    it.value(seconds, x * 0.01)
                }
                Circle(x, y, 10.0)
            })
        }
    }
}
private infix fun Number.rnd(max: Number) =
    Random.double(this.toDouble(), max.toDouble())

```

The resulting animated-additive-sine wave looks similar but it’s not a literal translation, as I wanted to write something simpler and making use of Kotlin’s features.

# Differences

Observe how the original code uses 5 for loops and the Kotlin code uses none.

| Purpose | Processing | OPENRNDR |
| --- | --- | --- |
| initialize variables | `for` loop | replaced by `List(5){...}` |
| set variables to zero and accumulate wave height | 3 `for` loops | replaced by one call to `List(numPoints)` and `.sumOf` used to accumulate the wave height at each point |
| render all the circles | `for` loop | replaced by OPENRNDR’s `drawer.circles()` method which takes a list of `Circle` instances |

The original code toggles between sine and cosine, but I found that unnecessary since sine is basically a shifted cosine 🙂 Instead, I created a data class called SineWave which has three properties: frequency, shift and amplitude. I included a `value()` method in that class which takes time and horizontal-position-in-the-waveform as arguments and returns the vertical shift.

Note the `rnd` **infix function** at the bottom. It allows me to write

```auto
SineWave(-5 rnd 5, 0 rnd PI * 2, 10 rnd 30)

```

instead of the longer version

```auto
SineWave(
  Random.double(-5.0, 5.0), 
  Random.double0(PI * 2), 
  Random.double(10.0, 30.0)
)

```

Finally, see how the original code uses 7 “global” variables", a few of them used to express one idea: a collection of sine waves. Kotlin makes it very easy to create data classes, basically in one line of code, grouping related properties together under one object. I used it to try to make it more obvious that we are working with a `List` of `SineWave`s.

# Closing thoughts

As it happens most of the time, I find the Kotlin code beautiful and easier to understand. The program is called AdditiveWave and it has one line that reads `sineWaves.sumOf` perfectly matching the program name. The Java code feels lower level and needs comments to clarify intentions. It is possible that the lower level code is better for learning or teaching computation, but at least in my daily work I find Kotlin more understandable and easier to work with. I can express myself with less effort and when I look at my previously written OPENRNDR programs I spend less time trying to understand what they do.

ps. Modern Java supported in the coming Processing 4 may allow simplifying the original program too. Feel free to share how that might look like.  
ps 2. Don’t use this code to run self driving vehicles 🙃 I’m only learning and sharing what I learn.

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