Why is my 3d array reversed? - c

I have a 3d array of ints stored in a struct which represents a tetris block:
typedef struct
{
int orientations[4][4][4];
dimension dimensions[4];
int i;
int x;
int y;
}block;
orientations is filled with every possible position for the block and dimension is a struct that provides information for collision checking:
typedef struct
{
int left, right, bottom;
}dimension;
each orientation and dimension should be linked by the block's i value. For some reason orientations (but not dimensions) seems to be reversed. Does anybody know why this is?
here is how I assign values to dimensions:
block* shape = malloc(sizeof(block));
shape->dimensions[0].left = 0;
shape->dimensions[0].right = 3;
shape->dimensions[0].bottom = 1;
shape->dimensions[1].left = 2;
shape->dimensions[1].right = 2;
shape->dimensions[1].bottom = 3;
shape->dimensions[2].left = 0;
shape->dimensions[2].right = 3;
shape->dimensions[2].bottom = 2;
shape->dimensions[3].left = 1;
shape->dimensions[3].right = 1;
shape->dimensions[3].bottom = 3;
and orientations:
int first[4][4] = {{0,0,0,0}, {2,2,2,2}, {0,0,0,0}, {0,0,0,0}};
int second[4][4] = {{0,0,2,0},{0,0,2,0},{0,0,2,0},{0,0,2,0}};
int third[4][4] = {{0,0,0,0},{0,0,0,0},{2,2,2,2},{0,0,0,0}};
int fourth[4][4] = {{0,2,0,0},{0,2,0,0},{0,2,0,0},{0,2,0,0}};
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
shape->orientations[0][i][j] = first[i][j];
}
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
shape->orientations[1][i][j] = second[i][j];
}
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
shape->orientations[2][i][j] = third[i][j];
}
}
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
shape->orientations[3][i][j] = fourth[i][j];
}
}
here is how I'm accessing the array:
shape->orientations[current->i][i][j]
when I attempt to access shape->orientations[3] it returns the values I set to shape->orientations[0] earlier. Any help would be greatly appreciated, thanks in advance.

