I am new to OpenGL as learning exercise I decided to draw a set of horizontal lines from a grid of m x n matrix containing the vertices locations
This is what I have
and If I use LINE_STRIP
A code snippet using vertex arrays and indices will be great, I cant seem to be able to get the concept just from a text book I need to see and play with a code example
Any help will be much appreciated!
#Thomas
Got it working with the following code
totalPoints = GRID_ROWS * 2 * (GRID_COLUMNS - 1);
indices = new int[totalPoints];
points = new GLModel(this, totalPoints, LINES, GLModel.DYNAMIC);
int n = 0;
points.beginUpdateVertices();
for ( int row = 0; row < GRID_ROWS; row++ ) {
for ( int col = 0; col < GRID_COLUMNS - 1; col++ ) {
int rowoffset = row * GRID_COLUMNS;
int n0 = rowoffset + col;
int n1 = rowoffset + col + 1;
points.updateVertex( n, pointsPos[n0].x, pointsPos[n0].y, pointsPos[n0].z );
indices[n] = n0;
n++;
points.updateVertex( n, pointsPos[n1].x, pointsPos[n1].y, pointsPos[n1].z );
indices[n] = n1;
n++;
}
}
points.endUpdateVertices();
Then I update and draw by doing
points.beginUpdateVertices();
for ( int n = 0; n < totalPoints; n++ ) {
points.updateVertex( n, pointsPos[indices[n]].x, pointsPos[indices[n]].y, pointsPos[indices[n]].z );
}
points.endUpdateVertices();
This is the result
Fix it by changing the nested for loop
for ( int col = 0; col < GRID_COLUMNS; col++ ) {
for ( int row = 0; row < GRID_ROWS - 1; row++ ) {
int offset = col * GRID_ROWS;
int n0 = offset + row;
int n1 = offset + row + 1;
indices[n++] = n0;
indices[n++] = n1;
}
}
Now I can have any number of rows and columns
Thanks agin!
You need to draw a line for each segment and resuse an index, i.e. for the first part you'd draw a line for (0,1), (1,2), (2,3) and so on.
Edit:
Suppose you have a 4x5 array (4 lines, 5 vertices per line). You could then calculate the indices like this (pseudo code):
Vertex[] v = new Vertex[20]; // 20 vertices in the grid
for(int row = 0; row < numrows; row++) // numrows = 4
{
int rowoffset = row * numcols ; //0, 4, 8, 12
for(int col = 0; col < (numcols - 1); col++) //numcols = 5
{
addLineIndices(rowoffset + col, rowoffset + col +1); //adds (0,1), (1,2), (2,3) and (3, 4) for the first row
}
}
Then issue the draw call for numrows * (numcols - 1) linesegments (GL_LINES), i.e. 16 in the example. Note that addLineIndices would be a function that adds the index pair for one line segment to an index array which is then supplied to the draw call.
Related
i have a matrix and I want to sum all content on the array from one point to another of the matrix, so in other words it might be that in row 1 i want to start to sum from col2 then sume row1 and row2 completely and then on row3 only until the position on number2
so leet me give you an example
class Lab {
public static void main(string[] args) {
int [][] scores = {{ 2, 8, 3, 2, 6 },
{ 3, 2, 8, 1, 0 },
{ 6, 9, 6, 3, 4 },
{ 5, 4, 2, 4, 5 }};
outputArray(scores);
}
public int sumRow(int[][] matrix, int row)
{
int sum = 0;
startrow = scores[1][]
lastrow =scores[3][]
startcol =scores[][2]
lastcol = scores[][2]
for(int i = startrow; i==lastrow;i++){
for (int j=startcol ; j==lastcol;j++) {
sum += scores[i][j];
return sum;
}
basically the sum of
row 1 -> 8, 1, 0
row 2 -> 6, 9, 6, 3, 4
row 3 -> 5, 4, 2
but done in one for loop (or any other method you think will be best to do so)
not sure if it can be done at once or if its needed to go row by row and then sum all the rows?
thanks!
The sales by month, in my opinion, greatly clarifies what you want to do.
To accomplish that, the sum method should have parameters to specify the row and column of the first cell, and row and column of the last cell to be summed.
You might try something like this:
public static int sumRange ( int matrix[][]
, int startRow, int startCol
, int endRow , int endCol ) {
int sum = 0;
int colIdx, rowIdx;
// add elements at end of first row
for (colIdx = startCol; colIdx < matrix [0].length; colIdx++) {
sum += matrix [startRow][colIdx];
}
// add elements of "in-between" rows, if any
for (rowIdx = startRow + 1; rowIdx < endRow; rowIdx++) {
for (colIdx = 0; colIdx < matrix [rowIdx].length; colIdx++) {
sum += matrix [rowIdx][colIdx];
}
}
// add elements at start of last row
for (colIdx = 0; colIdx <= endCol; colIdx++) {
sum += matrix [endRow][colIdx];
}
return sum;
}
The above uses 4 for loops, but is straightforward -- almost.
You could do it with a pair of nested for loops, but with an if that has several tests.
public static int sumRange ( int matrix[][]
, int startRow, int startCol
, int endRow , int endCol ) {
int sum = 0;
for (int rowIdx = startRow; rowIdx <= endRow; rowIdx++) {
for (int colIdx = 0; colIdx < matrix[rowIdx].length;colIdx++) {
if ( rowIdx == startRow && colIdx >= startCol
|| rowIdx == endRow && colIdx <= endCol
|| rowIdx > startRow && rowIdx < endRow ) {
sum += matrix [rowIdx][colIdx];
}
}
}
return sum;
}
Is it possible to do it with one for loop? It is.
public static int sumRange ( int matrix[][]
, int startRow, int startCol
, int endRow , int endCol ) {
int sum = 0;
int len = matrix[0].length;
for ( int idx = len * startRow + startCol ;
idx <= len * endRow + endCol ;
idx++ ) {
sum += matrix [idx / len] [idx % len];
}
return sum;
}
There are preconditons:
All rows in matrix have the same length.
The values for startRow, endRow, startCol, endCol are valid when used as row and column indices for the matrix parameter.
In the first two examples, startRow < endRow.
In the third example, startRow <= endRow . If startRow == endRow, then startCol < endCol.
Note the 2nd precondition implies the first two examples won't work when startRow == endRow. To fix the bug, precede the first for loop with an if statement to check for that, a for loop to sum the proper columns, and a return statement.
Because, in your example, the matrix was included as a parameter, and there was no use of instance variables, I made the methods static in these examples. If the matrix the method is supposed to use is an instance variable, remove int matrix [][] from the parameter list, and remove static from the method header.
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 years ago.
Improve this question
Write a method Picture emboss to add an emboss style effect to a picture by applying the following kernel.
| -2 -1 0 |
| -1 1 1 |
| 0 1 2 |
(it is a 3*3 matrix)
When applying a kernel filter to a pixel near the boundary, some of its neighboring pixels may not exist. In such cases, assume the leftmost column wraps around to the rightmost column, and vice versa; and the top row wraps around to the bottom row, and vice versa.
Below is part of my code, but I find that the picture I get is all black. I only have a limited knowledge of java. So after checking for some time, I still can not find the error.
public static Picture emboss(Picture picture) {
int width= picture.width();
int height= picture.height();
int[][] matrix1 = new int[height][width];
int[][] matrix2 = new int[height][width];
int[][] matrix3 = new int[height][width];
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++){
Color color = picture.getColor(col, row);
matrix1[row][col] = color.getRed();
matrix2[row][col] = color.getGreen();
matrix3[row][col] = color.getBlue();
int a = row-1;
int b = col-1;
int c = row+1;
int d = col+1;
if (a < 0) {
a = height-1;
}
if (b < 0) {
b = width-1;
}
if (c > height-1) {
c = 0;
}
if ( d > width-1 ) {
d = 0;
}
int GR = -2 * matrix1[a][b] - matrix1[row][b] - matrix1[a][col] + matrix1[row][col] + matrix1[c][col] + matrix1[row][d] + 2*matrix1[c][d];
int GG = -2 * matrix2[a][b] - matrix2[row][b] - matrix2[a][col] + matrix2[row][col] + matrix2[c][col] + matrix2[row][d] + 2*matrix2[c][d];
int GB = -2 * matrix3[a][b] - matrix3[row][b] - matrix3[a][col] + matrix3[row][col] + matrix3[c][col] + matrix3[row][d] + 2*matrix3[c][d];
if (GR < 0) {
GR=0;
}
if( GR>255 ) {
GR=255;
}
if ( GG<0 ) {
GG=0;
}
if( GG>255 ) {
GG=255;
}
if ( GB<0 ) {
GB=0;
}
if ( GB>255 ) {
GB=255;
}
Color newColor= new Color(GR,GG,GB);
picture.setColor(col,row,newColor);
}
}
return picture;
}
When you create a matrix like this
int[][] matrix1 = new int[height][width];
It is by default filled with 0s.
Look at when you actually give the matrix a value. in the first iteration of the for loops, everything is black. You start by setting the current pixel:
matrix1[row][col] = color.getRed();
But all the neighbours are still black. When you move in the iterations, all pixels that have not been computed yet are black and you include them in the computation when you use the neighbours.
You should start by an iteration just to fill these three matrices, followed by another iteration for the computation:
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++){
Color color = picture.getColor(col, row);
matrix1[row][col] = color.getRed();
matrix2[row][col] = color.getGreen();
matrix3[row][col] = color.getBlue();
}
}
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++){
int a = row-1;
int b = col-1;
[...] // The rest of the code goes here
}
}
I am trying to store all of the values in the matrix from the top right to the bottom left and store them in an array.
int matrixSample [][] = {
{6,4,1,4},
{7,5,4,4},
{4,4,8,3},
{4,4,8,3}
};
The output should be
[4,1,4,4,4,3,6,5,8,3,7,4,8,4,4,4]
I can get the bottom right diagonal
static int[] getAllDiagonalsInMatrix(int matrix[][]){
// Sum of arithmetic progression
int diagonal[] = new int[matrix.length * (matrix.length + 1)*2];
int index = 0;
for(int row = 0; row < matrix.length; row++) {
for(int col = 0; col < matrix[row].length - row; col++) {
diagonal[index++] = matrix[row + col][col];
}
}
return diagonal;
}
Is this even possible to do using the same two loops by adjustments made in the loops above?
Okay, here is my thought process on your problem. However, I'm going to print values instead of collecting them to make it a little easier on me and keep the solution easy to read.
First, how do you get a diagonal? We need to do this frequently so lets start by making a function for that. Maybe we could pass in the top left corner of the diagonal and go from there.
public void getDiagonal(int[][] array, int row, int col) {
// While row and col are within the bounds of the array
while (row < array.length && col < array[row].length) {
// Print element in diagonal
System.out.println(array[row][col]);
// Diagonal moves from top-left to bottom-right
row++;
col++;
}
}
Now that we have a function to get a diagonal, we just need a way to call it. Essentially, we just need to follow an L shape going from the top-right to the top-left to the bottom-left.
// Get diagonals starting in the first row with a column > 0
for (int col = array.length - 1; col > 0; col--) {
getDiagonal(array, 0, col);
}
// Get all diagonals starting from the left most column
for (int row = 0; row < array.length; row++) {
getDiagonal(array, row, 0);
}
Now that we have a working way to iterate through the values, we can rewrite it to save the values into an array instead. You could also choose to remove the function entirely now that you have a process.
Edit: I almost forgot, but the mathematical solution you were looking for is as follows.
for (int row = 0; row < array.length; row++) {
for (int col = 0; col < array.length; col++) {
// Index along diagonal
int diagonal = Math.min(row, col);
// Which part of L contains value
if (col >= row) {
int start = array.length - 1 - (col - row);
int passed = start * (start + 1) / 2;
solution[passed + diagonal] = array[row][col];
} else {
int start = array.length - 1 - (row - col);
int passed = array.length * array.length - 1 - start * (start + 1) / 2; solution[passed - array.length + 1 + row] = array[row][col];
}
}
}
One solution is to iterate through a matrix where you consider positions outside of the matrix, but exclude every index out of bounds.
static int[] getDiagonals(int[][] mat) {
int diagonal[] = new int[mat.length * (mat[0].length)];
int index = 0;
int yStart = -mat[0].length;
for (int y = yStart; y < mat.length; y++) {
for (int x = 0; x < mat[0].length; x++) {
if (y + x >= 0 && y + x < mat.length) {
diagonal[index++] = mat[y+x][x];
}
}
}
return diagonal;
}
Might not be optimal as you are effectively traversing a matrix nearly twice the size, but it is pretty intuitive.
i want to write a code that makes a specific numbers in the loop .
for example generate numbers like this :
column 1 - row 1
column 1 - row 2
column 1 - row 3
and then generate this ( for example):
column 2 - row 1
column 2 - row 2
column 2 - row 3
column 2 - row 4
is there any way to write this Algorithm ? thank you so much
code , i have a code like this but i want to manage it :
boolean[][] mapEq = new boolean[mapWidth][mapHeight];
int free = mapWidth * mapHeight;
int randomFree = ((int) (free * Math.random()));
int x = 0, y = 0;
for (int i = 0, k = 0; i < mapWidth; i++) {
for (int j = 0; j < mapHeight; j++) {
if (!mapEq[i][j]) {
if (k == randomFree) {
x = i;
y = j;
break SearchRandom;
} else {
k++;
}
}
}
}
it creat a random thing but i want to make a specific number for example
for column 1 - row 1 and row 2 and row 3
and for column 2 - row 1 and row 2 and row 3 and row 4
Maybe something like this?
int[] columnLengths = {3, 4}; // Lengths of the columns
for(int i = 0; i < columnLengths.length; i++) { // Loop the columns
for(int j = 0; j < columnLengths[j]; j++) { // Loop the rows
System.out.println("column " + i + " - row " + j);
}
}
I am really not sure what you are trying to make, but this is what I understood.
The task is following:
a square matrix A of order M is given. Starting with the element A0,0 and moving clockwise, you should output all its elements in a spiral: the first row, the last column, the last row in reverse order, the first column in reverse order, the remaining elements of the second row and so on.
public class Pres10Task8 {
public static void main(String[] args) {
int m =4;
int [][] a=new int [m][m];
Random rand = new Random();
for(int i =0;i<a.length;i++){
for(int j =0;j<a[i].length;j++){
a[i][j]=rand.nextInt(100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
for(int k=0;k<m/2+1;k++){
for(int j = k; j<m+1-k;j++){
System.out.println(a[k][j]);
}
int j =m+1-k;
for(int i=k+1;i<m+1-k;i++){
System.out.println(a[i][j]);
}
for(int j=m-k;j>k;j--){
j =k ;
System.out.println(a[i][j]);
}
for(int i =m-k;i>k+1;i-- ){
i =m+1-k;
System.out.println(a[i][j]);
}
}
}
}
Would you be so kind to look through my code and say what is wrong with it? How should I rewrite my code in order to get the right output?
You couldn't use a variable in your loop already exist before your method :
int j = m + 1 - k;
// ^--------------------------------------Already exist
for (int i = k + 1; i < m + 1 - k; i++) {
System.out.println(a[i][j]);
}
for (int j = m - k; j > k; j--) {
// ^---------You can't declare a variable already exist,
//you can just use it or initialize it
So instead use this without int j:
for (j = m - k; j > k; j--) {
Second
System.out.println(a[i][j]);
// ^-----The i is not exist so you have to
//create it and inisialize it so you can use it
You have made many mistakes as YCF_L mentioned in the answer and also After solving few of them I was still getting other errors. You can solve this problem by a simple logic that Divide Square Matrix into smaller squares and then follow the same pattern to print each of the squares.
For Example,
Suppose I have a matrix of order 5 then we can have 3 squares here for distinct dimensions.
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
Here each number represents that to which square the element belongs.So all outer elements belongs to first square then the next layer's elements belongs to second square and so on.
Now you have made your problem easier by dividing it into smaller sub-problems which can be solved in same way. Now you need to make logic of print the elements of each of the squares.
So for this, Consider the most outer square.
1 1 1 1 1 1 2 3 4 5
1 1 Thier Printing Order 16 6
1 1 ================> 15 7
1 1 14 8
1 1 1 1 1 13 12 11 10 9
So notice that we start from the first element and move into the same row into the right direction.
Then move in same column into down direction.
Then again in the same row in left direction.
At last in the same column but in the up direction.
After printing the outer square move to the inner square and do the same for each of the squares.
Code for the same:
import java.util.Scanner;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int m =4;
int [][] a=new int [m][m];
Random rand = new Random();
for(int i =0;i<a.length;i++){
for(int j =0;j<a[i].length;j++){
a[i][j]=rand.nextInt(100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
int squares=m/2; //Calculating total number of squares
for(int i=0;i<squares;i++)
{
int low=i; //Set the dimension of the square
int high=m-i-1;
for(int j=low;j<=high;j++) //First Row --> (Right Direction)
System.out.println(a[low][j]);
for(int j=low+1;j<=high;j++) //Last Column --> (Down Direction)
System.out.println(a[j][high]);
for(int j=high-1;j>=low;j--) //Last Row --> (Left Direction)
System.out.println(a[high][j]);
for(int j=high-1;j>low;j--) //First Column --> (Up Direction)
System.out.println(a[j][low]);
}
if(m%2==1) //If Matrix is of odd order then print the middle element.
System.out.println(a[mid][mid]);
}
}
Why you use jagged array [][] instead of 2-dimensional [,] ???
May give a simple sample:
public void CountDiag(int size)
{
// initialize straight order
int[,] ar2 = new int[size, size];
int count = 0;
// initialize spiral way
int y = 0;
int x = 0;
int top = 0;
int bot = ar2.GetLength(0)-1;
int left = 0;
int right = ar2.GetLength(1)-1;
do
{
//topleft to right
for (; y < right; y++)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
right--;
//topright to bottom
for (; x < bot; x++)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
top++;
//botright to left
for (; y > left; y--)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
left++;
//botleft to top
for (; x > top; x--)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
bot--;
} while (count < ar2.Length-1);
}
AND you print it out like this:
public void PrintArray(int[,] array)
{
int n = (array.GetLength(0) * array.GetLength(1) - 1).ToString().Length + 1; // for padding
for (int i = 0; i < array.GetLength(0); i++) // 0 - length rows
{
for (int j = 0; j < array.GetLength(1); j++) // 1 length columns
{
Console.Write(array[i, j].ToString().PadLeft(n, ' '));
}
Console.WriteLine();
}
Console.ReadLine();
}