Why are my circles displaying as black? - arrays

I'm trying to make a program that creates up to 24 circles in a neat lattice that start off as white, and then as conditions (such as the hammer reaching the bottom of the screen and resetting) are met, changing those circles in order from left to right - going down one row each time the x-axis circles reach the defined edge of their row.
I created an array that holds the 24 colours in its indexes, all set to white ( - the same as the background for invisible circles) at the beginning, but changing one by one with the conditions. However, when I run my code below, I get an unchanging lattice of all black circles from the very beginning without considering the hammer, and the upper-left circle of every seventh row having a little white dot in it (only one visible in the 6-row test run).
I have no clue what caused this, and having scanned the code numerous times, I can't see where black is coming in from at all. The hammerPos if statement is incomplete at this point, as I'm still trying to figure out what's going on.
Here's my code:
int hammerPos = 0; int hammerVel = 1; int hammerPending = 0;
int jump = 60;
int pointIntervX = 20;
int pointIntervY = 20;
int pointX = pointIntervX;
int pointY = pointIntervY;
int pointSize = 10;
color white = color(255,255,255);
color black = color(0,0,0);
color red = color(255,0,0);
color[] pointColour = new color[24];
//standalone method (at top outside of draw and setup)
void pointMaker(color colour, int pointX, int pointY){
fill(colour);
ellipse(pointX,pointY,pointSize,pointSize);
}
void setup(){
size(200,200);
background(255);
for(int i:pointColour){//setup pointColour array at BEGINNING of setup
pointColour[i] = white;
}
}
void draw(){
// draw hammer;
fill(0);
stroke(0);
strokeWeight(6);
line(128,hammerPos+10,148,hammerPos-12);
strokeWeight(4);
line(125,hammerPos+13,129,hammerPos+11);
strokeWeight(8);
line(115,hammerPos+5,130,hammerPos+20);
hammerPending = hammerPending + hammerVel;
if (hammerPending > jump){
hammerPos = hammerPos + hammerPending;
hammerPending = 0;
}
for(int i = 0;i<24;i++){//refreshes 24 circles in white(invisible) constantly in draw until a color is changed
pointMaker(pointColour[i], pointX, pointY);
pointX += pointIntervX;
if(pointX>pointIntervX*4){
pointX = pointIntervX;
if(pointY<pointIntervY*6){
pointY += pointIntervY;
}
}
}
if(hammerPos>height){
hammerPos = 0;
}
}

The for loop in draw() is executed in the context where strokeWeight(8) is still in force. You are seeing nothing but stroke. A simple fix would be to put the line strokeWeight(1); at the beginning of the definition of pointMaker.
When you do that, you see another bug. for(int i:pointColour) doesn't do what you think it does. You are iterating over the default elements (not the indices) of the array pointColour -- all of which are 0. Thus what you are doing in that loop is 24 times in a row setting the first element of that array to white, leaving the other 23 equal to 0, which is equal to black. Hence after fixing the strokeWeight bug you are left with a grid of 1 white and 23 black circles. You should either initialize the array when you create it or in setup() loop over the indices rather than the elements by using for(int i = 0; i < pointColour.length; i++) {
On Edit: To clarify what I meant by index vs. element: pointColour was declared as color[24]. Thus for(int i: pointColour) doesn't really make sense. Using that type of iteration it should be for(color i: pointColour). The only reason that what you wrote isn't a syntax error is that Processing's color data type seems to be an alias for a 32-bit int. The indices in pointColour are always the 24 integers 0,1,...,23. The elements of pointColour are whatever 24 colors that you happen to store in that array. In pointColour[2] = color(0,0,255) the index is 2 but the element is the color blue

Related

Adding an amount to a certain array index in Java

