# Switch space quarters iteratively

## Motivations of a glsl experiment

I asked myself how to randomly sort the tessellation of a glsl shader. Thinking about that problem, I ran into a slightly different problem: the challenge was to subdivide the canvas in quarters and then switch the top-left quarter with the bottom-right, and the top-right quarter with the bottom-left. Observable notebook at https://observablehq.com/@riccardoscalco/switch-space-quarters-iteratively.

The solution was pretty easy: mapping each point `q`

to
`mod((q - (.5, .5), 1)`

.
The `mod`

function computes the value of one parameter
*modulo* another,
see the reference pages.

We can go further and repeat the same procedure for each quarter. For example, take the (new) top-left quarter, subdivide it in quarters (each is 1/16 of the whole area) and switch the top-left with the bottom-right and the top-right with the bottom-left. Do that for each of the four 1/4-quarters.

Then repeat the procedure for each of the 1/16-quarters, then for each of the 1/32-quarters and so on... Of course, the iteration can be infinite but, at a certain point, we start to move around pixels.

## Let's look at the code implementation

The most interesting part of the fragment shader is the function
`g(q, v) = mod(q - v * (.5, .5), v) + floor(q / v) * v`

.
That function is called at each iteration and applied to the result
of the previous iteration.

The resulting function applied to the point coordinate
`q`

after each iteration is:
Note that the output `vec2`

value of each iteration is
the input coordinate of the next iteration.

- 1 iteration:
`g(q, 1/1)`

- 2 iterations:
`g(g(q, 1/1), 1/2)`

- 3 iterations:
`g(g(g(q, 1/1), 1/2), 1/4)`

- ...

The block of GLSL code below defines the function `g`

and
the function `field`

resulting after 3 iterations.

```
vec2 g (vec2 st, float v) {
return mod(
(st - v * vec2(0.5, 0.5)),
v
) + floor(st / v) * v;
}
vec2 field (vec2 st) {
vec2 f = st;
for (float i = 0.; i < 3.; i += 1.) {
f = g(f, 1. / pow(2., i));
}
return f;
}
```

Eventually, we can use the function `field`

to assign the
value at the `gl_FragColor`

variable.

```
void main() {
vec3 color = vec3(field(st), 1.);
gl_FragColor = vec4(color, 1.0);
}
```