# Order of layers not working as expected

**URL:** <https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452>\
**Category:** Coding Questions\
**Created:** [January 5, 2023, 6:39am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452 "2023-01-05T06:39:04Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![slacle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slacle/32/19522_2.png) [@slacle](https://discourse.processing.org/u/slacle)\
**Post date:** [January 5, 2023, 6:39am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/1 "2023-01-05T06:39:04Z")

</div>

I want the circles on top and all the lines below them. Since I’m drawing the circles last, I expected them to all be on top of the lines.

How can I solve this problem?

p.s.: This is only a small simplified piece of what I’m actually working on.

![canvas](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/5/9/59432a320fdcdfaf08b00f2ae984a33c0b91394e.png)

```auto
function setup() {
  createCanvas(400, 400);
  angleMode(DEGREES);
  background(50);
}

function draw() {
  for (let i = 0; i < 3; i++) {
    let x = 100 * cos(120 * i) + width / 2;
    let y = 100 * sin(120 * i) + height / 2;

    stroke(200);
    strokeWeight(2);
    line(
      x,
      y,
      100 * cos(120 * (i + 1)) + width / 2,
      100 * sin(120 * (i + 1)) + height / 2
    );

    fill(50);
    circle(x, y, 150);
  }
}

```

---

<div class="post-metadata">

**Author:** ![slacle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slacle/32/19522_2.png) [@slacle](https://discourse.processing.org/u/slacle)\
**Post date:** [January 5, 2023, 7:26am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/2 "2023-01-05T07:26:26Z")

</div>

I figured out the order that things are drawn.

1. first line is drawn
2. first circle is drawn
3. second line is drawn
4. second circle is drawn
5. third line is drawn
6. third circle is drawn

That was obvious, but helps to visualize.

I thought that circle 2 would be drawn where circle 4 is. Although then line 3 would be on top of that circle.

The problem is that both the lines and the circles are in the same loop. If I put them in separate loops then the problem would be fixed. But is there a way to fix the problem while still keeping them in the same loop?

![order](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/e/6ebc5bd03f34c9f11f9bd95b15f7249a33843abf.png)

```auto
function setup() {
  createCanvas(400, 400);
  angleMode(DEGREES);
  background(50);
}

function draw() {
  for (let i = 0; i < 3; i++) {
    let x = 100 * cos(120 * i) + width / 2;
    let y = 100 * sin(120 * i) + height / 2;

    stroke(100 * i);
    strokeWeight(5 * i + 1);
    line(
      x,
      y,
      100 * cos(120 * (i + 1)) + width / 2,
      100 * sin(120 * (i + 1)) + height / 2
    );

    fill(50);
    circle(x, y, 100);
  }
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 7:30am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/3 "2023-01-05T07:30:02Z")

</div>

> [@slacle](#):
>
> But is there a way to fix the problem while still keeping them in the same loop?

[**createGraphics()**](https://p5js.org/reference/#/p5/createGraphics)

```auto
'use strict';

var pg, cx, cy;

function setup() {
  createCanvas(400, 400);
  noLoop();

  fill(50).stroke(200).strokeWeight(2).angleMode(DEGREES);

  pg = createGraphics(width, height).fill(50).stroke(200).strokeWeight(2);

  cx = width >> 1;
  cy = height >> 1;
}

function draw() {
  background(50);
  pg.clear();

  var i = 0, px = 100 + cx, py = cy;

  while (i++ < 3) {
    pg.circle(px, py, 150);
    line(px, py, px = 100 * cos(120 * i) + cx, py = 100 * sin(120 * i) + cy);
  }

  image(pg, 0, 0);
}

```

---

<div class="post-metadata">

**Author:** ![slacle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slacle/32/19522_2.png) [@slacle](https://discourse.processing.org/u/slacle)\
**Post date:** [January 5, 2023, 8:46am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/4 "2023-01-05T08:46:08Z")

</div>

That works, but I can’t even understand the code 😕  
I’d rather just use two loops in that case.

And what about performance? What would be more performant? Using two loops or using createGraphics?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 9:16am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/5 "2023-01-05T09:16:50Z")

</div>

> [@slacle](#):
>
> What would be more performant? Using two loops or using **createGraphics()**?

`pg.circle(px, py, 150);` should have same performance as `circle(px, py, 150);`.

The slowest part is the additional statement `image(pg, 0, 0);`.

But I still think `image(pg, 0, 0);` should be much faster than having an extra loop.

> [@slacle](#):
>
> That works, but I can’t even understand the code 😕

Can you pinpoint exactly the parts where you couldn’t understand?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 9:32am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/6 "2023-01-05T09:32:06Z")

</div>

BtW, here’s my version w/ 2 loops in place of **createGraphics()** + **image()**:

```auto
'use strict';

var cx, cy;

function setup() {
  createCanvas(400, 400);
  noLoop();

  fill(50).stroke(200).strokeWeight(2).angleMode(DEGREES);

  cx = width >> 1;
  cy = height >> 1;
}

function draw() {
  background(50);

  var i = 0, px = 100 + cx, py = cy;

  while (i++ < 3)
    line(px, py, px = 100 * cos(120 * i) + cx, py = 100 * sin(120 * i) + cy);

  i = 0, px = 100 + cx, py = cy;

  while (i++ < 3) {
    circle(px, py, 150);
    px = 100 * cos(120 * i) + cx;
    py = 100 * sin(120 * i) + cy;
  }
}

```

---

<div class="post-metadata">

**Author:** ![slacle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slacle/32/19522_2.png) [@slacle](https://discourse.processing.org/u/slacle)\
**Post date:** [January 5, 2023, 9:33am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/7 "2023-01-05T09:33:31Z")

</div>

> [@GoToLoop](#):
>
> Can you pinpoint exactly the parts where you couldn’t understand?

Most of it 😛  
I guess by looking at it more I kind of understand, but just don’t see why write it like that. It’s more confusing for me.

I managed to just add the createGraphics() stuff to my previous code though:

```auto
let pg;

function setup() {
  createCanvas(400, 400);
  pg = createGraphics(400, 400);
  angleMode(DEGREES);
  background(50);
}

function draw() {
  image(pg, 0, 0);

  for (let i = 0; i < 3; i++) {
    let x = 100 * cos(120 * i) + width / 2;
    let y = 100 * sin(120 * i) + height / 2;

    pg.stroke(100 * i);
    pg.strokeWeight(5 * i + 1);
    pg.line(
      x,
      y,
      100 * cos(120 * (i + 1)) + width / 2,
      100 * sin(120 * (i + 1)) + height / 2
    );

    stroke(100 * i);
    strokeWeight(5 * i + 1);
    fill(50);
    circle(x, y, 100);
  }
}

```

It works here, but am having a bit of issues when introducing it to the rest of the sketch I’m working on. Things not working as expected when running as animation. And also things were looking a bit pixelated. Maybe pixel density issue.

I’ll keep playing with it and see what I manage. Thanks! 🙂

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 9:37am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/8 "2023-01-05T09:37:42Z")

</div>

> [@slacle](#):
>
> , but just don’t see why write it like that. It’s more confusing for me.

It’s just my attempt to halve the calls for both **cos()** & **sin()** and other calcs. 😇

---

<div class="post-metadata">

**Author:** ![slacle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slacle/32/19522_2.png) [@slacle](https://discourse.processing.org/u/slacle)\
**Post date:** [January 5, 2023, 9:44am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/9 "2023-01-05T09:44:47Z")

</div>

> [@GoToLoop](#):
>
> It’s just my attempt to halve the calls for both **cos()** & **sin()** and other calcs.

Ohhh, I see. Will that make a considerable difference in performance?

Also, why you do the chaining with the dots? Like fill(50).stroke(200).strokeWeight(2)? Is there a benefit to doing it this way instead of just one below the other without chaining with dots?

And what about the `>>`? I know those are bitwise operators, but how do they actually work?  
Would `width >> 1` be the same as `width / 2`?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 5, 2023, 10:16am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/10 "2023-01-05T10:16:37Z")

</div>

> [@slacle](#):
>
> Also, why do you do the chaining with the dots?

Given those 3 methods are chainable, I’m taking that opportunity to shorten the code.

> [@slacle](#):
>
> Would `width >> 1` be the same as `width / 2`?

Pretty much. W/ the added benefit of truncating the fractional part as well.

> [@slacle](#):
>
> Ohhh, I see. Will that make a considerable difference in performance?

A little for sure. Lowering unnecessary trigonometry calls always helps I guess.

Alternatively we could pre-calculate & cache those **cos()** & **sin()** calls into 2 arrays:

```auto
// Discourse.Processing.org/t/order-of-layers-not-working-as-expected/40452/10
// GoToLoop (2023/Jan/05)

'use strict';

const TURBO = true;
var pg, xCoords, yCoords;

function setup() {
  createCanvas(400, 400);
  noLoop();

  fill(50).stroke(200).strokeWeight(2).angleMode(DEGREES);

  pg = createGraphics(width, height).fill(50).stroke(200).strokeWeight(2);

  const
    cx = width >> 1,
    cy = height >> 1,
    length = { length: 4 };

  xCoords = Uint16Array.from(length, (_, i) => 100 * cos(120 * i) + cx);
  yCoords = Uint16Array.from(length, (_, i) => 100 * sin(120 * i) + cy);

  console.table(xCoords);
  console.table(yCoords);
}

function draw() {
  background(50);
  pg.clear();

  TURBO? turboLoop() : regularLoop();

  image(pg, 0, 0);
}

function regularLoop() {
  for (var i = 0; i < 3; ++i) {
    const
      x = xCoords[i],
      y = yCoords[i],
      a = xCoords[i + 1],
      b = yCoords[i + 1];

    pg.circle(x, y, 150);
    line(x, y, a, b);
  }
}

function turboLoop() {
  var i = 0, [px] = xCoords, [py] = yCoords;

  while (i++ < 3) {
    pg.circle(px, py, 150);
    line(px, py, px = xCoords[i], py = yCoords[i]);
  }
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [January 5, 2023, 11:04am UTC](https://discourse.processing.org/t/order-of-layers-not-working-as-expected/40452/11 "2023-01-05T11:04:28Z")

</div>

> [@slacle](#):
>
> But is there a way to fix the problem while still keeping them in the same loop?

The only way is to calculate the intersection points between the lines and the circles and then draw the circles and truncated lines in one loop. Unless you have millions of circles and lines to draw then using an offscreen buffer with createGraphics or calculating the intersection points will _ **swamp** _ any benefit to be had from using a single loop.

So in this instance the most efficient way is simply to draw all lines in one loop and the circles in a second (later) loop. 😄