I'm working on a project where I need to create 20 different circles with increasing brightness of red as the loop goes. I'm trying to find a way to increase the red value in an RGB style array here's my code:
for(int i = 0; i < circles.length; i++)
{
int[] gradient = new int[]{0, 0, 0};
circles[i].changeColor(gradient);
System.out.println(circles[i]);
gradient[0] += 15;
For some reason the shade of red is not increasing. I try adding 15 to the the 0 index of the gradient array (the 0 index is the red in the RGB) and it doesn't increase. I'm thinking it has something to do with how I'm adding the value to the array. Does anyone know what's going wrong and how can I fix it?
BTW, don't worry about the changeColor method, that's an existing and working method in a class on the program.
By declaring the gradient variable inside the 'for' loop you are setting it back to 0,0,0 each iteration. Make the declaration prior to the loop and you should be fine.
int[] gradient = new int[]{0, 0, 0};
for(int i = 0; i < circles.length; i++) {
circles[i].changeColor(gradient);
System.out.println(circles[i]);
gradient[0] += 15;
}

How do I randomly pick every color from my array only once without using classes

For my assignment I have to create the game 'memory'. I keep getting stuck on the part where I randomly give every card a color.
I first created this array
int rectColorArray[] ={BROWN, BROWN,WHITE, WHITE,RED, RED, GREEN, GREEN};
And made a loop in which I hoped it would only pick each color once.
void drawCards(int rectColor){
int length = 50;
int xPos =0;
int yPos =0;
for(int i = 7; i >= 0; i--){
rectColor = rectColorArray[(int)random(0,rectColorArray.length)];
fill(rectColor);
rect(xPos,yPos, length, length);
xPos = xPos + length + 10;
splice(rectColorArray,i,1);
}
}
it seems as if 'splice' doesn't do anything, because I keep getting rects that doesn't give the wanted output.
So my final question is: Does anyone know how to fix this problem, or if I should use another technique?
A very common solution to this sort of problem is to shuffle the source array, then simply use the shuffled items one at a time sequentially.
How can I shuffle an array?

Stuck implementing boundary checks on frame windows for mean filtering

I have a function that successfully reads rgb values from a ppm and a function that successfully writes to a ppm. What I am trying is a function called denoiseImage that changes rgb values from a ppm using mean filtering with a frame window size n by n where n is odd. My intent is to go through each pixel, using it as the center point for the window n by n that surrounds it. I then take the mean values for each color (r,g,b) and divide by the number of pixels in the window and assign those new values to the rgb of every pixel in the window. However, I am unable to implement a check for the cases where the frame does not fully fit into pixels (for example, the frame center point is the top right pixel, a window of 3x3 will go to non existent points.) When it does not fit fully, I intend to use the available pixels that fit and take the mean of those numbers instead. So far, my code will only work for cases where the frame fully fits. My function:
RGB *denoiseImage(int width, int height, const RGB *image, int n)
{
int firstPos, lastPos, i = 0, j = 0, k, numofPix;
int sumR=0,sumG=0,sumB=0;
numofPix = (width * height);
RGB *pixels = malloc(numofPix * sizeof(RGB));
if (n == 1) //Case where the window size is 1 and therefore the image does not get changed.
{
return pixels;
}
for (j=0;j < numofPix;j++)
{
firstPos = (j - width) - ((n - 1)/2);
lastPos = (j + width) + ((n - 1)/2);
//Need to check boundary cases to prevent segmentation fault
for (k=firstPos;k<=lastPos;k++) //Seg fault. Unable to shrink frame to compensate for cases where the frame does not fit.
{
sumR+=image[k].r;
sumG+=image[k].g;
sumB+=image[k].b;
i++;
if (i = n) //Used to skip elements not in frame
{
j += (width-n);
i = 0;
}
}
sumR = sumR/(n*n); //Calculating mean values
sumG = sumG/(n*n);
sumB = sumB/(n*n);
for (k=firstPos;k<=lastPos;k++) //Assigning the RGB values with the new mean values.
{
pixels[k].r=sumR;
pixels[k].g=sumG;
pixels[k].b=sumB;
printf("%d %d %d ",pixels[k].r, pixels[k].g, pixels[k].b);
}
}
return pixels;
}
int main()
{
RGB *RGBValues;
int width, height, max;
int j = 0,testemp=3; //test temp is a sample frame size
char *testfile = "test.ppm";
char *testfile2 = "makeme.ppm";
RGBValues = readPPM(testfile, &width, &height, &max); //Function reads values from a ppm file correctly
RGBValues = denoiseImage(width,height, RGBValues, testemp,testing);
writePPM(testfile2,width,height,max,RGBValues); //Function writes values to a ppm file correctly
}
How would I implement a way to check if the frame fits or not?
This is a great question and luckily known in the image processing community.
Edges are always treated differently when it comes to 2D filtering.
One way to look at it is to extend the space in 2D and to fill the edges with extrapolated values from the middle.
For example, you may look into the http://www.librow.com/articles/article-1 and search for a media filter.
I am sure that you will find solution soon, since you are going into right direction.

Accessing portions of a dynamic array in C?

I know, another dynamic array question, this one is a bit different though so maybe it'll be worth answering. I am making a terrain generator in C with SDL, I am drawing 9 chunks surrounding the screen, proportional to the screen size, that way terrains can be generated easier in the future.
This means that I have to be able to resize the array at any given point, so I made a dynamic array (at least according to an answer I found on stack it is) and everything SEEMS to work fine, nothing is crashing, it even draws a single tile....but just one. I am looking at it and yeah, sure enough it's iterating through the array but only writing to one portion of memory. I am using a struct called Tile that just holds the x, y, w, and h of a rectangle.
This is the code I am using to allocate the array
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*));
int arrayLen = sizeof(TileMap);
TileMap = (Tile*)realloc(TileMap, (totalTiles) * sizeof(Tile));
arrayLen = sizeof(totalTiles * sizeof(Tile));
The totalTiles are just the number of tiles that I have calculated previously are on the screen, I've checked the math and it's correct, and it even allocates the proper amount of memory. Here is the code I use to initialize the array:
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
So what's weird to me is it is considering the size of a tile (16 bytes) * the totalTiles (78,000) is equaling 4....When I drill down into the array, it only has one single rect in it that gets cleared as well, so then when I go calculate the sizes of each tile:
//Figure out Y and heights
for (int i = startY; i <= (startY*(-1)) * 2; i += TILE_HEIGHT)
{
TileMap[i].y = i * TILE_HEIGHT;
TileMap[i].h = TILE_HEIGHT;
//Figure out X and widths
for (int j = startX; j <= (startX*(-1)) * 2; j += TILE_WIDTH)
{
TileMap[i].x = i * TILE_WIDTH;
TileMap[i].w = TILE_WIDTH;
}
}
*Side note, the startX is the negative offset I am using to draw chunks behind the camera, so I times it by -1 to make it positive and then time it by two to get one chunk in front of the camera
Alright, so obviously that only initializes one, and here is the render code
for (int i = 0; i < totalTiles; i++)
{
SDL_Rect currentTile;
currentTile.x = TileMap[i].x;
currentTile.y = TileMap[i].y;
currentTile.w = TileMap[i].w;
currentTile.h = TileMap[i].h;
SDL_RenderDrawRect(renderer, &currentTile);
}
free(TileMap);
So what am I doing wrong here? I mean I literally am just baffled right now...And before Vectors get recommended in place of dynamic arrays, I don't really like using them and I want to learn to deal with stuff like this, not just implement some simple fix.
Lots of confusion (which is commonplace with C pointers).
The following code doesn't provide expected answer :arrayLen = sizeof(totalTiles * sizeof(Tile));
totalTiles * sizeof(Tile) is not even a type, I'm surprised it compiles at all. Edit : See molbnilo comment below. so it provides the size of the return type.
Anyway, proper answer should be :
arrayLen = totalTiles;
Because that's what you need in your next loop :
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
You don't need the size of the table, you need its number of elements.
There are other confusions in your sample, they don't directly impact the rest of the code, but better correct them :
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*)); : avoid allocating a size of 0.
int arrayLen = sizeof(TileMap); : no, it's not the arrayLen, just the size of the pointer (hence 4 bytes on 32-bits binaries). Remember TileMap is not defined as a table, but as a pointer allocated with malloc() and then realloc().

