We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › drawing a grid with vertices
Page Index Toggle Pages: 1
drawing a grid with vertices (Read 473 times)
drawing a grid with vertices
Feb 15th, 2009, 8:34pm
 
I am trying to draw a grid using vertices however the code below doesn't seem to connect all the vertices as I want.
does anyone know how i can create a grid without the diagonal lines appearing at the end of each row?

void setup(){
 size(600,600);
 ellipseMode(CENTER);
}
void draw(){
 background(0);
 stroke(255);
 strokeWeight (2);
 noFill();
 beginShape();
 noFill();
 // verticle lines
 for (int i=1; i<10;i++){
   for (int j=1; j<10;j++){
     vertex(i*60, j*60);      
   }
 }
// horizontal lines
 for (int i=1; i<10;i++){
   for (int j=1; j<10;j++){
     vertex(j*60, i*60);
   }
 }
 endShape();
}



Re: drawing a grid with vertices
Reply #1 - Feb 15th, 2009, 9:19pm
 
Mmm, any reason why you use vertices instead of lines?
If you prefer this way, you probably need to endShape, then beginShape, more often.
Re: drawing a grid with vertices
Reply #2 - Feb 15th, 2009, 9:44pm
 
well i wanted to use vertices cos i thought it would be easier to manipulate the vertices later on, but i guess ill just stick to line for now.

Re: drawing a grid with vertices
Reply #3 - Feb 15th, 2009, 10:07pm
 
http://wonderlandlabs.com/terrain_gl_2/applet

I am working on a similar problem. I am using openGL to draw a terrain map. I use a terrain object with a 2d map of floats (normalized), three boundry values for the whole terrain, a color map for height, and a "waterline" to flatten out the floor. (As my terrain map is an actual terrain, this makes sense. for more general use you could set the waterline to zero, or MIN_INT).

Since the heights are an array of values you could manipulate the heights as you would any array; you could also use standard processing 3d lines to connect, instead of the openGL library (or you could use both :) ).

Note the keys are set to recieve input to allow you to "scan around" your data. Its a bit lunky but it works.
Also note that the height (y-axis) in my terrain is set to a very flat value (1/30 of the sum of the sides, or 1/15th the width/height of a square) to make the terrain resemble land; for data analysis you would probably want to use other criteria to scale the height.

I am including only the terrain class in this post for brevity -- check out my site for the complete code base.

Note that much of this code -- smoothing, subdivision, normalizing, etc. isn't critical to use or understand if you are working with real data.
Terrain 3D (the source)
Reply #4 - Feb 15th, 2009, 10:12pm
 
This is the core terrain rendering class (uses openGL), shortened for brevity.

class Terrain_3d
{
 float t_width = 1500;
 float t_height = 500;
 float depth = 1500;
 float[] center = {
   0.0, 500.0, -200.0                };
 float [][] heights; // t_width, depth, t_height
 int width_points = 100;
 int depth_points = 100;
 int rolls = 3; // number of random walks the interpolation makes
 int hydration[][];
 
 
 /**************** colors *****************************/
 
 color ocean_color = color(240, 100, 10);
 color ocean_color_2 = color(210, 100, 33);
 float waterline = 0.5;

 color coast_color = color(0, 50, 15);
 color hills_color = color(30, 50, 45);
 float hills = 0.8;

 color mountains_color = color(60, 50, 75);
 float mountains = 1.2;

 color peaks_color = color(60, 25, 100);
 float peaks = 2;
 
/*********************** constructor ***********************/

 Terrain_3d(int pTWP, int pTDP, float pWidth, float pDepth)
 {
   width_points = pTWP;
   depth_points = pTDP;    

   t_width = pWidth;
   depth = pDepth;
   t_height = (pWidth + pDepth) / 30;

   heights = new float[pTWP][pTDP];
   hydration = new int[pTWP][pTDP];
   
   for (int w = 0; w < pTWP; ++w) for (int d = 0; d < pTDP; ++d)
   {
     heights[w][d] = 0;
     hydration[w][d] = 0;
   }
   
 }
 
 
 // ******************* DIVIDE **********************
 // doubles the terrain's resolution, interpolating the results and smoothing

 Terrain_3d subdivide()
 {
   ...
 }

/****************** height accessors **********************
* "convenience" methods for height access
*/

 void set_height(int w, int d, float height_percent){
   if (w != constrain(w, 0, width_points )) return;
   if (d != constrain(d, 0, depth_points )) return;

   heights[w][d] = height_percent;
 }

 float get_height(int w, int d){
   return heights[w][d];
 }
 
 /************************ render ***************************
  * the basic 3d visualizer method; draws triangles
  */

