I am trying to rotate a 2d vector clockwise but I am unable to get it to work for vectors that are not square.
Here is what I tried
bool Pgm::Clockwise(){
int i, j, k;
vector <vector <int> > tempPixel;
for (i = 0; i < Pixels.size(); i++) {
tempPixel.push_back(Pixels.at(i));
}
for (j = 0; j < tempPixel.size(); j++) {
tempPixel.push_back(vector<int>());
for (k = 0; k < tempPixel.at(0).size(); k++) {
tempPixel.at(j).push_back(Pixels.at(j));
}
}
return true;
}
#include <vector>
std::vector<std::vector<int>> rotateClockwise(std::vector<std::vector<int>> v) {
int n = v.size();
int m = v[0].size();
// create new vector with swapped dimensions
std::vector<std::vector<int>> rotated(m, std::vector<int>(n));
// populate the new vector
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
rotated[j][n-i-1] = v[i][j];
}
}
return rotated;
}
This function takes a 2D vector as input and returns a new 2D vector that is rotated 90 degrees clockwise. It first creates a new vector rotated with dimensions swapped, then populates it by copying the elements from the input vector in the appropriate order.
i hope this will help you to get an idea..
Related
I have written some c++ code that receives a Matrix as input and now I want to create a 2D array with matrices in each element so that I can send the individual matrices to the function.
typedef vector< vector > Matrix;
double a[2][2] = Matrix(2, vector(2));
so that each element of a is a 2x2 Matrix.
The reason I don't want to just create a 4D array with vectors is that I want to keep all of the original functions that I have already created with matrices as input.
Any way this is possible?
Here is a simple example code...
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <vector>
typedef vector< vector > Matrix;
void test2D_array(int l, int m, Matrix &a, Matrix &b) {
int R = l - 1;
for (int i = 0; i < m+1; i++) {
b[l - 1][i] = a[l][i];
b[l - 2][i] = (l - 1) * a[l - 1][i];
for (int k = R-1; k > 0; k--) {
b[k - 1][i] = b[k + 1][i] + a[k][i];
}
}
}
int main(void) {
Matrix a(2, vector<double>(2));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = 1;
}
}
Matrix b(2, vector<double>(2));
test2D_array(2, 2, a, b);
// What I want to accomplish...
// Matrix a[2][2] = Matrix((2, vector<double>(2)); i.e. 4D array with each element a 2x2 matrix
// for (int i = 0; i < 2; i++) {
// for (int j = 0; j < 2; j++) {
// test2D_array(2, 2, a[i][j], b);
// }
//}
//
return 0;
}
I would like to ask how to use the dft function in opencv to do Fourier transform with 2d vector.
I have error in my code ...
thank you all
//2d vector in here v1 and v2
//vector size is 1000*1000
//i have to do about 600 images in this process
for (int k = 0; k < 600; k++){
vector <vector <complex < double >>> v1(InputWidth, vector<complex < double >>(InputHeight));
vector <vector <complex < double >>> v2(InputWidth, vector<complex < double >>(InputHeight));
for (int i = 0; i < InputWidth; i++) {
int tempIndex = i*InputHeight;
for (int j = 0; j < InputHeight; j++)
{
int Correction_value = ProjectionImage[k]->data.s[tempIndex + j] * meshGrid[tempIndex + j];
ProjectionImage[k]->data.s[tempIndex + j] = Correction_value;
//v1 is an image
v1[i][j] = Correction_value;
}
}
//error happen in here
dft(v1, v2, DFT_COMPLEX_OUTPUT);
//do frequency filter
for (int i = 0; i < InputWidth; i++) {
for (int j = 0; j < InputHeight; j++)
{
v2[i][j] *= filter_2D[i][j];
}
}
//inverse fourier transform
idft(v2, v1, DFT_COMPLEX_OUTPUT);
}
error message
What is happening here is that you create a std::vector of pointers to other vectors. Those other vectors contain the pixel data. But those data are therefore not necessarily contiguous. Each row (or column) of your image is stored in its own memory segment. OpenCV expects all pixels to be in the same memory segment.
In short, simply copy your pixel data to a form supported by OpenCV, such as a cv::Mat.
So i keep trying to transfer the elements but it keeps giving me repeated elements, it fails to properly copy the 2D array onto a 1D vector
// This was one of my attempts
vector<int> rando(int rowsize, int columnsize)
{
int elements = rowsize*columnsize;
vector<int> x(elements);
int matrix[100][100];
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
srand((int)time(0));
matrix[i][j]= -10 + rand() % 21;
for(int n=0; n < elements; n++)
x[n]=matrix[i][j];
}
// Ive also tried this
for(int n=0; n < elements; n++)
{
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
x[n]=matrix[i][j];
}
}
}
}
return x;
}
Why do you want to store data into the matrix first and copy it into the vector afterwards? Use the vector from the start.
std::vector<int> rando(std::size_t rowsize, std::size_t columnsize)
{
std::vector<int> v(rowsize*columnsize);
std::mt19937 mt{std::random_device{}()};
std::uniform_int_distribution<int> rand_dist(-10, 10);
for (auto & e : v) e = rand_dist(mt);
return v;
}
If you want to transfer data from a matrix into a vector you must calculate the proper index or just increment a single variable as Thomas Matthews suggests.
constexpr std::size_t n = 100, m = 100;
int matrix[n][m];
// do stuff with matrix
std::vector<int> v(n*m);
for (std::size_t i=0; i<n; ++i)
{
for (std::size_t j=0; j<m; ++j)
{
v[i*m + j] = matrix[i][j];
}
}
THe general copy should loop through the 2 dimensions, and just increment the target index at each iteration (no third nested loop):
int n=0;
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
...
x[n++]=matrix[i][j]; // not in an additional for loop !!
}
} // end of initialisation of matrix
If your matrix is a 2D array (i.e. contiguous elements) you can also take the following shortcut using <algorithm>:
copy (reinterpret_cast<int*>(matrix), reinterpret_cast<int*>(matrix)+elements, x.begin());
Try this:
unsigned int destination_index = 0;
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
x[destination_index++]=matrix[i][j];
}
}
The destination index is incremented after each assignment to a new slot.
No need for a 3rd loop.
It is enough to use two loops.
For example
srand((int)time(0));
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
matrix[i][j]= -10 + rand() % 21;
x[i * columnsize + j] = matrix[i][j];
}
}
In general if you have a two-dimensional array and want to copy nRows and nCols of each row elements in a vector then you can use standard algorithm std::copy declared in header <algorithm>
For example
auto it = x.begin();
for ( int i = 0; i < nRows; i++ )
{
it = std::copy( matrix[i], matrix[i] + nCols, it );
}
I'm trying to design a program that creates a matrix using vectors of vectors of integers, and then multiplyies it with another matrix. I know how to multiply matrices on paper, but when I try to implement it in my program, I'm not getting it to work. I know that both matrices are entered correctly and are passed correctly as I have the the output of those functions so that I can debug. The program works incorrectly when I try to multiply them. The answer and the number of elements are not right. I know I'm missing something but can't figure out what.
Matrix Matrix::operator*(Matrix m){
vector<int> mRow = m.getRow(0);
vector<int> mCol = m.getCol(0);
vector<int> newElem;
int product = 0;
//adds the contents of the 2nd matrix to the 2d vector
vector< vector<int> > m2(mRow.size(), vector<int>(mCol.size()));
for (int i = 0; i < mRow.size(); i++){
mRow.clear();
mRow = m.getRow(i);
for (int j = 0; j < mCol.size(); j++){
m2[j][i] = mRow[j];
}
}
//Multiplies the matrices using the 2d matrix**THIS IS WHERE IT GOES WRONG**
for (int i = 0; i < row; i++){
for (int j = 0; j < column; j++){
product += matrix[i][j]*m2[j][i];
}
newElem.insert(newElem.begin()+i,product);
product = 0;
}
//displays the products so that i can see if its working
for (int i = 0; i < newElem.size(); i++){
cout << " "<<newElem[i]<<endl;
}
//adds the new product vector to a new Matrix object and returns it
Matrix newM(row, mCol.size());
vector<int> temp;
for (int i = 0; i < row; i++){
for (int j = 0; j < mCol.size(); j++){
temp.insert(temp.begin()+j, newElem[0]);
newElem.erase(newElem.begin());
}
newM.setRow(temp,i);
temp.clear();
}
return newM;
}
Although I don't know whether this helps, I'm using this site as a reference for multiplying 2 matrices together.
Your matrix representation has nothing to do with your mistake. You need to have more nested iterations. Think of a result matrix and iterate through that to calculate it's every element. In a pseudocode:
for i in result column
for j in result row
res[i, j] = multiply(m1, m2, i, j)
where multiply function is the nested loop, something like this:
multiply(m1, m2, i, j)
{
val = 0;
for k in row
val += m1[i, k] * m2[k, j]
return val
}
Here is an implementation of the outer loops. Mind you, there are no error checking in the code.
vector<vector<int> > ml;
vector<vector<int> > mr;
// fill in ml and mr
...
// result matrix
vector<vector<int> > res;
// allocate the result matrix
res.resize(ml.size());
for( it = res.begin(); it != res.end(); ++it)
it->resize(ml[0].size());
// loop through the result matrix and fill it in
for( int i = 0; i < res.size(); ++i)
for( int j = 0; j < res[0].size(); ++j)
res[i][j] = multiply(ml, mr, i, j);
Leaving a proper implementation of multiply() function to you.
I have a problem, I am making a RPG game with C++, and here is my problem:
I have a 1D vector that contains "gid" elements of tiles in my game, like this picture:
This 1D vector contains 400 elements (my map is 20x20), and I want to convert it to a 2D vector, so I can then create a grid of tiles...
I have tried this:
map_floor2D.resize(map_floor.size(), map_floor);
for (int i = 0; i < map_floor2D.size(); i++)
{
for (int j = 0; j < map_floor2D[i].size(); i++)
{
cout << map_floor2D[i][j];
}
}
map_floor is the 1D vector.
map_floor2D is the 2D vector
How can I do that?
vector<int> map_floor1D;
vector<vector< int> > map_floor2D;
map_floor2D.resize(20);
for (int i = 0; i < 20; i++)
{
map_floor2D[i].resize(20);
}
for (int i = 0; i < map_floor1D.size(); i++)
{
int row = i / 20;
int col = i %20;
map_floor2D[row][col] = map_floor1D[i];
}
I wouldn't do any conversion at all. Just create a 2D view over the 1D data:
const int WIDTH = 16;
const int x = 5; // 5 across
const int y = 6; // 6 down
cout << map_floor[y*WIDTH + x];