The reason is that your array is indexed [orientation][row][column], but you are interpreting it as [orientation][x][y] when you should be interpreting it as [orientation][y][x]. So you are getting a pattern with the x and y swapped, which appears as if it has been rotated to a different orientation (actually it's equivalent to a rotation and a flip).

Related

Beginner in C - Array of strings lost content after initialization in cyklus

I am trying to make array of strings each representing one card of a poker deck from 2 strings (ranks, colors). If I try print card immidietly after assignment it's ok but if I try it after all assignments nothing happend.
My "code":
int main(void)
{
char rank[] = "23456789TJQKA";
char color[] = "cdhs";
char deck[52][3];
int k = 0;
for (int i = 0; i < 13; i++) {
for(int j = 0; j < 4; j++) {
deck[k][0] = rank[i];
deck[k][1] = color[j];
deck[k][2] = 0;
k++;
printf("%s\n",deck[k-1]); // this print works
}
}
printf("%s\n",deck[0]); //this does nothing (even if I change index)
//-------------------------- here I am trying make all possible pairs but deck is now empty :(
k = 0;
char allPairs[1327][5];
for (int i = 0; i < 51; i++) {
for (int j = 0; j < 52; j++) { //**edit** - thanks ;)
allPairs[k][0] = deck[i][0];
allPairs[k][1] = deck[i][1];
allPairs[k][2] = deck[j][0];
allPairs[k][3] = deck[j][1];
allPairs[k][4] = 0;
k++;
}
}
}
All seems to work now thanks guys!
What you need to do is replace i++ with j++ in the following statement
for (int j = 0; j < 3; i++)
and also comment out the following line as it is printing 2c again:
printf("%s\n",deck[0]); //this does nothing (even if I change index)

I am getting an error while using bubble sort in array of structures not able to find it

I am having a structure
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
I am using bubble sort to sort as per my choice
Ratings rect[64], temp;
n = 64;
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if (REC1[j].movieId >= REC1[j+1].movieId)
{
temp = REC1[j];
REC1[j] = REC1[j + 1];
REC1[j + 1] = temp;
}
}
}
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if(REC1[j].movieId == REC1[j+1].movieId )
{
if (REC1[j].userId >= REC1[j+1].userId)
{
temp = REC1[j];
REC1[j] = REC1[j + 1];
REC1[j + 1] = temp;
}
}
}
}
i used the above logic to get my output and succeeded. Can it be reduced to less???? Please try it
my inputs are
1,1,9
1,2,0
1,3,2
2,1,2
2,2,10
2,3,10
3,1,7
3,2,1
3,3,9
i want the output as
1,1,9
2,1,2
3,1,7
1,2,0
2,2,10
3,2,1
1,3,2
2,3,10
3,3,9
for this i am using my above logic of sorting still not getting the result
This is the output i am getting but i need a the above output
You have already declared Ratings as a type of struct ratings.
Hence you should declare a array of structure like below
Ratings myratings[100], temp;
if (myratings[i].movieId > myratings[j].movieId)
{
temp = myratings[j];/* it might not work if you are not compiling with a C++ compiler better use memcpy function if you are using a C compiler */
myratings[j] = myratings[j + 1];
myratings[j + 1] = temp;
}
Please correct your bubble short algorithm like below:-
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if (rect[j].movieId > rect[j+1].movieId)
{
temp = rect[j];
rect[j] = rect[j + 1];
rect[j + 1] = temp;
}
}
}
if you want to swap value only not the object it should be like
int t;
//This is bubble sort for middle row
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if (rect[j].movieId > rect[j+1].movieId)
{
t = rect[j].movieId;
rect[j].movieId = rect[j+1].movieId;
rect[j+1].movieId = t;
}
}
}
//This is bubble sort for 1st row
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if (rect[j].userId > rect[j+1].userId)
{
t = rect[j].userId;
rect[j].userId = rect[j+1].userId;
rect[j+1].userId = t;
}
}
}
//This is bubble sort for 3rd row
for (i = 0; i < n-1; i++)
{
for (j = 0; j < (n - i -1); j++)
{
if (rect[j].rating > rect[j+1].rating)
{
t = rect[j].rating;
rect[j].rating = rect[j+1].rating;
rect[j+1].rating = t;
}
}
}
you have to add all the above three while loop in your code
The typedef keyword in
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings, temp;
defines Ratings and temp as aliases for the type struct ratings, not as objects of the type struct ratings. What you want to do is something like
struct ratings {
int userId;
int movieId;
int rating;
};
struct ratings Ratings[N], temp; // where N is the size of the array you want.
or
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
Ratings myRatings[N], temp;
I prefer the first form, myself. I'd rather not hide a struct type behind a typedef if the user of the type has to be aware of its struct-ness (i.e., having to access individual members).

Array values changing without reason

This is my code for Project Euler: Problem 11
int main(int argc, char** argv) {
char stevila [1600] = "08022297381500400075040507785212507791084949994017811857608717409843694804566200814931735579142993714067538830034913366552709523046011426924685601325671370236912231167151676389419236542240402866331380244732609903450244753353783684203517125032988128642367102638406759547066183864706726206802621220956394396308409166499421245558056673992697177878968314883489637221362309750076442045351400613397343133957817532822753167159403800462161409535692163905429635314755588824001754243629855786560048357189070544443744602158515417581980816805944769287392138652177704895540045208839735991607975732162626793327986688366887576220720346336746551232639353690442167338253911249472180846293240627636206936417230238834629969826759857404361620733529783190017431497148868116235705540170547183515469169233486143520189196748";
int stevilaGrid [20][20];
int stevilaRacunanje[4][4];
int stevecPoStevilih = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
stevilaGrid[i][j] = (stevila[stevecPoStevilih] - 48)*10 + stevila[stevecPoStevilih + 1] - 48;
stevecPoStevilih += 2;
}
}
int rezultat [10];
int najvecji = 0;
int trenutni;
int temp = 0;
for (int i = 0; i < 17; i++) {
for (int j = 0; j < 17; j++) {
//problems start here
for (int k = 0; k < 5; k++) {
for (int l = 0; l < 5; l++) {
temp = stevilaGrid[i + k][j + l];
stevilaRacunanje[k][l] = temp;
}
}
for (int k = 0; k < 5; k++) {
rezultat[k] = stevilaRacunanje[k][0] * stevilaRacunanje[k][1] * stevilaRacunanje[k][2] * stevilaRacunanje[k][3];
rezultat[k+4] = stevilaRacunanje[0][k] * stevilaRacunanje[1][k] * stevilaRacunanje[2][k] * stevilaRacunanje[3][k];
}
rezultat[8] = stevilaRacunanje[0][0] * stevilaRacunanje[1][1] * stevilaRacunanje[2][2] * stevilaRacunanje[3][3];
rezultat[9] = stevilaRacunanje[0][3] * stevilaRacunanje[1][2] * stevilaRacunanje[2][1] * stevilaRacunanje[3][0];
for (int k = 0; k < 10; k++) {
trenutni = rezultat[k];
if(trenutni > najvecji){
najvecji = trenutni;
}
}
}
}
printf("Najvecji zmnozek: %d", najvecji);
return (EXIT_SUCCESS);
}
First I convert the string of numbers into a 2D int array.
Then I try to divide the grid into smaller 4x4 squares with which I can work more easily. That is where the problems start (as marked in the code).
At the very beginning (*i=0,j=0;k=4,j=0*) something strange starts to happen. The values in *stevilaGrid[][]* start to change randomly and seemingly without a reason.
Can somebody please explain this to me. I have tested this behavior on Windows with Cygwin 64bit and Ubuntu with GCC 64bit.
[i + k][j + l];
When i==16 and k==4 or j==16 and j==4 you'll be hitting element [20]
Your array only goes 0...19

