Generate circle around certain point of a 2D matrix [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I am trying to make a height map using randomly generated values in console using c++.
I have an array [50, 50] that is initialized as all 0s.
matrix = new int[rows * columns];
for (int i = 0; i < rows; i++) {
for (int k = 0; k < columns; k++) {
matrix[i * columns + k] = 0;
}
}
I use a loop to generate random points in the array and store the position of those points in a vector.
std::vector<int> sprinklePeaks(int peakDensity, int dimension) {
int count = 0;
std::vector<int> peaks;
for (int i = 0; i < peakDensity; i++) {
int peakIndex = randomize(0, dimension);
matrix[peakIndex] = randomize(69, 99);
peaks.push_back(peakIndex);
}
return peaks;
}
Problem: I am trying to generate a circle with a random radius around these points and fill the circle with randomly generated values, increasing as they approach the center, my circle generation seems to have the right coordinates for the center but the distance is wrong and no values get added to the matrix.
void circleGen(std::vector<int> peaks, int dimensions) {
for (int i = 0; i < peaks.size(); i++) {
int radius = randomize(5, 15);
int area = 3.14159 * radius * radius;
int index = peaks[i];
int x = index / 50;
int y = index % 50;
// std::cout << "Peak: " << peaks[i] << "\n";
// std::cout << "Peak Coordinates: [" << x << ", " << y << "]\n";
int peakHeight = matrix[peaks[i]];
for (int k = 0; k < radius * 2; k++) {
for (int j = 0; j < radius * 2; j++) {
int distance = sqrt((i - radius) * (i - radius) + (j - radius) * (j - radius));
matrix[x - j * columns + y - k] = randomize(10, 20);
}
}
}
}

First issue could be that you don't have bounds checking. I assume you should not change the matrix (and more importantly the surrounding memory) if coordinates are out of the bounds.
Second issue I see is that you calculate distance, but then you don't use this value.
Third issue could be that you want to add to the matrix cell, not replace the value. In line matrix[x - j * columns + y - k] = randomize(10, 20); maybe it should be += instead of =. And distance should participate in the right-side. Or you want to replace, but only if new value is greater than the existing value.
Fourth, as Andrej in the comments mentioned, the math to calculate the index in the matrix is wrong. Should use parentheses, (x - j) * columns + y - k

Related

Generate vector elements from previous elements

I would like to build a vector of vectors which is really a tree. I have the seed value and going forward, I multiply the seed with u to get the up value and with d to get the down value. I have the below snippet that does what I want but can you please suggest a more efficient approach?
void short_rate_lattice() {
double r00 = 0.06;
double u = 1.25;
double d = 0.9;
int num_periods = 5;
vector<vector<double>> short_rates(num_periods + 1);
short_rates[0].push_back(r00);
for (int i = 1; i <= num_periods; ++i) {
for (int j = 0; j < i; ++j) {
short_rates[i].push_back(d * short_rates[i - 1][j]);
}
short_rates[i].push_back(u * short_rates[i - 1][i - 1]);
}
cout << "short_rates vector is populated" << endl;
}

Using the flattened array syntax in C++, crashes depending on width/height

I have read quite a few articles in SO and cplusplus.com and decided to give a try to the flattened, 1D array that mimics 2D and 3D.
I managed to get a prototype to work with some values, but there is something wrong with the indices, which has to be the formula. All I did was copy the formula from different places and applied to the code. Here it is:
#include <iostream>
using namespace std;
int main(void)
{
float *flat_2d_array, *flat_3d_array;
int width, height, depth, counter;
counter = 1;
width = 2;
height = 3;
depth = 4;
flat_2d_array = new float[width * height];
flat_3d_array = new float[width * height * depth];
// 2D part, works fine
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
flat_2d_array[y * width + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
cout << "Element [" << x << "]" << "[" << y << "] = " << flat_2d_array[y * width + x] << endl;
cout << endl;
// Resets the counter and runs the 3D part
counter = 1;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
flat_3d_array[z * height * depth + y * depth + x] = counter++;
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
for(int z = 0; z < depth; z++)
cout << "Element [" << x << "]" << "[" << y << "]" << "[" << z << "] = " << flat_3d_array[z * height * depth + y * depth + x] << endl;
delete[] flat_2d_array;
delete[] flat_3d_array;
return 0;
}
It just declares a few variables, allocates memory for the arrays, populates them with a counter in for() loops and prints the elements, then frees the memory.
If you copy/paste it will compile the way it is and will run fine.
However, if you change width to 3 and height to 2, then compile and run, it will crash after the element [2][1][3] in the 3D part.
So there seems to be indexing problem with this formula I'm using for the 3D:
3d_array[ X ][ Y ][ Z ] == flat_3d_array[ Z * height * depth + Y * depth + X ]
Can you guys see anything incorrect?
Can you guys see anything incorrect?
yes, your formula should be instead:
z * height * width + y * width + x
or more efficient form:
( z * height + y ) * width + x
and you should make loop on x inner, otherwise you iterate against CPU cache.
To make clear: making loop on x inner would not affect correctness of your program, it will make it more efficient (including iteration on 2d array as well). Your program crashes because you calculate linear index for 3d array by wrong formula.

Implement 2d array coordinates in 1d array in C++

The code inside the for loop is for the x and y (j and i) "coordinates" from a 2d array. How could I implement this neighbor/index finding in a 1d array?
I think I could implement it for the first four equations. But i'm confused as how to implement up-left etc.
for(int i=0; i<cols*rows; i++){
//Counts current index's 8 neigbour int values
int count=0;
int x = i%cols;
int y = i/rows;
//rows y i
//cols x j
count+= [grid][i][(j-1+cols)%cols] //left
+[grid][i][(j+1+cols)%cols] //right
+[grid][(i-1+rows)%rows][j] //up
+[grid][(i+1+rows)%rows][j] //down
+[grid][(i-1+rows)%rows][ (j-1+cols)%cols] //up-left
+[grid][(i+1+rows)%rows][ (j+1+cols)%cols] //down-right
+[grid][(i+1+rows)%rows][ (j-1+cols)%cols] //down-left
+[grid][(i-1+rows)%rows][ (j+1+cols)%cols] ;//up-right
}
Starting with a 1-D vector:
int rows = 10;
int cols = 10;
vector<int> grid(rows * cols);
You can manage this in different ways, example
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < cols; x++)
{
int point = grid[y * rows + x];
}
}
Where you can access any point at any given x and y in a 2-dimensional plane.
Top-left is:
x = 0;
y = 0;
bottom-right is
x = cols - 1;
y = rows - 1;
And so on.
Use a function like this
inline int idx(const int i, const int j, const int rows) const
{
return i * rows + j;
}
to convert the 2d indices to 1d indices.
This way you don't have to change your algorithm.
Usage would be grid[idx(i, (j-1+cols)%cols, rows)].
The basic formula for computing the 1d coordinate from the 2d index pattern is usually one of the following:
row_index * row_length + column_index
column_index * column_length + row_index
Which one applies to your case depends on whether you would like to have a row-based or column-based memory layout for your 2d array. It makes sense to factor out the computation of this index into a separate function, as suggested in the other answer.
Then you just need to fill in the values somehow.
You could do it like this, for example:
// iterate big picture
// TODO: make sure to handle the edge cases appropriately
for (int i_row = 1; i_row < n_rows - 1; i_row++) {
for (int i_col = 1; i_col < n_cols -1; i_col++) {
// compute values
dst[i_row*n_cols+i_col] = 0;
for (int r = i_row-1; r < i_row+2; r++) {
for (int c = i_col-1; c < i_col+2; c++) {
dst[i_row*n_cols+i_col] += src[r*n_cols + c];
}
}
}
}
Assuming src and dst are distinct 1d vectors of size n_rows*n_cols...

