How to mirror an array with WS2801 LEDs? - arrays

I have the following code http://pastebin.com/25ugwNhK# which basically reads the equalizer color values for 7 differenece frequencies and maps them to a color. Then mirrors them projected on a string starting from both ends.
void EQcenterBarString(){
// reads eq and plugs RGB values directly into each consecutive pixel, mirrored from center.
if(LoopCnt <= PixelCount) {
readEQ();
//Add new color to array at pointer position
//For Array replace LoopCnt with row number
leds[LoopCnt].r = ledRed;
leds[LoopCnt].g = ledGreen;
leds[LoopCnt].b = ledBlue;
//now the opposite
//For Array replace Pixel - Loop with ROWS - row number
leds[PixelCount - LoopCnt].r = ledRed;
leds[PixelCount - LoopCnt].g = ledGreen;
leds[PixelCount - LoopCnt].b = ledBlue;
FastSPI_LED.show();
LoopCnt++;
}else{LoopCnt=0;}
}
I'd like to make this be able to work with an Array of [ROWS] [COLS], however I'm struck with getting the pixels to update or loop through the array.
My pseudo code looks something like this:
void EQcenterBarArray(){
int pixel = 0, rows = 0, cols = 0;
//rows = 0, loop through till the end going down the array, rows++
for(rows = 0; rows < ROWS; rows++) {
readEQ();
// should light up a whole row at once starting from the beginning of the array
while (cols != COLS) { //while in row # x fill all the col values until = COL value
pixel = ( LEDmatrix[rows][cols] ); // set pixel index to the array pos
leds[pixel].r = ledRed;
leds[pixel].g = ledGreen;
leds[pixel].b = ledBlue;
FastSPI_LED.show(); //update the pixel and move to next col value
cols++; //should fill whole col on row x ?
}
//now the opposite side
// should light up a whole row at once starting from the end of the array
while (cols != COLS) {
pixel = ( LEDmatrix[(ROWS-1) - rows][cols] ); //take the total# of ROWS and subtract the current row value to create a mirror effect?
leds[pixel].r = ledRed;
leds[pixel].g = ledGreen;
leds[pixel].b = ledBlue;
FastSPI_LED.show();
cols++;
}
}
}
However, when I run this through my arduino with WS2801 lights using the FastSPI_LED library I only get one row to light up and it doesn't cycle through all the rows?

