2D isometric engine - Math problems - Cube selection - diamond shape map - c++

I calculate my coordinates when i create a layer with a std::vector, filled with cube objects(wich is a class of mine):
for(int J = 0; J < mapSize; J++)
{
for(int I = 0; I < mapSize; I++)
{
x = (J - I) * (cubeSize/2);
y = (J + I) * (cubeSize/4);
c = new cube(cubeSize, x, y, z, I, J);
cs.push_back(*c);
}
}
I wanna do this : cs[getCubeByID(mouseX, mouseY)].setTexture(...);
Example of use: The cube in I-J [0, 0] have the number 0 in the cubes array. if i click on 0,0 i got this number.
EDIT:
We gave me the formula to get a J or a I with a pair of x,y in the comments, thanks a lot. I only need to convert this pair of I-J to the entry number of my array like the example i gave.
I tried : int entry = (J - 1) * size + (I - 1); and the selected cube is not so far from the one i want but still not the right formula. Modular arithmetic can fix my problem but i don't understand how it's working.

So you have
x = (J - I) * (cubeSize/2);
y = (J + I) * (cubeSize/4);
and you want to compute I and J (and therefore the index which is I + J*mapSize) from that, right? It's a linear system of two equations.
J - I = x * 2 / cubeSize
J + I = y * 4 / cubeSize
I = (y * 2 - x) / cubeSize
J = (y * 2 + x) / cubeSize

Related

Implementing the Lanczos algorithm into C++ for a quantum anharmonic oscillator

Firstly, I would like to mention that I am a complete beginner when it comes to coding, let alone C++, so bear with me, as I need complete guidance. My task is to implement the Lanczos algorithm for the case of a 1-D anharmonic oscillator in C++, with reference to the paper linked Analytical Lanczos method.
The paper offers a step by step guide for the implementation of the algorithm:
Step by step guide here
with the initial trial function being: Psi_1 = (1 + x^2) * (exp(-x^2 - 1/4 * x^4).
The paper also contains code in MATHEMATICA for this particular case. Mathematica code
and thus, here is my attempt, which is greatly unfinished, however, I wanted to ensure I was going along the correct path with regards to the programming logic. There are still plentiful errors etc. (Also excuse the lack of fundamentals here, I am only a beginner. Thank you very much.)
int main() {
//Grid parameters.
const int Rmin = 1, Rmax = 31, nx = 300;//Grid length and stepsize.
double dx = (Rmax- Rmin) / nx; //Delta x.
double a, b;
std::vector<double> x, psi_1;
for (int j = 1; j < 64; ++j) { //Corresponds to each succesive Lanczos Vector.
for (int i = Rmin; i < nx + 1; i++) { //Defining the Hamiltonian on the grid.
x[i] = (nx / 2) + i;
psi_1[i] = (1 + pow(x[i] * dx, 2)) * exp(pow(-x[i] * dx, 2) - (1 / 4 * pow(x[i] * dx, 4 )) //Trial wavefunction.
H[i] = ((PSI[j][i + 1] - 2 * PSI[j][i] + PSI[j][i - 1]) / pow(dx, 2)) + PSI[j][i] * 1/2 * pow(x[i] * dx, 2) + PSI[j][i] * 2 * pow(x[i] * dx, 4) + PSI[j][i] * 1/2 * pow(x[i], 6); //Hamiltonian. ****
//First Lanczos step.
PSI[1][i] = psi_1[i]
}
//Normalisation of the wavefunction (b).
double b[j] = 0.0;
for (int i = Rmin; i < nx + 1; i++) {
PSI[1][i] = psi_1[i];
b[j] += abs(pow(PSI[j][i], 2));
}
b[j] = b[j] * dx;
for (int i = Rmin; i < nx + 1; i++) {
PSI[j] = PSI[j] / sqrt(b[j]);
}
//Expectation values (a). Main diagonal of the Hamiltonian matrix.
double a[j] = 0.0;
for (int i = Rmin; i < nx + 1; i++) {
a[j] += PSI[j] * H[i] * PSI[j] * dx
}
//Recursive expression.
PSI[j] = H[i] * PSI[j-1] - PSI[j-1] * a[j-1] - PSI[j-2] * b[j-1]
//Lanczos Matrix.
LanczosMatrix[R][C] =
for (int R = 1; R < 64; R++) {
row[R] =
}
}
I have yet to finish the code, but some experienced guidance would be greatly appreciated! (also, the code has to be cleaned up greatly, but this was an attempt to get the general idea down first.)

How do I handle edge pixels from a image without any libraries but the standart ones from C++?

I have developed a code that can read and handle the bits from a 24 bits bmp image, mostly applying filters, but now I want to make my blur filter to blur the edge pixels too. Right now I have a 1 pixel edge, I'm using a 3x3 box blur, and this is the image I get after the blur is applied:
https://i.stack.imgur.com/0Px6Z.jpg
I'm able to keep the original bits from the image if I use an if statement in my inner loop but that doesn't really help given that I want it to be blurred and not the original unblurred bits.
Here is the code:
>
for (int count = 0; count < times; ++count) {
for (int x = 1; x < H-1; ++x) {
for (int y = 1; y < W-1; ++y) {
double sum1 = 0;
double sum2 = 0;
double sum3 = 0;
for (int k = -1; k <= 1; ++k) {
for (int j = -1; j <= 1; ++j) {
sum1 += bits[((x - j) * W + (y - k)) * 3] * kernel[j + 1][k + 1];
sum2 += bits[((x - j) * W + (y - k)) * 3 + 1] * kernel[j + 1][k + 1];
sum3 += bits[((x - j) * W + (y - k)) * 3 + 2] * kernel[j + 1][k + 1];
}
}
if (sum1 <= 0) sum1 = 0;
if (sum1 >= 255) sum1 = 255;
if (sum2 <= 0) sum2 = 0;
if (sum2 >= 255) sum2 = 255;
if (sum3 <= 0) sum3 = 0;
if (sum3 >= 255) sum3 = 255;
temp[(x * W + y) * 3] = sum1;
temp[(x * W + y) * 3 + 1] = sum2;
temp[(x * W + y) * 3 + 2] = sum3;
}
}
bits = temp;
}
I know that 5 for loops nested are really slow but I would like to be able to make it work properly first, but if there are any tips on how to improve it I'm all ears.
Now as for the first loop, what it does is it applies the filter the amount of times you want.
The next two is to go through the vector as a 2d vector, and the inner 2 are for the box blur.
Important things to know: I have a vector of bits(RGB) and not just the pixels, that is why I treat them one by one(bits), also my vector is a 1d vector.

C++: Transpose of Matrix, using SINGLE DIMENSION dynamic array to save elements

Dear Friends I am having problem to transpose a matrix. The transposed matrix has elements that are undefined. Not sure what is wrong. Thank you for your time!
entries[i] is the dynamic array storing the elements in the matrix. Elements are stored row by row, from left to right. i.e. in a 3X3 matrix, entries[2] is 3rd element on the 1st row, entries[3] is 1st element on the 2nd row
n is the number of rows of matrix
m is the number of columns of matrix
Matrix Matrix::Transpose() const {
double* temp;
temp = new double[n * m];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
temp[(j - 1) * m + i - 1] = entries[(i - 1) * m + j - 1];
}
Matrix Result(m, n, temp);
delete temp;
return Result;
}
When the original matrix is a square, all elements of the transposed matrix are defined. When the original matrix is 1x3, then the resulting transposed 3x1 matrix has undefined elements for the 2nd and 3rd elements. I.e. (1 1 3) after transposed returns (1 -3452346326236 -12351251515)
The Matrix Print out function is below. The error likely comes from here too.
void Matrix::Print() const
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
cout << setw(13) << entries[(i - 1) * m + j - 1];
cout << endl;
}
}
When the matrix is not square, the line
temp[(j - 1) * m + i - 1] = entries[(i - 1) * m + j - 1];
is not right. It needs to be:
temp[(j - 1) * n + i - 1] = entries[(i - 1) * m + j - 1];
// ^^ needs to be n, not m.
Think of the 2D analogue. You want to use:
temp[j][i] = entries[i][j];
entries is a n x m matrix. For it, the 2D indices [i][j] are translated as [i*m + j] for the 1D index.
temp is a m x n matrix. For it, the 2D indices [j][i] are translated as [j*n + i] for the 1D index.
Suggestion for improved readability
Instead of n and m, use num_rows, and num_columns. You will find your code a lot more readable.