C++ Image processing loop

I have two grey scale images in txt files, one being a smaller block of the Main image. I have read the images into two different 2d vector matrices.
The Rows and the Columns of the images are:
Main: M = 768 N = 1024
SubImg: R = 49 C = 36
int R = 49; int C = 36; //Sub Image Rows / Columns
int M = 768; int N = 1024; //Main Image Rows / Columns
I want to loop through the Main image by blocks of width: 49 and height: 36 and put each block into an array, so I can compare the array with the Sub image (using Nearest Neighbor Search) to see which block has the closest result to the Sub image.
The problem I am having is that I cannot get the loop to display all of the blocks. When I run the loop only a certain number of block appear and the program clashes.
// Testing Main 2D Vector in block format
for (int bx = 0; bx < M; bx += R)
for (int by = 0; by < N; by += C)
{
for (int x = 0; x < R; ++x)
{
for (int y = 0; y < C; ++y)
{
cout << MainIMG_2DVector[bx + x][by + y] << " ";
}
}
cout << "\n\n" << endl;
}
Can someone please tell me what I have done wrong.
Thanks
EDIT +++++++++++++++++++++++++++++++++++++++++
After debugging
_DEBUG_ERROR("vector subscript out of range");
_SCL_SECURE_OUT_OF_RANGE;
M=768 is not divisible by R=49, the last loop starts with bx=735 (15*49) and should ends to bx=735+48=783 > 768... Same problem in N=1024 and C=36 by=1008 (28*36) to by=1008+35=1043 > 1024. – J. Piquard
If I increase the width and the height, my main image stretch. Is there a way around this?
Two ways could be explored:
Way 1 - change the value R (and C) to the best divider of M (and N)
int M = 768; int N = 1024; //Main Image Rows / Columns
int R = 48; int C = 32; //Sub Image Rows (768=16*48) / Columns (1024=32*32)
Way 2 - prevent out of range error in the for-loop exit condition
For x, both conditions (x < R) and ((bx + x) < M)) shall be
true.
And for y, both conditions (y < C) and ((by + y) < N)) shall be
true.
for (int x = 0; ((x < R)&&((bx + x) < M)); ++x)
{
for (int y = 0; ((y < C)&&((by + y) < N)); ++y)
{
if ((bx + x)>=M) {
std::cout << (bx + x) << (by + y) << " ";
}
}
}
Instead of:
for (int x = 0; x < R; ++x)
{
for (int y = 0; y < C; ++y)
{
if ((bx + x)>=M) {
std::cout << (bx + x) << (by + y) << " ";
}
}
}

Rotating a 2D converted 1D array 90 degrees clockwise

Been stuck on this a few days now, I'm going out my mind. Essentially I have converted a 2D array of values (an image, I know there are easier ways to achieve this but I have explicit requirements) into a 1D array. I can rotate the 2D array with ease. I'm having trouble with the rotating of the 1D version of the array, and I think it's down to a single line of algorithm being incorrect.
The code I'm using for rotating the array is:
cout << "\nTransfer from 2D to dynamic 1D array and print details\n\n";
myImage * p_myImage = new myImage[total];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int offset = width * y + x;
p_myImage[offset].pixel = array2D[y][x];
cout << p_myImage[offset].pixel << " ";
}
cout << "\n";
}
//new pointer to copy to
myImage * p_myImage2 = new myImage[total];
cout << "\nRotate Matrix through 1D array\n\n";
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int offset = height * x + y;
//int offset = width * y + x ;
p_myImage2[offset].pixel = p_myImage[height-1+x].pixel;
cout << p_myImage2[offset].pixel << " ";
}
cout << "\n";
}
This should rotate it clockwise:
p_myImage2[offset].pixel = p_myImage[width * (height - 1 - y) + x].pixel;