You need to reset cols to 0 at the start of each iteration of your rows for() loop.
for(rows = 0; rows < ROWS; rows++) {
readEQ();
// should light up a whole row at once starting from the beginning of the array
cols = 0; //reset cols to zero to iterate next set of columns
while (cols != COLS) { //while in row # x fill all the col values until = COL value
Incidentally, it's not clear if you should call readEQ every row, or only after you have finished an entire display grid - each will have various advantages (rate of partial response, vs self-consistency of updates)

Related

Keep tablelayoputpanel rows height identical as rows are added dynamically

I have a TableLayoutPanel whose rows are set to autoresize. It has two columns, but rows can be added dynamically at run time.
How do I add a row, and then have the height of each roenter code herew be the same percentage? I tried this code after adding the control:
private void BindRawData(int rc) // row number is passed in
{
var percent = 100 - (tableLayoutPanel1.RowCount * 10);
tableLayoutPanel2.Controls.Add(grid1, 1, rc);
for(int i = 0; i < tableLayoutPanel2.RowStyles.Count - 1; i++)
{
var panel = tableLayoutPanel2.RowStyles[i];
panel.SizeType = SizeType.AutoSize;
}
}
The result is a grid on top that is really tiny, and the next grid takes up almost the whole panel.

C - How to check if at least one neighbor of a cell in a matrix respects a predication?

I'm on a project where I have to code a little game named "recolor", basically it's grid of a certain size, the grid is divided in cells (we have size*size cells), I can play a color (the color have to be in the grid or in the authorized colors) and each time I'm playing a color the grid will change from the top letf corner to color each cells directly connected to the top left corner that has the same color.
That's for the global context, now I already have all the functions to play this game but I have some problems with the function I use to play a move:
The game is defined using this type :
struct game_s
{
color **grid;
color **initial_grid;
uint width;
uint height;
uint nmb_cur_mv;
uint nmb_mv_max;
};
/*
* Def :
* - neighbour_of_origin checks if a cell is in the neighborhood of the (0,0) of the game grid, to be in the neighborhood
* the cell should have the same color as the (0,0) and the cell and (0,0) have to be connected by a path of cells that have the same
* color as (0,0).
* Param :
* - cgame g : the game grid
* - int x, y : coordinates of the cell we are currently checking
* - bool** to_change_tab : 2D array of boolean that represent the game grid and have the same size as it. It is used to mark all the cells to
* modify. By default the whole grid is set to false except (0,0) which is changed no matter what.
* Ret :
* - void function, nothing to return.
*/
void neighbour_of_origin(cgame g, int x, int y, bool **to_change_tab)
{
assert(g);
assert(g->grid);
assert(to_change_tab);
color origin = g->grid[0][0];
int offset[4][2] = {
{-1, 0}, /*W*/
{0, 1}, /*S*/
{1, 0}, /*E*/
{0, -1} /*N*/
};
int off_x;
int off_y;
for (int elem = 0; elem < 4; elem++)
{
off_x = x + offset[elem][0]; /*takes the 'x' coord in the offset matrix and add it to the current x*/
off_y = y + offset[elem][1]; /*takes the 'y' coord in the offset matrix and add it to the current y*/
if (((off_x >= 0 && off_x < SIZE) && (off_y >= 0 && off_y < SIZE)) && (to_change_tab[off_x][off_y] == true) && (g->grid[x][y] == origin))
{
to_change_tab[x][y] = true;
break;
}
}
}
/*
* Def :
* - game_play_one_move will change all the cells that are neighbors of the (0,0)that have the same color as it. The changing always begin
from the (0,0) and then it expands in all directions.
* Param :
* - game g : the game grid that will be modified.
* - color c : the color that will be applied to all the cells we have to change.
* Ret :
* - void function, nothing to return.
*/
void game_play_one_move(game g, color c)
{
assert(g);
assert(g->grid);
bool **to_change_tab = (bool **)malloc(sizeof(bool *) * SIZE);
assert(to_change_tab);
for (int i = 0; i < SIZE; i++)
{
to_change_tab[i] = (bool *)malloc(sizeof(bool) * SIZE);
assert(to_change_tab[i]);
for (int j = 0; j < SIZE; j++)
{
to_change_tab[i][j] = false;
}
}
/*getting all the cells we have to change*/
to_change_tab[0][0] = true; /*(0,0) is always modified */
printf("mark tab : \n");
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
neighbour_of_origin(g, x, y, to_change_tab);
printf("%d ", to_change_tab[x][y]); /*debbuging purpose*/
}
printf("\n");
}
/*modification of the game grid */
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
if (to_change_tab[x][y] == true)
{
g->grid[x][y] = c;
}
}
}
g->nmb_cur_mv += 1;
/*free the temporary array of bools*/
for (int x = 0; x < SIZE; x++)
{
free(to_change_tab[x]);
to_change_tab[x] = NULL;
}
free(to_change_tab);
to_change_tab = NULL;
}
above we have the two functions I've made to change the color as described in the rules, It actually works pretty well but I have a big issue on it.
This is my grid at the very begining :
each number corresponds to a color, the grid is 12*12 cells.
000202101030
033111132010
101232320332
231032111220
212333320100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
Here is my grid when I play the following colors : 3 1 3 0
000202101030
000000002010
000202020332
230002111220
212300020100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
if I play any color (except 0 of course) as my next move I expect every 0 connected to the top left to change but i got this instead:
333202101030
333333332010
333232320332
233332111220
212333320100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
the 0 on the first line didn't changed whereas they were connected to the origin, I suspected that the bug is in my condition in neighbour_of_origin(cgame g, int x, int y, bool **to_change_tab) because i'm using a for on x and y so the first line is evaluated first and the 0 on the first line did not have any neighbor that corresponds to the if condition at this state, is there a way to evaluate in "the order of propagation",I wanted to rewrite it recursively but I'm really bad in recursion.
Very sorry for the long post, I wish someone could help me, have a good day.
edit : I got a ''''fix'''' I duplicate my for loops in the game_play_one_move() function so it will loop again and again to find each cells he couldn't find before, I know it's not a real fix because in the future i don't know how the grid will be displayed exactly, but i guess that a loop that will check again and again until it can't find any neighbor could be a solution too, in terms of colplexity it would be a real problem since i'm looping in the grid again and again and again

