# Unexpected spikes in noise values?

**URL:** <https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801>\
**Category:** Processing\
**Created:** [June 19, 2021, 7:49pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801 "2021-06-19T19:49:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![zmitchell](https://avatars.discourse-cdn.com/v4/letter/z/c2a13f/32.png) [@zmitchell](https://discourse.processing.org/u/zmitchell)\
**Post date:** [June 19, 2021, 7:49pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/1 "2021-06-19T19:49:34Z")

</div>

I’m trying to create a circle/ellipse/loop whose radius varies with the built-in noise function. I’m using Quil, a set of Clojure bindings to the Processing framework, so I’ll paste my code below and explain it since I suspect few if any here are Clojure people.

## Problem

First, here is the output. I’ve limited it to a single loop and illustrated each vertex with a little dot.

 ![ringing](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/af808f372eae9511a76bbf228f9e97f07745c0ff.png)  
The spike happens between the first, last, and second to last points. The first point is at a radius of 186.96024, the last point is at a radius of 202.97652, and the second to last point is at a radius of 180.59953.

The fact that the second to last point is inwards of the mean, the last point is outside of the mean leads me to believe there’s some kind of instability near that point in the noise function.

## Code

Here is the code for how I generate this (explanation below):

```clojure
(defn noise-path
  []
  (let [divs 1000
        nscale 0.008
        mean-rad (* 0.75 win-rad)
        ]
    (reduce
      (fn
        [acc div]
        (let [{:keys [last-x last-y]} acc
              noise (q/noise
                      (* nscale last-x)
                      (* nscale last-y))
              max-rad (* 1.25 mean-rad)
              min-rad (* 0.75 mean-rad)
              new-rad (q/map-range noise 0 1 min-rad max-rad)
              angle (* q/TWO-PI (/ div divs))
              new-x (* new-rad (q/cos angle))
              new-y (* new-rad (q/sin angle))]
          (-> acc
              (assoc :last-x new-x)
              (assoc :last-y new-y)
              (update :vertices
                      (fn [vs] (cons [new-x new-y] vs))))
          ))
      {:last-x (* nscale (q/random 0 d))
       :last-y (* nscale (q/random 0 d))
       :vertices nil}
      (range divs))))

```

I divide the ellipse into some number of angle increments (`divs`, 1000 in this case), then iterate over them to generate a random radius at each angle.

To generate a random radius I first set a mean radius (`mean-radius`, randomly selected in the real code, set to 0.75x the window radius for debugging), then from that mean radius I set an upper bound (`max-rad`) and lower bound (`min-rad`) within which the randomly selected radius will be selected. I use the (scaled) x- and y-coordinates of the previous point as the inputs to the noise function (`q/noise`, which is just Processing’s `noise` function).

When I’m “rendering” the path I just connect the vertices with lines and let `end-shape` close the shape.

## Thoughts

I haven’t been able to figure out why the last point freaks out. The last point isn’t always on the inside or outside of the mean, and it’s not pegged at the minimum or maximum radius.

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [June 20, 2021, 2:13pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/2 "2021-06-20T14:13:07Z")

</div>

i think you want looping noise or 2d noise. you can see it in this [daniel shiffman codingtrain video](https://youtu.be/ZI1dmHv3MeM?t=314) the whole video is worth a watch but i’ve set it at the point it relates to your issue

---

<div class="post-metadata">

**Author:** ![zmitchell](https://avatars.discourse-cdn.com/v4/letter/z/c2a13f/32.png) [@zmitchell](https://discourse.processing.org/u/zmitchell)\
**Post date:** [June 20, 2021, 6:46pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/3 "2021-06-20T18:46:44Z")

</div>

That’s actually a different issue. I do use 2D noise, and I use point `n-1` to determine the noise value for point `n`, which keeps the noise values close to one another.

In the video you posted when Daniel displays the curve without `close`-ing the shape, you can see that the radius slowly wanders away from the initial radius. If you look at the image I’ve posted below (displayed the same way i.e. without closing the curve), you can see that it’s just the last couple of points that begin to oscillate. To me that points at some kind of numerical instability in the noise function.

 ![jump](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c421806f3045f8a1483bd14e2efe3b58a19f0e9f.png)

---

<div class="post-metadata">

**Author:** ![debxyz](https://avatars.discourse-cdn.com/v4/letter/d/58956e/32.png) [@debxyz](https://discourse.processing.org/u/debxyz)\
**Post date:** [June 20, 2021, 8:31pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/4 "2021-06-20T20:31:04Z")

</div>

> [@zmitchell](#):
>
> To me that points at some kind of numerical instability in the noise function.

However the spikes are not happening in the Shiffman tutorial…  
There must be some other variable at play?

> [@zmitchell](#):
>
> I divide the ellipse into some number of angle increments ( `divs` , 1000 in this case), then iterate over them to generate a random radius at each angle.

In the Shiffman tutorial there is a single point of origin from where the circle begins. Since I cannot read the code provided and am basing this on your description, I wonder if you have a single point of origin in how you are drawing your circle? Also the noise appears to be mirrored in the 4 quadrants of the circle…  
which may be your intention, however could that be a factor that is affecting the desired smooth closure of the shape?  
🤓

---

<div class="post-metadata">

**Author:** ![zmitchell](https://avatars.discourse-cdn.com/v4/letter/z/c2a13f/32.png) [@zmitchell](https://discourse.processing.org/u/zmitchell)\
**Post date:** [June 21, 2021, 6:03pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/5 "2021-06-21T18:03:18Z")

</div>

I threw together a Java (Processing) version of the program so that everyone else can see exactly what’s happening:

```java
void setup() {
  size(500, 500);
  colorMode(HSB, 360, 100, 100, 1);
  pixelDensity(2);
  randomSeed(0);
  noiseSeed(0);
  smooth();
}

void draw() {
  noLoop();
  background(263, 11, 46);
  fill(9, 26, 100);
  noStroke();
  int d = 500;
  float win_rad = (0.99 * d) / 2;
  ellipse(d/2, d/2, d/25, d/25);
  strokeWeight(d/500);
  stroke(360, 0, 100, 1);
  noFill();
  float mean_radius = 0.75 * win_rad;
  float min_rad = 0.75 * mean_radius;
  float max_rad = 1.25 * mean_radius;
  float nscale = 0.008;
  float last_x = random(0, d);
  float last_y = random(0, d);
  int divs = 1000;
  translate(d/2, d/2);
  beginShape();
  for (int div = 0; div < 1000; div++) {
    float noise_value = noise(nscale*last_x, nscale*last_y);
    //float new_rad = noise_value * (min_rad + max_rad) - min_rad;
    float new_rad = map(noise_value, 0.0, 1.0, min_rad, max_rad);
    float angle = 2 * 3.14159 * ((float)div / (float)divs);
    float x = new_rad * cos(angle);
    float y = new_rad * sin(angle);
    vertex(x, y);
    last_x = x;
    last_y = y;
  }
  endShape();
  save("sketch.png");
}

```

> [@debxyz](#):
>
> In the Shiffman tutorial there is a single point of origin from where the circle begins. Since I cannot read the code provided and am basing this on your description, I wonder if you have a single point of origin in how you are drawing your circle?

I’m not exactly sure what you mean by this. The origin of my loop is right in the center of the window.

> [@debxyz](#):
>
> Also the noise appears to be mirrored in the 4 quadrants of the circle…

Yeah, I don’t know why that happens.

---

<div class="post-metadata">

**Author:** ![debxyz](https://avatars.discourse-cdn.com/v4/letter/d/58956e/32.png) [@debxyz](https://discourse.processing.org/u/debxyz)\
**Post date:** [June 22, 2021, 12:40am UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/6 "2021-06-22T00:40:51Z")

</div>

> [@zmitchell](#):
>
> I’m not exactly sure what you mean by this. The origin of my loop is right in the center of the window.

I was referring to where along the radius of the circle the first point is placed. And I see your code provides the answer. 🙂

And regarding the 4 quadrants:

> [@zmitchell](#):
>
> Yeah, I don’t know why that happens.

I was curious and rewatched the Shiffman tutorial. He does address the reason and solution to the mirrored quadrants.  
**He adds +1** to the lines below like this:

> [@zmitchell](#):
>
> ```auto
> float x = new_rad * cos(angle) + 1;
> float y = new_rad * sin(angle) + 1;
> 
> ```

**However** when I tested that with your code, **it didn’t work…**  
Your code is basically modeled on Shiffman solution, but there is something extra going on and I can’t figure out what that extra thing is.

If you haven’t already you might try doing a line by line comparison between Shiffman code in the tutorial and your code to see if (or where) there is an unintended departure?

At this point I’ll have to take a step back as I’m not sure definitively the issue.  
Good luck!  
🤓

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [June 22, 2021, 4:38pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/7 "2021-06-22T16:38:55Z")

</div>

if you watch that video you can see the symmetry comes from where you are sampling the noise and can be fixed by offsetting the sample point (explained [here](https://youtu.be/ZI1dmHv3MeM?t=704) in the video). the other problem is the noise not being closed correctly and that is because you are not sampling from the noise space in a perfect circle but rather by feeding the noisy values back in and breaking the circle many times. basically you need to decouple the sampling and the use of the sample. i don’t have processing installed atm but [here](https://editor.p5js.org/hotfooted/sketches/rfiEBCTgS) is a p5js example that works and here is your code modified which should work (i haven’t tested it).

```auto
void setup() {
  size(500, 500);
  colorMode(HSB, 360, 100, 100, 1);
  pixelDensity(2);
  randomSeed(0);
  noiseSeed(0);
  smooth();
}

void draw() {
  noLoop();
  background(263, 11, 46);
  fill(9, 26, 100);
  noStroke();
  int d = 500;
  float win_rad = (0.99 * d) / 2;
  ellipse(d/2, d/2, d/25, d/25);
  strokeWeight(d/500);
  stroke(360, 0, 100, 1);
  noFill();
  float mean_radius = 0.75 * win_rad;
  float min_rad = 0.75 * mean_radius;
  float max_rad = 1.25 * mean_radius;
  float nscale = 0.8;
  int divs = 1000;
  translate(d/2, d/2);
  beginShape();
  for (int div = 0; div < 1000; div++) {
    float angle = 2 * 3.14159 * ((float)div / (float)divs);
    float cosValue = cos(angle);
    float sinValue = sin(angle);
    float noise_value = noise(1 + nscale * cosValue, 1 + nscale * sinValue);
    //float new_rad = noise_value * (min_rad + max_rad) - min_rad;
    float new_rad = map(noise_value, 0.0, 1.0, min_rad, max_rad);
    float x = new_rad * cosValue;
    float y = new_rad * sinValue;
    vertex(x, y);
  }
  endShape();
  save("sketch.png");
}

```

---

<div class="post-metadata">

**Author:** ![zmitchell](https://avatars.discourse-cdn.com/v4/letter/z/c2a13f/32.png) [@zmitchell](https://discourse.processing.org/u/zmitchell)\
**Post date:** [July 5, 2021, 8:24pm UTC](https://discourse.processing.org/t/unexpected-spikes-in-noise-values/30801/8 "2021-07-05T20:24:38Z")

</div>

I figured it out, so I’ll document what I found in case anyone else has the same issue in the future.

## “Aha” moment

I plotted the points along the loop with varying brightness and discovered that it wasn’t the last few points that were “freaking out,” but instead it was the first few! I messed this up because the axes are oriented differently from how you would think of the axes in a math class.

## Context

I’m generating each loop vertex sequentially based on the previous one. In principle this works because even though you aren’t sampling the noise in a perfect circle, you’re still sampling the noise from points that are very close to one another i.e. point `n` is close to point `n-1`, so the difference in noise values shouldn’t be huge. This also works in practice, which is why most of my loop is fine aside from a few points. In fact, if I add an extra vertex the loop closes no problem (aside from the bad first point).

However, if you generate point `n` based on point `n-1`, how do you generate the first point? The answer is that you just have to pick a point, but which point you choose makes a big difference.

## The _actual_ problem

How you select your first point is pretty arbitrary. After all, you’re just using these coordinates as the input to the `noise` function, not adding it as a vertex.

If you choose the point `(mean_rad, 0)` as the initial input for each loop, then loops with similar mean radii will end up looking similar because their first points are close to one another and they’re essentially sampling the same noise.

Another solution (the one I chose) was to select a random point within the window as the first input for each loop. This way each loop is more likely to look distinct from other loops. However, this is where the problem lies. Here’s how the chain of events goes:

1. Select a random location in the window `(n_x, n_y)` as the initial input for the noise function.
2. Compute the radius `r_0` for the first point at `angle_0` based on `(n_x, n_y)`.
3. Compute `(x_0, y_0)` from the radius and angle relative to an origin placed at the center of the window.
4. Use `(x_0, y_0)` as the input for computing `(x_1, y_1)`
5. Repeat

The issue is that `(x_0, y_0)` and `(n_x, n_y)` are in completely different locations since `(n_x, n_y)` is chosen at random, whereas `(x_0, y_0)` is always plotted at `angle = 0` since it’s the first point.

## Solution

I think the easiest solution is just to sample the noise in a perfect circle as has been suggested, that way you don’t have to do things sequentially in the first place.