 void render()
 {
   for (int w = 0; w < width_points - 1; ++w) for (int d = 0; d < depth_points - 1; ++d)
   {
     float water_height = waterline * t_height * -1;
     float[] tri_heights = {
         (get_height(w, d) * t_height * -1),
         (get_height(w + 1, d) * t_height * -1),
         (get_height(w, d+1) * t_height * -1),
         (get_height(w+1, d+1) * t_height * -1)
     };
     
    // if (max(tri_heights) > t_height * waterline * -1) continue;
     //  float v = random(0, 100);
  //   float v = constrain((100 * get_height(w, d)), 25, 100);
   //  fill(map(w, 0, width_points, 0, 360), 100, v);
   fill(terrain_color(tri_heights));
   for (int t = 0; t < tri_heights.length; ++t) tri_heights[t] = min(water_height, tri_heights[t]);
     //   if (heights[w][d] < height/10) continue;
     beginShape(TRIANGLES);
     vertex(
     (w  / float( width_points)) * t_width,  
     tri_heights[0],
     ((d * -1 / float(depth_points)) * depth)
       );
     vertex(
     ((w + 1)  / float( width_points)) * t_width,
     tri_heights[1],
     ((d * -1/ float(depth_points)) * depth)
       );
     vertex(
     (w  / float( width_points)) * t_width,
     tri_heights[2],
     (((d + 1)  * -1/ float(depth_points)) * depth)
       );
     endShape();

     beginShape(TRIANGLES);
     vertex(
     ((w + 1)  / float( width_points)) * t_width,
     tri_heights[1],
     ((d * -1/ float(depth_points)) * depth)
       );
     vertex(
     ((w + 1)  / float( width_points)) * t_width,  
     tri_heights[3],
     (((d + 1) * -1 / float(depth_points)) * depth)
       );
     vertex(
     (w  / float( width_points)) * t_width,
     tri_heights[2],
     (((d + 1)  * -1/ float(depth_points)) * depth)
       );
     endShape();
   }

 }

...
Re: drawing a grid with vertices
Reply #5 - Feb 15th, 2009, 10:19pm
 
The bit that is useful to you is that the heights are kept in their own array; during the render process they are summarized in a smaller array.

Every quadrant is rendered in two seperate triangles, in case (always) the quadrant is not planar.

The entire quadrant is filled with the color of the average height, taken from the terrain_color method.

then the two triangles are drawn, from points (w, d) (w + 1, d) (w, d + 1), and points (w + 1, d), (w + 1, d + 1), (w, d + 1).

You might consider refactoring this with a Point class or float[4][3] if readability is an issue. Cheesy
Re: drawing a grid with vertices
Reply #6 - Feb 15th, 2009, 10:22pm
 
Lastly -- "width" is the x-axis measure;
"depth" is the z-axis measure.

These measures make up the "floor" of the terrain.

"height", the y-axis, is translated to a negative measure for rendering purposes. it is the "value"that the terrain is reflecting.
Re: drawing a grid with vertices
Reply #7 - Feb 16th, 2009, 8:03am
 
in answer to arta's original question: you need to call the beginShape/endShape pair more often. here's my fixed draw function:

void draw(){  
 background(0);  
 stroke(255);
 strokeWeight (2);
 noFill();

 for (int i=1; i<9; ++i) {
   for (int j=1; j<9 ; ++j) {
     beginShape();
     // A
     vertex(j*60, i*60);
     // B
     vertex((j+1)*60, i*60);
     // C
     vertex((j+1)*60, (i+1)*60);
     // D
     vertex(j*60, (i+1)*60);
     // A
     vertex(j*60, i*60);
     endShape();
   }
 }
}

I like to structure my code so that it draws across the screen before it draws down. it's a personal preference and not critical to this code.

for illustration let's imagine we are trying to draw a single square. starting at the top-left corner and labeling the corners (vertices) A,B,C,D in clockwise order:

 A--B
 |  |
 D--C

the default mode of beginShape/endShape is to follow all the vertices defined in between the calls, drawing a line between the previous vertex and the current one. here's an example: to draw the top edge of the square we need to call vertex twice, first with A and then B. nothing special here.

when I add a 3rd vertex (C) I get two lines. one from A->B, and the second from B->C. add a 4th vertex, D, and I get the two lines from before and a third from C->D. finally add vertex A again to draw a line from D->A to complete the square.

those are the 5 vertex calls you see in my code, and I follow the same order around the square as my ASCII art: start at the top left and process clockwise around the square.

hopefully, if my explanation is clear enough you can understand why you were seeing your diagonal lines. you were specifying the vertices correctly but not ending the  shape between each square. so processing would draw a diagonal line from the last vertex of the previous square to that first vertex of the new square. this became apparent when you started the next row or column.

one final point: I had to drop the loop limit to 9 because I draw 'extra' vertices to the right and below (the +1 statements).

hth.
Re: drawing a grid with vertices
Reply #8 - Feb 16th, 2009, 12:11pm
 
thanks guys ill have a look at both suggestions!
Page Index Toggle Pages: 1