How can I fix this error : 'Cannot invoke loadPixels() on the array type PImage[]'?

I'm kind of a beginner with Processing and I've been having difficulty with my pixel array. I have 10 images numbered from 0-9 that are being shown one after another... What I am trying to do on top of that is take each image and change its brightness level, turning it either white or black.
I've already tried to just change the brightness using one image, so not an array of images which works perfectly! But when joining those two together it doesn't work for me.
int maxImages = 10; // The number of frames in the animation
int imageIndex = 00; //initial image to be displayed first
PImage[] picture = new PImage[maxImages]; //the image array
void setup() {
size(500, 500); //size of sketch
frameRate(1); //frames processed per second
//loading images with numbered files into the array
for (int i = 0; i< picture.length; i++) {
picture[i] = loadImage("spast_" + i + ".jpg");
}
}
void draw() {
image(picture[imageIndex], 0, 0); //dispaying one image
loadPixels(); //accessing pixels
picture.loadPixels(); //accessing the image pixels too
//THIS is where it stops me and gives me 'Cannot invoke loadPixels() on the array type PImage[]'
for (int x = 0; x < width; x++) { //loops through every single x value
for (int y = 0; y < height; y++) { //loops through every single y value
int loc = x + y*width; // declare integer loc
float b = brightness(picture.pixels[loc]); //give me the brightness of pixels
if (b < 150) { //if the pixel is lower than 150
pixels[loc] = color(0); //then make those pixels black
} else { //otherwise
pixels[loc] = color(255); //make pixels white
}
}
}
imageIndex = (imageIndex + 1) % picture.length; //increment image index by one each cycle
updatePixels(); //when finished with the pixel array update the pixels
}
I'm expecting as each image is displayed it brightness value is changed and then it goes on to image 2 and so on...
Your picture variable is an array of PImage instances. You can't call loadPixels() on the array itself. You have to get a PImage at a specific index of the array, and then call the loadPixels() function on that instance.
Here's an example:
picture[0].loadPixels();
This line of code gets the PImage at index 0 and calls the loadPixels() function on it.
Note that you're already doing something pretty similar with this line:
image(picture[imageIndex], 0, 0);
Shameless self-promotion: here is a tutorial on arrays in Processing.
This is the updated and working code:
int maxImages = 10; // The number of frames in the animation
int imageIndex = 0; //initial image to be displayed first
PImage[] picture = new PImage[maxImages]; //the image array
void setup() {
size(500, 500); //size of sketch
frameRate(1); //frames processed per second
//loading images with numbered files into the array
for (int i = 0; i< picture.length; i++) {
picture[i] = loadImage("spast_" + i + ".jpg");
}
}
void draw() {
loadPixels(); //accessing pixels
image(picture[imageIndex], 0, 0); //dispaying one image
imageIndex = (imageIndex + 1) % picture.length; //increment image index by one each cycle
picture[imageIndex].loadPixels(); //accessing the image pixels in the array
for (int x = 0; x < width; x++) { //loops through every single x value
for (int y = 0; y < height; y++) { //loops through every single y value
int loc = x + y*width; // declare integer loc
float b = brightness(picture[imageIndex].pixels[loc]); //give me the brightness of pixels
if (b < 150) { //if the pixel is lower than 150
pixels[loc] = color(0); //then make those pixels black
} else { //otherwise
pixels[loc] = color(255); //make pixels white
}
}
}
updatePixels(); //when finished with the pixel array update the pixels
}

