# Task #6: Enter the Matrix

**URL:** <https://forum.electromage.com/t/task-6-enter-the-matrix/1062>\
**Category:** Pixelblaze Academy of Wizardry and Enchantment\
**Created:** [March 6, 2021, 3:33am UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062 "2021-03-06T03:33:22Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [March 6, 2021, 3:33am UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/1 "2021-03-06T03:33:22Z")

</div>

Welcome to Task #6.  
This will require a matrix panel, or equivalent, of at least 8x8 (larger is fine)

We’re going to start easy:

Render2D requires a map, that puts all pixels into x and y coordinates.

So you can effectively consider all pixels will be between 0 and 1, on both X and Y axes.

Let’s start with picking a random point, picking a random color, and then setting that point to that color.

Repeat.

We’ll build on this next week. As I said, this is a simple start.

---

<div class="post-metadata">

**Author:** ![zranger1](https://forum.electromage.com/user_avatar/forum.electromage.com/zranger1/32/301_2.png) [@zranger1](https://forum.electromage.com/u/zranger1)\
**Post date:** [March 14, 2021, 9:23pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/2 "2021-03-14T21:23:09Z")

</div>

This week’s madness, as requested, picks a random set of x,y coordinates and draws a dot at that location. The  
twist is that you can control the size of the dot with a slider. When I started writing this, I noticed that my larger dots were rarely symmetrical. A little thinking revealed that this was because the random numbers I was generating were rarely or never landing on pixel centers.

Solving this problem requires knowing the dimensions of the matrix. At this writing, there’s no straightforward way for a pattern to get that information, which is why you occasionally see matrix dimensions hard coded even in patterns that support render2D(). Here’s a way, only slightly hack-o-riffic, to get matrix dimensions on the fly:

```auto
// variables to help find matrix boundaries;
var sizeFound = 0;        
var xMax,yMax; 
var renderer = renderMapDimensions;

// variables used to generate random dot
var frameTimer = 9999;
var x1,y1,hue;

// variables used by UI
export var holdTime = 250;
export var dotSize = 1;

// UI Sliders
export function sliderDotSize(v) {
  dotSize = 0.5+10 * (v * v);
}

export function sliderHoldTime(v) {
  holdTime = 50 + (1500 * v);
}

// This is a sneaky way of determining the map dimensions for
// rectangular matrices while rendering (while not rendering, actually)
// the first frame. Will not work well on irregular 2D shapes.
// Far as I know, there's no direct way to get map data from a
// pattern right now.
// We do this because unless we know where the pixel centers are,
// it's difficult to generate random numbers that land on pixel centers.
function renderMapDimensions(index,x,y) {
  if (!sizeFound && x >= 0.999) {
    xMax = index;
    yMax = -1+ (pixelCount / (xMax+1));
    sizeFound = 1;
  }
}

// Render our random dot. Yay Pythagoras!!!  
function renderRandomDot(index,x,y) {
  x = ((x * xMax) - x1) ; y = ((y * yMax) - y1);
  bri = sqrt((x * x) + (y * y)) < dotSize;
  hsv(hue, 1, bri)  
}

// uses a straightforward timing mechanism based on 
// accumulating delta to periodically generate new
// random coordinates and color. 
export function beforeRender(delta) {
  frameTimer += delta
  if (sizeFound) renderer = renderRandomDot;
  
  if (frameTimer > holdTime) {
    frameTimer = 0;
    x1 = floor(random(xMax+1));
    y1 = floor(random(yMax+1));
    hue = random(1);
  }
}

export function render2D(index,x,y) {
  renderer(index,x,y);
}

```

---

<div class="post-metadata">

**Author:** ![JustPete](https://forum.electromage.com/user_avatar/forum.electromage.com/justpete/32/1832_2.png) [@JustPete](https://forum.electromage.com/u/JustPete)\
**Post date:** [March 19, 2021, 2:20pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/3 "2021-03-19T14:20:20Z")

</div>

Great code! I marked-up most of this for self/noobs. Here are a few select notes and related comments/questions -

1. Sliders - e.g.

> [@zranger1](#):
>
> ```auto
> export function sliderDotSize(v) {
> dotSize = 0.5+10 * (v * v);
> }
> 
> ```

Left number is lower bound, right plus left is upper bound, use v-squared, v-cubed and etc. for increased “sensitivity”.

1. 

> [@zranger1](#):
>
> ```auto
> function renderMapDimensions(index,x,y) {
> if (!sizeFound && x >= 0.999) {
> xMax = index;
> yMax = -1+ (pixelCount / (xMax+1));
> sizeFound = 1;
> }
> }
> 
> ```

This bit is indeed fun and sneaky (once figured out) seems it would work in 3D also. “!” is a logical “not”, returns reverse logical value. So, if sizefound is \> 0.999 AND x is \>= 0.999 then you have found the range in X = width = index. And so on.

Not so sure about this , tho -

> [@zranger1](#):
>
> `yMax = -1+ (pixelCount / (xMax+1));`

Seems the front-end “-1” is redundant?  
sizefound = 1 kicks it out of any more iterating on xMax.

Nice to know one can just make up render functions and work them like -

> [@zranger1](#):
>
> `function renderMapDimensions(index,x,y)`

OK. That’s it for this AM. On to figuring the spots… !

---

<div class="post-metadata">

**Author:** ![zranger1](https://forum.electromage.com/user_avatar/forum.electromage.com/zranger1/32/301_2.png) [@zranger1](https://forum.electromage.com/u/zranger1)\
**Post date:** [March 19, 2021, 6:28pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/4 "2021-03-19T18:28:49Z")

</div>

Here’s what’s going on with that line:  
`(pixelCount / xMax+1)` calculates the _number_ of rows. In the case of a 16x16 matrix, this would be… 16. What I actually want for later ease of use though, is the _index_ of the last row, which is 15. Therefore, the `-1+(pixelCount/xMax+1)`.

---

<div class="post-metadata">

**Author:** ![JustPete](https://forum.electromage.com/user_avatar/forum.electromage.com/justpete/32/1832_2.png) [@JustPete](https://forum.electromage.com/u/JustPete)\
**Post date:** [April 2, 2021, 10:35pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/5 "2021-04-02T22:35:03Z")

</div>

> [@zranger1](#):
>
> What I actually want for later ease of use though, is the _index_ of the last row

Ok, I got it with wanting the index not the width. Lost track of which was in focus in the instance.

But, anyway, I’ve fiddled with this Task today for long enough. I tried it a good while back and gave up. Nothing I do seems to work. And I still do not get mapping or how the mapper tab integrates with the code I write…

Here’s my recent go at it. All it does is flash the whole matrix . I tried “scaling” calls of x and y to 0 to 1 to no avail. Something trivial no doubt, but, help please?

export var DwellTime  
var timer  
var width = 16  
var height = pixelCount / width  
var x1, y1

export function sliderDwellTime(v) {  
DwellTime = 50 + (2500 \* v)}

export function beforeRender(delta) {  
timer += delta

if (timer \>= DwellTime) {  
timer = 0  
x1 = floor(random(width))  
y1 = floor(random(height))  
hue = clamp(random(1),0.1,0.9)

}  
}

export function render2D(index,x,y) {  
if (x = x1)  
if (y = y1) {

```
hsv(hue,1,1) 

```

}

else {

```
hsv(0,0,0) }

```

}

Thanks!

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [April 3, 2021, 12:05am UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/6 "2021-04-03T00:05:34Z")

</div>

I’ll take a look tomorrow when I spend some time on the next Task (which I’m still mulling)

---

<div class="post-metadata">

**Author:** ![zranger1](https://forum.electromage.com/user_avatar/forum.electromage.com/zranger1/32/301_2.png) [@zranger1](https://forum.electromage.com/u/zranger1)\
**Post date:** [April 3, 2021, 10:48pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/7 "2021-04-03T22:48:13Z")

</div>

@JustPete, you’ve found one of the classics: In the two `if` statements in your render function, you’re using the assignment operator `=`, when I think you mean to use the comparison operator ```==````.

```auto
export function render2D(index,x,y) {
if (x = x1) // should be 'if (x == x1) 
if (y = y1) { // 'if (y == y1)

```

I admit to having done this more than once myself. It’s a problem in most popular computer languages – easy to do, and hard to find. “Bigger” development tools _might_ warn you about it, and some modern languages make the operators easier to tell apart, but it’s really just one of those things you have to watch out for.

In beforeRender, you’re setting x1,y1 to be integers from 0 to width and 0 to height. In render() though, x and y come in normalized to the range 0 to 1 according to your mapping function. To get back to integer coordinates that can be easily compared, you need to multiply them by width and height:

```auto
if (floor(x * width) == x1)
if (floor(y * height) == y1) {

```

also, the arrangement of if statements – `if (condition1) if (condition2) { do things; }` – looks like it ought to work but it doesn’t. I have no idea if it’s supposed to.

Anyway, there’s a surprising amount of wiggle room in language specification. Best practice is to be very explicit about what you want done, and put in all the braces. (Or make this a compound conditional using the logical AND operator `&&`. Like this: `if ((condition1) && (condition2)) { do things;}` )

Here’s your render function with these modifications made. Your design was correct – it works perfectly.

```auto
export function render2D(index,x,y) {
  if (floor(x * width) == x1) {
    if (floor(y * height) == y1) {
      hsv(hue,1,1) 
    }
  }
  else {
    hsv(0,0,0)
  }
}

```

---

<div class="post-metadata">

**Author:** ![JustPete](https://forum.electromage.com/user_avatar/forum.electromage.com/justpete/32/1832_2.png) [@JustPete](https://forum.electromage.com/u/JustPete)\
**Post date:** [April 5, 2021, 4:41pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/8 "2021-04-05T16:41:23Z")

</div>

> [@zranger1](#):
>
> you’ve found one of the classics: In the two `if` statements in your render function, you’re using the assignment operator `=`, when I think you mean to use the comparison operator ```==````.

Indeed, this could be viewed as some kind of code epistemology, 'the nature of “equals”, but I see what you mean. Code may be flexibly configured but intolerant of interpretation, clearly demonstrated in this instance. Thanks.

> [@zranger1](#):
>
> ```auto
> if (floor(x * width) == x1) {
> if (floor(y * height) == y1) {
> hsv(hue,1,1) 
> 
> ```

Normalizing this was, I thought something I has tried, but I get lost in what I have and have not tried when it does not work for a while… It is useful to me to understand the code in before render can be whatever, in render it has to be normalized to the 0 to 1 range.

Interesting note (as yet unexplored), my 16 x 16 matrix displays two adjacent pixels in y when displaying the last column, but not always.

Thanks much for filling me in @zranger1

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [April 5, 2021, 6:18pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/9 "2021-04-05T18:18:06Z")

</div>

> [@JustPete](#):
>
> in render it has to be normalized to the 0 to 1 range.

No, that’s incorrect.

PB as part of mapping anything, changes the map into a range from 0..1  
So if you give 1, 2, 3, 4, 5(for example), when you actually get the map, it’s 0, .25, .5, .75, and 1

This is different from Index, value which is always 0 thru the number of pixels (minus 1)

The mapping change is meant to be helpful, so that no matter what values you put in, you always get a consistent range back out, so any pattern can just “work”, rather than insist on having some specific value. For multiple examples of the opposite of this, look at any of matrix-y patterns that require setting the width and height, and break if you don’t. Done with a map, it doesn’t matter if you have 8x8, 16x16 or 32x64, the map is still 0,0 in one corner and 1,1 in the opposite corner.

Render has nothing to do with this. Remember it just gives you Index (actual pixel number) and if 2D also gives you X (0..1), and Y (also 0..1).

What you do with that is up to you.

---

<div class="post-metadata">

**Author:** ![JustPete](https://forum.electromage.com/user_avatar/forum.electromage.com/justpete/32/1832_2.png) [@JustPete](https://forum.electromage.com/u/JustPete)\
**Post date:** [April 5, 2021, 10:08pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/10 "2021-04-05T22:08:57Z")

</div>

Yup. That would be a misstatement on my part. This index plus coordinates thing is just alright with me.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [November 3, 2021, 3:32pm UTC](https://forum.electromage.com/t/task-6-enter-the-matrix/1062/11 "2021-11-03T15:32:27Z")

</div>

5 posts were split to a new topic: [How does Pixelblaze coordinates mapping work?](https://forum.electromage.com/t/how-does-pixelblaze-coordinates-mapping-work/1698)
