I have made a program in C.
What it does or should do is draw a filled circle by displaying values of a matrix.
You can input the values of the radius of the circle, the position of the center of the circle relative to the center of the matrix and the size of the matrix i.e. resolution.
So when it gives values of the cells of the matrix, it checks if the cell (or point) is inside the circle.
For each cell there is a point determined by the variables x and y. When the point is inside the circle, that means that the number that we get by calculating the equation of a circle with the x and y values is less than the radius of the circle squared.
If the point is inside the circle, the program makes the value of the corresponding cell 1. Otherwise it makes it 0.
So in the end it should display the matrix and it should look like a bunch of zeroes and inside there is a filled circle made of ones.
The problem:
The program works, I can type in the values it needs (for example radius is 50, x position is 0, y position is 0 and resolution (matrix size) is 150), but when it is supposed to display the matrix it only prints zeroes.
Is there anything fundamentally wrong with my program? What could cause the problem?
Thanks in advance!
My code:
#include <stdio.h>
int main()
{
float x = 0, y = 0, ypos= 0 , xpos = 0, radius = 0, rsqrd = 0, rcheck = 0;
int matsize = 0, i, j;
printf("Value of radius:");
scanf("%f" , &radius);
printf("Position of circle on the x axis:");
scanf("%f" , &xpos);
printf("Position of circle on the y axis:");
scanf("%f" , &ypos);
printf("Resolution:");
scanf("%d" , &matsize);
printf("\n");
rsqrd = radius*radius; //rsqrd is equal to radius squared.
x = -1*(matsize/2); //with this I make sure that the x and y values start from the top right corner of the matrix, so that each x, y value corresponds to the correct cell position (i, j)
y = matsize/2;
int mat[matsize][matsize];
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(rcheck <= rsqrd)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
y = y-1;
}
for(i = 0; i < matsize; i++) // displaying the matrix
{
for(j = 0; j < matsize; j++)
{
printf("%d ",mat[i][j]);
}
printf("\n");
}
return 0;
}
You forgot to reset x when decrementing y.
Try this:
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(rcheck <= rsqrd)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
y = y-1;
x -= matsize; // <-- Reset x to start of row
}
Related
could any one explain me the difference between one dimensional for loop and two dimensional for loop. and how could i change following one dimensional for loop to two dimensional for loop on the second snippet code. thank you
i think following is one dimensional for loop
Capture video;
for(int i = 0; i < video.pixels.length; i++){
// encoded so blue is > 0 if a pixel is within threshold
if(blue(video.pixels[i]) > 0){
count++;
// processing takes 0-1 (float) color values from shader to 0-255 (int) values for color
// to decode, we need to divide the color by 255 to get the original value
avg.add(red(video.pixels[i]) / 255.0, green(video.pixels[i]) / 255.0);
}
}
and following snippet code is 2 dimensional for loop
Capture video;
for (int x = 0; x < video.width && x < 100; x++ ) {
for (int y = 240; y < video.height; y++ ) {
int loc = x + y*video.width;
}
}
A for loop has 3 parts initialization; condition; increment/decrement
Typically used as
for (int x = 0; x < video.width && x < 100; x++ )
Where int x = 0 initializes the variable x.
x < video.width && x < 100 checks whether the loop should continue.
And x++ increases x every time it finishes one iteration of the loop.
A 2D for is just 2 for loops nested. In the example
for (int x = 0; x < video.width && x < 100; x++ ) {
for (int y = 240; y < video.height; y++ ) {
int loc = x + y*video.width;
}
}
For every increase of x, the for loop will loop through every value 240 ≤ y < video.height.
The 2D for loop is assigning a 1D position to each pixel in the video. You can use this position to read each pixel in video.pixels.
for (int x = 0; x < video.width && x < 100; x++ ) {
for (int y = 240; y < video.height; y++ ) {
int loc = x + y*video.width;
if(blue(video.pixels[loc]) > 0){
count++;
avg.add(red(video.pixels[i]) / 255.0, green(video.pixels[i]) / 255.0);
}
}
}
Both the code above and your original code achieve the same thing but this way is using a 2D for loop
[Edit 1]
To have the same limits on a 1D for loop is a bit more complicated
(untested)
for(int i = 0; i < video.pixels.length; i++){
const pX = i % video.width;
const pY = (i - pX) / video.width;
if(pX > minX && pX < maxX && pY > minY && pY < maxY){
... //It is within minX and maxX and within minY and maxY
}
}
Enter N (dimension of square matrix) such that N is odd and in interval [1,100]. For entered matrix, check if it is a target matrix: if yes, print YES; if no, print NO.
Target Matrix is a matrix that is organized in concentric circles starting from the centre. Each concentric circle has -1 the value of the previous one. Examples:
and
I've tried approaching this problem by using a while loop to increase the radius which starts at centre increases. inside, I've used two for loops to go through that part and check if the values are according the the rule given above.
I'm not really sure if this is a good approach. Do you have some suggestions?
#include <stdio.h>
#define DIM 100
int main() {
int matrix[DIM][DIM];
int N;
int targetMatrix = 1;
int matrixCenter;
int radius;
do{
printf("Enter N: ");
scanf("%d", &N);
if (N % 2 == 0 || N < 1 || N > 100){
printf("Invalid value of N.\n");
}
} while (N % 2 == 0 || N < 1 || N > 100);
// Matrix Entry
printf("Enter the matrix: ");
int i, j;
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
scanf("%d", &matrix[i][j]);
}
}
// Value at Center
matrixCenter = matrix[N/2][N/2];
radius = 1;
// (N - 1) / 2 is the distance from center of matrix to its side
while (radius <= (N - 1) / 2)
{
for(i = N/2 - radius; i <= N/2 + radius; i++){
for(j = N/2 - radius; j <= N/2 + radius; j++){
if (i == N/2 && j == N/2) // Center Value
continue;
if (matrix[i][j] != matrixCenter - radius)
targetMatrix = 0;
}
}
if (targetMatrix == 0){
printf("NO: This is not a target matrix"); // If not a target matrix
return 1;
}
radius++;
}
printf("YES: this is a target matrix"); // If it is a target matrix
return 0;
}
Testing shell of submatrix only :
int first = N/2 - radius;
int last = N/2 + radius;
for (int i = first; i <= last;i++) {
// first on last line: increment by one
// other : increment by radius * 2
for (int j = first; j <= last;j += ((i==first)||(i==last) ? 1 :radius*2)) {
// test i,j here
}
}
This question already has an answer here:
Minesweeper revealing cells in C
(1 answer)
Closed 1 year ago.
I want to make a minefield. First I made a matrix, asked the user to enter with the rows and columns.
I need to:
put the bombs
indicate the amount of bombs nearby.
#include <stdio.h>
#include <stdlib.h>
int main(){
int rows, columns, i, j, bombs, **matrix;
printf("\Enter the rows: ");
scanf("%d", &rows);
printf("Enter the columns:");
scanf("%d", &columns);
printf("Enter the bombs:");
scanf("%d", &bombs);
if (bombs>= (rows*colums)){
printf("Error");
}
if (bombs<= 0){
printf("Error);
}
for (i = 0; i < rows; i++){
for (j = 0; j < columns; j++){
matrix[i][j] = rand() % 10;
}
}
// show the map //
for (i = 0; i < rows; i++){
for (j = 0; j < columns; j++) {
printf("%d", matrix[i][j]);
}
printf("\n\n");
}
return 0;
}
``
Data Structures
Instead of using an int then remembering magical numbers like -1 indicates a mine, it's more natural to say what these mean explicitly. Then you can change your mind or add to it without worrying about rewriting your whole programme. In the whole minefield, it's useless to have int **m without cols and rows. This interdependence is a sign that you should also package them in a structure to pass as one variable.
struct tile { unsigned nearby : 4, is_mine : 1, is_revealed : 1; };
struct map { size_t x, y; struct tile **tile; };
These definitions are very similar to what you had before, but they express the intent of the code much better.
Arrays
I would forget your complicated alocMatrix and just use one allocation, but then you have to use tiles[y * map->x + x]. Personal preference; I think it's easier to have a constructor that returns one allocated block.
struct map { size_t x, y; struct tile *tile; };
...
if(!(map = malloc(sizeof *map + sizeof *tile * x * y)))
{ if(!errno) errno = ERANGE; return 0; }
...
map->tile = (struct tile *)(map + 1);
memset(map->tile, 0, sizeof *tile * x * y);
Mines
A method of laying mines uniformly at random is to repeatedly choose a random tile, throwing out the tiles you've seen. Another method is to visit all the tiles and calculate the probability of each, P(mines left / tiles left). It depends on the number of mines which will be faster.
const size_t x1 = map->x, y1 = map->y;
size_t x, y, squares = x1 * y1;
assert(map && mines < squares);
for(x = 0; x < x1; x++) {
for(y = 0; y < y1; y++) {
struct tile *tile = &map->tile[y * x1 + x];
tile->is_revealed = 0;
tile->is_mine = rand() < RAND_MAX / squares * mines;
mines -= tile->is_mine;
squares--;
}
}
for(x = 0; x < x1; x++) for(y = 0; y < y1; y++)
map->tile[y * x1 + x].nearby =
(x && y && map->tile[(y-1) * x1 + (x-1)].is_mine) +
...
(x && y < y1 - 1 && map->tile[(y+1) * x1 + (x-1)].is_mine);
How about using this function to place the bombs? Call it by passing the address of m. Keep in mind that marking the rest of the squares with the appropriate number has to happen after the bombs have been placed (and it shouldn't depend on a call to rand). Also, the map has to be initialized to avoid surprises.
void placeBombs(int*** map, int numOfRows, int numOfColumns, int numOfBombs)
{
while (numOfBombs > 0) {
int column = rand() % numOfColumns;
int row = rand() % numOfRows;
if ((*map)[row][column] != -1) {
(*map)[row][column] = -1;
--numOfBombs;
}
/* Else, if a bomb already exists in the cell,
* we iterate without placing a bomb
*/
}
}
So I have made this program where you can give in the parameters of a circle or a line and it will display said object by drawing an array on the display.
It works by "projecting" a coordinate-system onto an array. (The program also asks you to give the resolution of the array, the number of columns and rows are the same.) Then for every cell of the array it checks if the circle/line intersects the cell. If it does, or it is within a given range, the cell will get a value of 1. If it is out of range, it will be 0. When all the cells have been given a value, the program displays the array. So in the end you will see a circle or line made of ones, the rest of the arrays will show up in zeroes.
The problem is that it takes a relatively long time (7 to 10s) to print the array, while the actual calculations take like no time.
My question is as said in the title, can the process of displaying the array be sped up somehow? Or am I doing something wrong? I am using Code::Blocks as my compiler.
I know that my code is probably very poorly optimized, but I've only started programming like a week ago. So please forgive me if the code is hard to understand.
Thank you in advance!
#include <stdio.h>
#include <stdlib.h>
int main()
{
float x = 0, y = 0, ypos= 0 , xpos = 0, radius = 0, rsqrd = 0, rcheck = 0, thick = 0, grad = 0, offs = 0, lcheck = 0;
int matsize = 0, i, j, branch = 0;
char filled;
printf("\n0 - circle\n1 - line\nDo you want to draw a circle or a line? (0/1) ");
scanf("%d", &branch);
if(branch == 0)
{
printf("Value of radius: ");
scanf("%f", &radius);
printf("Position of circle on the x axis: ");
scanf("%f", &xpos);
printf("Position of circle on the y axis: ");
scanf("%f", &ypos);
printf("Is the circle filled? (y/n) ");
scanf(" %c", &filled);
if(filled == 'n')
{
printf("The thickness of circle: ");
scanf("%f", &thick);
}
if(filled == 'y' || filled == 'n')
{
printf("Resolution: ");
scanf("%d" , &matsize);
printf("\n");
}
rsqrd = radius*radius; //rsqrd is equal to radius squared.
x = -1*(matsize/2); //with this I make sure that the x and y values start from the top right corner of the matrix, so that each x, y value corresponds to the correct cell position (i, j)
y = matsize/2;
int mat[matsize][matsize];
if(filled == 'n')
{
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(abs(rcheck-rsqrd) <= (thick*thick))
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
}
if(filled =='y')
{
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(rcheck <= rsqrd)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
}
if(filled == 'y' || filled == 'n')
{
for(i = 0; i < matsize; i++) // displaying the matrix
{ //
for(j = 0; j < matsize; j++) //
{ //
printf("%d ",mat[i][j]); //
} //
printf("\n"); //
} //
}
}
if(branch == 1)
{
printf("Value of gradient: ");
scanf("%f", &grad);
printf("Value of offset: ");
scanf("%f", &offs);
printf("Thickness of line: ");
scanf("%f", &thick);
printf("Resoultion: ");
scanf("%d", &matsize);
x = -1*(matsize/2); //with this I make sure that the x and y values start from the top right corner of the matrix, so that each x, y value corresponds to the correct cell position (i, j)
y = matsize/2;
int mat[matsize][matsize];
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
lcheck = y - (x * grad); // calculating the equation of the circle with the x and y values taking the offset into account
if(abs(lcheck-offs) <= thick)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
if(branch == 1)
{
for(i = 0; i < matsize; i++) // displaying the matrix
{ //
for(j = 0; j < matsize; j++)//
{ //
printf("%d ",mat[i][j]);//
} //
printf("\n"); //
} //
}
}
return 0;
}
As I stated in my comment maybe it has something to do with this stack overflow question and answer
After reading a bit, you could also try to buffer your stdout in order to make it faster.
I'm trying to split a 2^n by 2^n 2D array into 4 quadrants. I then want to search these quadrants for pieces of information. If all the quadrant array elements = 1 or 0, then that quadrant can be left alone. If the quadrant has a mix of 1's and 0's, then I want to carry on splitting the array until I am left with a quadrant of only 1's or 0's (Even if that's a single array element). I understand that I must implement a recursive function, but I can't seem to figure out how... Here's what I have so far. Any help is greatly appreciated!
node* split(int **image_array, int width){
node* root = NULL;
int i, j;
int black_pixel_NW = 0, black_pixel_NE = 0, black_pixel_SE = 0, black_pixel_SW = 0;
if (width >= 2){
for (i = 0; i < width/2; i++) {
for (j = 0; j < width/2; j++){
printf("(%d,%d) = %d\n", i, j, image_array[i][j]);
if (image_array[i][j] == 0){
black_pixel_NW = ++black_pixel_NW;
}
}
}
printf("\nBlack pixels NW = %d\n", black_pixel_NW);
for (i = width/2; i < width; i++) {
for (j = 0; j < width/2; j++){
printf("(%d,%d) = %d\n", i, j, image_array[i][j]);
if (image_array[i][j] == 0){
black_pixel_NE = ++black_pixel_NE;
}
}
}
printf("\nBlack pixels NE = %d\n", black_pixel_NE);
for (i = width/2; i < width; i++) {
for (j = width/2; j < width; j++){
printf("(%d,%d) = %d\n", i, j, image_array[i][j]);
if (image_array[i][j] == 0){
black_pixel_SE = ++black_pixel_SE;
}
}
}
printf("\nBlack pixels SE = %d\n", black_pixel_SE);
for (i = 0; i < width/2; i++) {
for (j = width/2; j < width; j++){
printf("(%d,%d) = %d\n", i, j, image_array[i][j]);
if (image_array[i][j] == 0){
black_pixel_SW = ++black_pixel_SW;
}
}
}
printf("\nBlack pixels SW = %d\n", black_pixel_SW);
width = width / 2;
}
return root;}
The code will be for reading a binary image file, hence the black_pixel variables. black_pixel_NW means number of black pixels in the upper left quadrant. I have pointer stuff in the function as this information will eventually be stored in a quad tree.
Recursion is easiest to understand when breaking the function into its absolute barest state. You're actually writing the logic 4 times.
The most obvious solution(to me!) would be to expand the function parameters a bit. Something like:
split(int **img, int x, int y, int width, int height);
Putting your logic in for only a single quadrant, then recursing through each of the four quadrants. Like:
if (all_pixels_same_color) return; // or do something
else {
split(img, x, y, width/2, height/2); // Top left Quadrant
split(img, x + width/2, y, width/2, height/2); // Top right Q.
split(img, x, y + height/2, width/2, height/2); // Bottom left Q.
split(img, x + width/2, y + height/2, width/2, height/2); // Bottom right Q.
}
Now to look through each pixel of the image, just start with the full dimensions of the image
split(img, 0, 0, 256, 256);
The function will treat this as a quadrant, and most likely split into four more quadrants(calling itself four times with the four new starting quadrant locations).
EDIT:
And an example of checking all the pixels in a quadrant for the same value:
if (width == 1 || height == 1)
return; // or something else
int i, j;
int cmp = img[x][y]; // top-left pixel
for (j = y; j < height; j++)
for (i = x; i < width; i++)
if (img[i][j * IMG_WIDTH] != cmp)
goto split_to_quads; // or whatever