Google Apps Script .setvalues For loop not working

The goal of the loop is to fill each cell over 797 rows across 5 columns A, B, C, D and E with a formula whose cell reference increments by 1.
E.g. Column A rows 6 onwards will have formula "=indirect("'Data Repository'!A3++")"
Column B rows 6 onwards will have formula "=indirect("'Data Repository'!B3++")"
What happens when I run the function however is it only fills in column A. I've checked the execution transcript and execution succeeded is logged after the first column has been filled up. I've tried various variations to no avail.
Below is the last variation I've tested:
function indirect(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Fleet - Weekly V3");
var formulaArray = [];
var columns = ["A","B","C","D","E"];
var row = 2;
var text = '=indirect(\"\'Data Repository\'!';
var headerRow = 6;
var column;
for(i = 0; i < 5; i++) {
column = parseInt(i) + 1;
formula = text + columns[i];
for(i = 0; i < 797; i++) {
row += 1;
if (formulaArray.length == 797) {
sheet.getRange(headerRow, column).offset(0, 0, formulaArray.length).setValues(formulaArray);
} else {
formulaArray.push([formula + row + '")']);
}
Logger.log(formulaArray.length);
}
Logger.log(i)
formulaArray = [];
}
}
Here is where you might be making an error - you need to create the variable i (var i = 0 instead of just i = 0) and if you're nesting loops, you need to have different variables increasing (first loop use i, then nest with j, then nest in that with k etc as needed)
for(var i = 0; i < 5; i++) {
column = parseInt(i) + 1;
formula = text + columns[i];
for(var j = 0; j < 797; j++) {
Untested but I believe it should work if you just substitute that in.
Your problem is in your loops. You are using the 'i' variable twice. Change the for loop that you have nested to iterate over the variable 'j' or something other than 'i'.

C int array sort

If I have an int[3] array like such:
score_list[3] = [ 1, 2, 0]
Where each location in the array corresponds to a specific Document Number:
score_list[0] = D1
score_list[1] = D2
score_list[2] = D3
What would be the easiest way to sort the array in Descending order, keeping track of the place of each moved int
Where (after sort):
score_list[3] = [ 2, 1, 0]
And
score_list[0] = D2
score_list[1] = D1
score_list[2] = D3
I only need to print in descending order, not actually rearrange the int array, so:
for (int i=0; i<3; i++)
{
if (score_list[0] > score_list[1] && score_list[2])
printf("D%d-%d",i, score_list[0]);
if (score_list[1] > score_list[0] && score_list[2])
printf("D%d-%d", i, score_list[1]);
if (score_list[2] > score_list[0] && score_list[1])
printf("D%d-%d", i, score_list[2]);
}
Would print the highest number first, then I would compare the last 2, I just feel like this takes too long and there must be a more efficient way
You can solve this using marker (interface) design pattern.
By keeping a record of the visited index in your array each time you get the max, let me define the solution structure first then I will walk through it:
Make a new array of the same size of the score_list, let's call that array marker
In the for loop, you will make another loop to check for max score and in the same time check to see if the location of the max score in the marker array is 0.
Sample run:
On i=0
Loop on the score_list, and find the max score with marker == 0, print it and then put marker for that score = 1.
On i=1
You will do the same but now there is one location excluded from the list
Here you are a sample code how to do it:
Note that: this code is not a runnable one (and it is not optimized too O(n^2)), I wrote it for explanation purposes only.
int max = -1;
int doc = -1;
int marker[3] = {0, 0, 0};
for (i=0; i<3; i++)
{
max = -1;
for (j=0; j<3; j++)
{
// skip this location if it is already printed
if (marker[j] == 1)
continue;
if (score_list[j] > max)
{
doc = j;
max = score_list[j];
}
}
// this doc will not appear again in the inner for loop (j-loop)
marker[doc] = 1;
// print the document with the score
printf("D%d-%d",doc, max);
}

Resources