Symmetric matrix, value into c++ vector

I am trying to solve the following problem. Let's say I have a symmetric matrix with size n. I want to take all the "important values", and store them into a vector. Let me give an example to explain it better.
Let's say I have the following matrix A = [1, 2, 3 // 2, 5, 6 // 3, 6, 9]. I want to define vector of size n*(n+1)/2 such that:
V = [A(0,0), A(0,1), A(0,2), A(1,1), A(1,2), A(2,2) ]
I want to find a function that receives as input two integer i and j, and outputs the corresponding value of the matrix. The catch is that I do not want to access the matrix directly, instead I want to access the vector.
This is my reasoning so far. If I have an input with j < i, I just swap them since the matrix is symmetric. If I have that i == 0, the position in the array is just j. If that is not the case, I think I need to do something like this. (n is the dimension of the matrix, and position is the integer that I need when for the array.)
int position = 0;
for(int k = 0; k < i; k++){
position = position + (n-k);
}
position = position + j % i;
However, this code fails. I think I'm close to the solution but I am missing something. Any help?
The last j % i should be j - i.
In addition, the loop is essentially doing
position = n + (n - 1) + ... + (n - i + 1);
which can be simplified to
position = (n * 2 - i + 1) * i / 2;
So you can simply write
position = (n * 2 - i + 1) * i / 2 + j - i;
or
position = (n * 2 - i - 1) * i / 2 + j;
You can do simply this:
int myvector[matrix.size()];
int pos = 0;
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < matrix.size(); j++){
if(j > i) myvector[pos++] = matrix[i][j];
else myvector[pos++] = matrix[j][i];
}
}

How to draw a grid of spheres in increasing order in C++?

I've been trying to draw a grid of spheres in increasing order of radius (Image link above) but then all the loops I've tried have been failing. I made the loop below because I thought for one value of x, the y values are incremented and drawn fully and then the x gets incremented and the whole process repeats. But then that doesn't work. What changes should I make?
'a' is a variable belonging to class that contains the coordinates and radius of a sphere.
a.x = -500, a.y = -500, a.z = 0, a.r=0;
for (int i = 0; i < 500; i++, a.x += 30, a.r++)
for (int j = 0; j < 10; j++, a.y += 30, a.r++)
drawSphere(a.x + (2 * a.r), a.y, a.z, a.r);
Derive the values rather than trying to manipulate some kind of counter:
for (int i = 0; i < 500; i++)
for (int j = 0; j < 10; j++)
drawSphere(a.x + i * 30, a.y + j * 30, a.z, a.r + i + j);
"As a function of" is a mathematical term meaning the final value of x you need can be computed from the a.x and i values, there's no other input necessary. Here it's effectively:
x = a.x + i * 30