Accessing array of classes

I am trying to create a 1d array that contains classes as its type. The following code is what have so far:
public class dog{
int x;
int y;
int health;
}
Dog[] dog_properties = new Dog[4];
for(int i = 0; i < 4; i++){
Dog d = new Dog();
d.x = 2;
d.y = 3;
d.health = 10;
dog_properties[i] = d;
}
How do i access each property of dog from the array once it has been stored there? By this i mean i if want to iterate over the array later on how do i access d.x?
for(int i = 0; i < 4; i++){
int x = dog_properties[i].x;
}
for (int i = 0; i < 4; i++)
{
Dog d = dog_properties[i];
int x = d.x;
}
If the properties are public you can do:
for(int i; i < 4; i++){
int x = dog_properties[i].x;
}

High Pass Filter using FFTW in C

I have a question regarding FFT. I already manage to do FFT forward and backward using FFTW in C. Now, I want to apply high pass filter for edge detection, some of my source said that just zeroing the centre of the magnitude.
This is my input image
http://i62.tinypic.com/2wnxvfl.jpg
Basically what I do are :
Forward FFT
Convert the output to 2D array
Do forward FFT shifting
Make the real and imag value to 0 when the distance from the centre is 25% of the height
Generate the magnitude
Do backward FFT shifting
Convert into 1D array
Do Backward FFT.
This is the original magnitude, the processed magnitude, and the result
http://i58.tinypic.com/aysx9s.png
can someone help me, to tell me which part is wrong and how to do the high pass filtering using FFTW in C.
Thank You.
The Source Code:
unsigned char **FFT2(int width,int height, unsigned char **pixel, char line1[100],char line2[100], char line3[100],char filename[100])
{
fftw_complex* in, * dft, * idft, * dft2;
//fftw_complex tmp1,tmp2;
fftw_plan plan_f,plan_i;
int i,j,k,w,h,N,w2,h2;
w = width;
h = height;
N = w*h;
unsigned char **pixel_out;
pixel_out = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_out[i]=malloc(w*sizeof(unsigned char));
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
idft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
/*run forward FFT*/
plan_f = fftw_plan_dft_2d(w,h,in,dft,FFTW_FORWARD,FFTW_ESTIMATE);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
in[k][0] = pixel[i][j];
in[k][1] = 0.0;
}
}
fftw_execute(plan_f);
double maxReal = 0.0;
for(i = 0 ; i < N ; i++)
maxReal = dft[i][0] > maxReal ? dft[i][0] : maxReal;
printf("MAX REAL : %f\n",maxReal);
/*fftshift*/
//convert to 2d
double ***temp1;
temp1 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp1[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp1[i][j] = malloc(2*sizeof(double));
}
}
double ***temp2;
temp2 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp2[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp2[i][j] = malloc(2*sizeof(double));
}
}
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] = dft[i*w+j][0];
temp1[i][j][1] = dft[i*w+j][1];
}
}
int m2 = h/2;
int n2 = w/2;
//forward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//process
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 0.25*h)
{
temp1[i][j][0] = (double)0.0;
temp1[i][j][1] = (double)0.0;
}
}
}
/* copy for magnitude */
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp2[i][j][0] = temp1[i][j][0];
temp2[i][j][1] = temp1[i][j][1];
}
}
//backward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//convert back to 1d
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
dft[i*w+j][0] = temp1[i][j][0];
dft[i*w+j][1] = temp1[i][j][1];
dft2[i*w+j][0] = temp2[i][j][0];
dft2[i*w+j][1] = temp2[i][j][1];
}
}
/* magnitude */
double max = 0;
double min = 0;
double mag=0;
for (i = 0, k = 1; i < h; i++){
for (j = 0; j < w; j++, k++){
mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
if (max < mag)
max = mag;
}
}
double **magTemp;
magTemp = malloc(h * sizeof (double*));
for (i = 0;i < h; i++){
magTemp[i] = malloc(w*sizeof (double));
}
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
mag = 255*(mag/max);
//magTemp[i][j] = 255-mag; //Putih
magTemp[i][j] = mag; //Item
}
}
/* brightening magnitude*/
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
//double temp = magTemp[i][j];
double temp = (double)(255/(log(1+255)))*log(1+magTemp[i][j]);
pixel_out[i][j] = (unsigned char)temp;
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"magnitude");
/* backward fft */
plan_i = fftw_plan_dft_2d(w,h,dft,idft,FFTW_BACKWARD,FFTW_ESTIMATE);
fftw_execute(plan_i);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double temp = idft[i*w+j][0]/N;
pixel_out[i][j] = (unsigned char)temp; //+ pixel[i][j];
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"backward");
return pixel_out;
}
EDIT new source code
I add this part before the forward shifting, the result is as expected also.
//proses
//create filter
unsigned char **pixel_filter;
pixel_filter = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_filter[i]=malloc(w*sizeof(unsigned char));
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 20)
{
pixel_filter[i][j] = 0;
}
else
{
pixel_filter[i][j] = 255;
}
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter1");
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
unsigned char tmp13 = pixel_filter[i][k];
pixel_filter[i][k] = pixel_filter[i+m2][k+n2];
pixel_filter[i+m2][k+n2] = tmp13;
unsigned char tmp24 = pixel_filter[i+m2][k];
pixel_filter[i+m2][k] = pixel_filter[i][k+n2];
pixel_filter[i][k+n2] = tmp24;
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter2");
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] *= pixel_filter[i][j];
temp1[i][j][1] *= pixel_filter[i][j];
}
}
Your general idea is OK. From the output, it's hard to tell whether there's simply an accounting problem in your program, or whether this is perhaps the expected result. Try padding the source image with much more empty space, and filter out a smaller area in the frequency domain.
As a side note, doing this in C appears incredibly painful. Here is an equivalent implementation in Matlab. Not including plotting, it's around 10 lines of code. You might also try Numerical Python (NumPy).
% Demonstrate frequency-domain image filtering in Matlab
% Define the grid
x = linspace(-1, 1, 1001);
y = x;
[X, Y] = meshgrid(x, y);
% Make a square (source image)
rect = (abs(X) < 0.1) & (abs(Y) < 0.1);
% Compute the transform
rect_hat = fft2(rect);
% Make the high-pass filter
R = sqrt(X.^2 + Y.^2);
filt = (R > 0.05);
% Apply the filter
rect_hat_filtered = rect_hat .* ifftshift(filt);
% Compute the inverse transform
rect_filtered = ifft2(rect_hat_filtered);
%% Plot everything
figure(1)
imagesc(rect);
title('source');
axis square
saveas(gcf, 'fig1.png');
figure(2)
imagesc(abs(fftshift(rect_hat)));
title('fft(source)');
axis square
saveas(gcf, 'fig2.png');
figure(3)
imagesc(filt);
title('filter (frequency domain)');
axis square
saveas(gcf, 'fig3.png');
figure(4)
imagesc(fftshift(abs(rect_hat_filtered)));
title('fft(source) .* filter');
axis square
saveas(gcf, 'fig4.png');
figure(5)
imagesc(abs(rect_filtered))
title('result');
axis square
saveas(gcf, 'fig5.png');
The source image:
Fourier transform of the source image:
The filter:
Result of applying (multiplying) the filter with the fourier transform of the source image:
Taking the inverse transform gives the final result:

Resources