I am trying to create triangular grid with sorted triangles in OpenGL. I have vertices buffer and indices buffer. I was partialy succesfull, but one half of grid is rendering wrong as you can see on screenshot. I cant figure out why is that.
My code is here
float[] vertices = new float[2 * rows * columns];
int counter = 0;
for(int r = 0; r <rows; r++){
for(int c = 0; c < columns; c++){
vertices[counter ++] = (float)r / (rows-1);
vertices[counter ++] = (float)c / (columns -1);
}
}
int[] indices = new int[4 * (rows) * (columns)];
int counter = 0;
for(int r = 0; r < rows; r++){
for(int c =0; c <= columns; c++){
if(r % 2 == 0){
if(c == columns){
indices[counter ++] = (c-1) + (r+1)*columns;
indices[counter ++] = (c-1) + (r+1)*columns;
}else{
indices[counter ++] = c + r * columns;
indices[counter ++] = c + (r+1) * columns;
}
}else{
if(c == columns){
indices[counter ++] = (columns) - c + (r +1) * columns;
indices[counter ++] = (columns) - c + (r +1) * columns;
}else{
indices[counter ++] = (columns - 1) - c + (r + 1) * columns;
indices[counter ++] = r*columns + (columns-1) - c;
}
}
}
}
for (int r = 0; r < rows - 1; r++) { is what you actually want.
You are using (r+1) rows while looping from r = 0 to r = (rows - 1), effectively ending up in a non-existent row filled with zeroes.
So this is not a «half of the grid», it`s just the final row of triangles.
And BTW, 4 * rows * columns is too much for a list of triangle strip indices with 2 additional degenerate triangles between strips; 2 * (columns + 1) * (rows - 1) shall be enough.
Related
Dear nice and smart people, would you mind sharing with me why my code is unable to swap rows for a matrix please? When I run the code, both rows become the same, omg.
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 = number of rows in matrix
m = number of columns in matrix
void Matrix::SwapRows(int i, int j) {
double* temp;
temp = new double[n * m];
double* temp2;
temp2 = new double[n * m];
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= m; b++) {
if (a == i) {
temp[(j - 1) * m + b - 1] = entries[(j - 1) * m + b - 1];
entries[(a - 1) * m + b - 1] = temp[(j - 1) * m + b - 1];
}
if (a == j) {
temp2[(i - 1) * m + b - 1] = entries[(i - 1) * m + b - 1];
entries[(a - 1) * m + b - 1] = temp2[(i - 1) * m + b - 1];
}
}
}
delete temp;
delete temp2;
}
THanx to Jesper Juhl, swap does the trick. Correct method is as per below. Thank you Jesper!
void Matrix::SwapRows(int i, int j) {
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= m; b++) {
if (a == i) {
swap (entries[(a - 1) * m + b - 1], entries[(j - 1) * m + b - 1]);
}
}
}
}
my codes does not work for Gauss Elimination for Matrix. The core code is ok, but it seems to be missing some final touch which I honestly dont know. Would be great if someone can point out the mistake.
Basically when I input a square 3x3 Matrix filled with 3s, I get back (3, 3, 3, 0, -3, -3, 0, 0, 3) but it should be (3, 3, 3, 0, 0, 0, 0, 0, 0)
n is number of rows of matrix and m is number of columns.
All elements of matrix are stored in a SINGLE DIMENSION array called entries[i]
My code below for GaussElimination basically starts with placing the row with the largest first element on the top row. Then after that I just delete the elements right below the top elements.
Matrix Matrix::GaussElim() const {
double maxEle;
int maxRow;
for (int i = 1; i <= m; i++) {
maxEle = fabs(entries[i-1]);
maxRow = i;
for (int k = i+1; k <= m; k++) {
if (fabs(entries[(k - 1) * n + i - 1]) > maxEle) {
maxEle = entries[(k - 1) * n + i - 1];
maxRow = k;
}
}
for (int a = 1; a <= m; a++) {
swap(entries[(i - 1) * m + a - 1], entries[(maxRow - 1) * m + a - 1]);
}
for (int b = i + 1; b <= n; b++) {
double c = -(entries[(b - 1) * m + i - 1]) / entries[(i - 1) * m + i - 1];
for (int d = i; d <= n; d++) {
if (i == d) {
entries[(b - 1) * m + d - 1] = 0;
}
else {
entries[(b - 1) * m + d - 1] = c * entries[(i - 1) * m + d - 1];
}
}
}
}
Matrix Result(n, m, entries);
return Result;
}
For starters, I'd suggest to drop the habit of starting the loops at 1 instead of the more idiomatic 0, it would simplify all of the formulas.
That said, this statement
else {
entries[(b - 1) * m + d - 1] = c * entries[(i - 1) * m + d - 1];
// ^^^
}
Looks suspicious. There should be a += (or a -=, depending on how you choose the sign of the pivot).
Another source of unexpected results is the way chosen to calculate the constant c:
double c = -(entries[(b - 1) * m + i - 1]) / entries[(i - 1) * m + i - 1];
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Even in case of partial pivoting, that value could be zero (or too small), due to the nature of the starting matrix, like in the posted example, or to numerical errors. In those cases, it would be preferable to just zero out all the remaining elements of the matrix.
I overloaded operator * which multiplying 2D arrays. I have some problems with multiplying, don't understand exactly an indexes when I am multiplying.
Here's some declarations:
int *const e; //pointer to the memory storing all integer elements of A
const int row, column; //r and c are the numbers of rows and columns respectively
And some code:
A A::operator*(const A& matrix)const
{
MAT result(matrix.row, matrix.column);
if (column == matrix.row)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < matrix.column; j++)
{
result.e[j*row + i] = 0;
for (int k = 0; k < column; k++)
{
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
}
}
}
}
return result;
}
I know that I need 3 loops, I think I have some problems in
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
Do you have any clue ? You can write me some ideas how can I figure out it myself, because I want to understand it. Thanks
Your line
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + column];
is broken. The product P of two matrices A (dim M,N) and B (dim N,P) has it's coefficient in position (i,j) defined by the following :
Pi,j = sum(k = 1..N, ai,k . bk,j).
Thus the line mentioned above should be :
result.e[j*row + i] += e[j*row + k] * matrix.e[k*row + i];
I am building a game of life CA in C++ (openFrameworks). As I am new to C++ I was wondering if someone could let me know if I am setting up the vectors correctly in the following code. the CA does not draw to the screen and I am not sure if this is as a result of how I set up the vectors. I have to use 1D vectors as I intend to send data to Pure Data which only handles 1D structures.
GOL::GOL() {
init();
}
void GOL::init() {
for (int i =1;i < cols-1;i++) {
for (int j =1;j < rows-1;j++) {
board.push_back(rows * cols);
board[i * cols + j] = ofRandom(2);
}
}
}
void GOL::generate() {
vector<int> next(rows * cols);
// Loop through every spot in our 2D array and check spots neighbors
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
// Add up all the states in a 3x3 surrounding grid
int neighbors = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
neighbors += board[((x+i+cols)%cols) * cols + ((y+j+rows)%rows)];
}
}
// A little trick to subtract the current cell's state since
// we added it in the above loop
neighbors -= board[x * cols + y];
// Rules of Life
if ((board[x * cols + y] == 1) && (neighbors < 2)) next[x * cols + y] = 0; // Loneliness
else if ((board[x * cols + y] == 1) && (neighbors > 3)) next[x * cols + y] = 0; // Overpopulation
else if ((board[x * cols + y] == 0) && (neighbors == 3)) next[x * cols + y] = 1; // Reproduction
else next[x * cols + y] = board[x * cols + y]; // Stasis
}
}
// Next is now our board
board = next;
}
this looks weird in your code:
void GOL::init() {
for (int i =1;i < cols-1;i++) {
for (int j =1;j < rows-1;j++) {
board.push_back(rows * cols);
board[i * cols + j] = ofRandom(2);
}
}
}
"vector.push_back( value )" means "append value to the end of this vector" see std::vector::push_back reference
After doing this, you access the value of board[i * cols + j] and change it into a random value. What I think you are trying to do is:
void GOL::init() {
// create the vector with cols * rows spaces:
for(int i = 0; i < cols * rows; i++){
board.push_back( ofRandom(2));
}
}
This is how you would access every element at position x,y in your vector:
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
board[x * cols + y] = blabla;
}
}
This means that in void GOL::generate() you are not accessing the right position when you do this:
neighbors += board[((x+i+cols)%cols) * cols + ((y+j+rows)%rows)];
I think you want to do this:
neighbors += board[((x+i+cols)%cols) * rows + ((y+j+rows)%rows)];
so x * rows + y instead of x * cols + y
I wrote the following, but I'm not understanding it after modifying it some to fit with single pixels (graphic displays) instead of single characters (character displays).
XRES x YRES is the pixel resolution of each character. LCDGraphic draws its own characters based on these values. The idea in this transition algorithm is that you can go right, left, or (both) right one line, left the next line, then right, etc... The text version works like it's supposed to, but when I translated it for graphic displays, it's acting weird.
LCOLS is 256 (the sentinal), and transition_tick_ increments till this sentinel each time LCDGraphic::Transition() is executed. col can thus be in the range between 0-255. Well, when pixels are going left and right, they're supposed to be moving together. However, for some reason the lines going right move till they're finished, then the lines moving left move till they're finished. It appears that where col is < 128 the left moving lines are adjusting, then when col is >= 128 the right moving lines adjust. I'm pretty well confused by this.
void LCDGraphic::Transition() {
int direction = visitor_->GetDirection();
int col;
transitioning_ = true;
for(unsigned int row = 0; row < LROWS / YRES; row++) {
if( direction == TRANSITION_LEFT ||
(direction == TRANSITION_BOTH && row % 2 == 0))
col = LCOLS - transition_tick_;
else if( direction == TRANSITION_RIGHT || direction == TRANSITION_BOTH)
col = transition_tick_;
else
col = 0;
if(col < 0)
col = 0;
for(unsigned int i = 0; i < YRES; i++) {
int n = row * YRES * LCOLS + i * LCOLS;
for(unsigned int l = 0; l < 1; l++) {// LAYERS; l++) {
RGBA tmp[LCOLS];
memcpy(tmp + XRES, GraphicFB[l] + n + col + XRES, (LCOLS - col) * sizeof(RGBA));
for(unsigned j = 0; j < XRES; j++)
tmp[j] = NO_COL;
memcpy(GraphicFB[l] + n + col, tmp, sizeof(RGBA) * (LCOLS - col));
}
}
}
transition_tick_+=XRES;
if( transition_tick_ >= (int)LCOLS ) {
transitioning_ = false;
transition_tick_ = 0;
emit static_cast<LCDEvents *>(
visitor_->GetWrapper())->_TransitionFinished();
}
GraphicBlit(0, 0, LROWS, LCOLS);
}
I figured it out. Just half LCOLS. Odd problem though. I'm still a bit confused.
void LCDGraphic::Transition() {
int direction = visitor_->GetDirection();
int col;
transitioning_ = true;
for(unsigned int row = 0; row < LROWS / YRES; row++) {
if( direction == TRANSITION_LEFT ||
(direction == TRANSITION_BOTH && row % 2 == 0))
col = LCOLS / 2 - transition_tick_; // changed this line
else if( direction == TRANSITION_RIGHT || direction == TRANSITION_BOTH)
col = transition_tick_;
else
col = 0;
if(col < 0)
col = 0;
for(unsigned int i = 0; i < YRES; i++) {
int n = row * YRES * LCOLS + i * LCOLS;
for(unsigned int l = 0; l < 1; l++) {// LAYERS; l++) {
RGBA tmp[LCOLS];
LCDError("Transition: LROWS: %u, LCOLS: %u, n: %d, row: %d, col: %d, calc1: %d, calc2: %d, fb: %p, tmp: %p",
LROWS, LCOLS, n, row, col, n + col + XRES, (LCOLS - col) * sizeof(RGBA), GraphicFB, tmp);
memcpy(tmp + XRES, GraphicFB[l] + n + col + XRES, (LCOLS - col) * sizeof(RGBA));
for(unsigned j = 0; j < XRES; j++)
tmp[j] = NO_COL;
memcpy(GraphicFB[l] + n + col, tmp, sizeof(RGBA) * (LCOLS - col));
}
}
}
transition_tick_+=XRES;
if( transition_tick_ >= (int)LCOLS / 2) { //changed this line
transitioning_ = false;
transition_tick_ = 0;
emit static_cast<LCDEvents *>(
visitor_->GetWrapper())->_TransitionFinished();
}
GraphicBlit(0, 0, LROWS, LCOLS);
}