Diagonal line in PNM P6 not drawing correctly

I am currently writing a program for an assignment that requires a single black line to be drawn perfectly solid diagonal (so that all x=y) from the upper-left corner of a standard PNM P6 file. I have had no issues with file I/O.
However, I cannot get the diagonal line to display properly. Instead of the single, solid, white line I need from the corner, I get dotted lines wrapping over the image as shown in this picture.
Does anyone have any idea as to what is going wrong?
My function is as follows:
Image *
DiagonalWhite(Image *img)
{
int i, j;
for (i = 0; i < img->x; i++)
{
for (j=0; j < img->y; j++)
{
if (i==j)
{
img->data[i*img->y+j].red=255;
img->data[i*img->y+j].green=255;
img->data[i*img->y+j].blue=255;
}
}
}
return img;
}
You don't give any definition for Image *img, so actually this question cannot be answered with confidence; however, I assume you are doing the same class as yesterday's Issues writing PNM P6.
You are multiplying in the wrong direction. img->y holds the height of the image. However, since you need the span, you should be using img->x -- the width -- to go down by i pixels (followed by adding j pixels to go right).
img->data[i*img->x+j].red=255; /* x, not y */
Note: Better names for these properties would have been width and height.
Note: It's easier and quicker to loop only once over the minimum of width and height, and set pixel[i,j] immediately, rather than testing which one 'has' the same x and y position.

Resources