Loading...
Logo
Processing Forum

Shapes and Grid

in Programming Questions  •  2 years ago  
Hi All,

I'd like to create grid of shapes - ie. tesselation on the plane of some basic geometric tiles such triangles, quads, and hexagons.

I thought it would be nice to have a unique Class Shape to handle different basic shapes and then replicate them by translations. But I am not sure how to organize data...Let's say I have 3 basic shapes should I have 3 constructor that build the actual shape or should I have additional function for that?

Then the same when I want to create the grid with the basic shape. Another issue is that If, lets say I use pvector to locate points for basic shape, then I dont want to have duplicate points on shape that are next to each other - any idea how to avoid this?

It would great if someone has a very basic sample I can look at to have some ideas how can I start building it. Suggestions?

Replies(19)

Re: Shapes and Grid

2 years ago
Hi
To get the effect I *think* you want, the following came to mind. Here's a drawing showing how you might make irregular quadrilaterals. It could be easily tweaked for more regular shapes and for triangles and hexagons.
 
 
I could quite gladly be distracted with this so let me know if you'd like to follow this route.
string

Re: Shapes and Grid

2 years ago
mhh interesting approach, I used something similar for hexagons but I was trying something different especially because in that way I have extra data to store the invisible grids which was something I was trying to avoid...

Re: Shapes and Grid

2 years ago
Hi
I wasn't nessarily thinking of coding the invisible grid, more keeping it in your mind's eye. You mentioned covering the plane with quadrilaterals, triangles or hexagons and not wanting to store points more than once.
I was thinking that if you have, say, chosenShape = QUADRILATERALS, you know to provide rows of equal numbers of points. Imagining those points in the invisible grid helps me to get what's going on, and might help with the creation and spacing of the points in a for-loop: new pointx[i] = random(i, i+1) * 100 say.
Then if you have chosenShape = TRIANGLES, all you (might) need to do is to adjust the spacing of the rows, and so on.
string

Re: Shapes and Grid

2 years ago
mhh I see - intriguing. So let s say I have a collection of points inside an ArrayList -  how should I define the points (xyz) ? They should be within defined interval values (the invisible grid) ? I can figure out for regular triangles though...I should give it a try in the weekend and let you know!

Re: Shapes and Grid

2 years ago
Ok I gave  a try ... with quads is easy ..but not sure how to control it to get regular trinagles or worse hex...
Another point that is important is that I have to be able to sort all points stored (in this case in an ArrayList) according to basic shape topology - i.e If have quads I have to identfy all collections of 4 points within my points list. The same for triangles (sortable for every 3 points ) and hex (6 points).

I tried with quads and it works fine, though probably the code is getting complicated...especially if want to tweak to get regular triangles...?

Here is how I implemented it - QUADS
Copy code
  1. import processing.opengl.*;



  2. //overall grid spacing
  3. int x,y;
  4. int dx = 50;
  5. int dy = 50;

  6. //  point position within a grid cell
  7. int px,py;
  8. ArrayList <PVector> points = new ArrayList<PVector>();

  9. int n = 7;

  10. void setup() {
  11.   size (400,400,OPENGL);
  12.   background(255);
  13.   smooth();
  14.   noFill();
  15.   x = 25;
  16.   y = 25;

  17.   px = x/2;
  18.   py = y/2;
  19.   // STORE POINTS COORDINATES
  20.   for (int i=1; i<n; i++) {
  21.     for (int j=0; j<n; j++) {
  22.       int k ;

  23.       // y = 25;

  24.       if (j %2 ==0 ) {
  25.         px = x/4;
  26.       } 
  27.       else {
  28.         px = x/2;
  29.       }

  30.       PVector a = new PVector ((px)+(i-1)*x+dx, (py)+j*y+dy);
  31.       points.add(a);


  32.       rect((i-1)*x+dx,j*y+dy, x,y);
  33.     }
  34.   }
  35. }


  36. void draw() {

  37.   for (int i=0; i<points.size(); i++) {
  38.     PVector a =  points.get(i);

  39.     ellipse(a.x,a.y,2,2);
  40.   }


  41.   //DRAW 
  42.   for (int i=1; i<points.size()-n; i++) {

  43.     //SORT POINTS TO DRAW QUADS (I HAVE 1 ARRAYLIST WITH POINTS ORDERED BY COLS)
  44.     int j=i;
  45.     if (j%n ==0) j = i+1;
  46.     //QUADS TOPOLOGY
  47.     PVector a = (PVector) points.get(j-1);
  48.     PVector b = (PVector)points.get(i);
  49.     PVector c = (PVector)points.get(j+(n-1));
  50.     PVector d = (PVector)points.get(i+n);


  51.     stroke(255,0,0);

  52.     // DRAW QUADS
  53.     beginShape(QUADS);

  54.     vertex(a.x,a.y);
  55.     vertex(b.x,b.y);
  56.     vertex(d.x,d.y);
  57.     vertex(c.x,c.y);
  58.     endShape();


  59.   }
  60. }
TRIANGLES
Copy code
  1. import processing.opengl.*;


  2. //overall grid spacing
  3. int x,y;
  4. int dx = 50;
  5. int dy = 50;

  6. //  point position within a grid cell
  7. int px,py;

  8. ArrayList <PVector> points = new ArrayList<PVector>();

  9. int n = 6;

  10. void setup() {
  11.   size (800,400,OPENGL);
  12.   background(255);
  13.   smooth();
  14.   noFill();

  15.  
  16.   y=36;
  17.   x=36;
  18.   py = y/2;
  19.   // STORE POINTS COORDINATES
  20.     for (int i=1; i<n; i++) {
  21.     for (int j=0; j<n; j++) {
  22. int k ;
  23.       
  24.  // y = 25;
  25.       
  26. if (j %2 ==0 ) {
  27.    px = x/4;
  28.    k = i;
  29.   
  30. } else {
  31.    px = x/2;
  32.    k = i-1;
  33.  
  34. }

  35.       PVector a = new PVector ((px)+(k-1)*x+dx, (py)+j*y+dy);
  36.       points.add(a);
  37.    
  38.      
  39.       rect((k-1)*x+dx,j*y+dy, x,y);
  40.     }
  41.   }
  42. }


  43. void draw() {
  44.   

  45.    
  46.      for (int i=0; i<points.size(); i++){
  47.        PVector a =  points.get(i);
  48.      
  49.         ellipse(a.x,a.y,2,2);
  50.      }

  51. //DRAW 
  52.   for (int i=1; i<points.size()-n; i++) {
  53.     
  54.     //SORT POINTS TO DRAW QUADS (I HAVE 1 ARRAYLIST WITH POINTS ORDERED BY COLS)
  55.     int j=i;
  56.     if (j%n ==0 ) j = i+1;
  57.     //TRIANGS TOPOLOGY
  58.     PVector a = (PVector) points.get(j-1);
  59.     PVector b = (PVector)points.get(i+n);
  60.     PVector c = (PVector)points.get(j+(n-1));
  61.    // PVector d = (PVector)points.get(i+n);
  62.     stroke(255,0,0);
  63.     
  64.     // DRAW TRIANGLES
  65.     beginShape(TRIANGLES);
  66.    vertex(a.x,a.y);
  67.    vertex(b.x,b.y);

  68.     vertex(c.x,c.y);
  69.     endShape();


  70.    
  71.   }

  72.  
  73. }

Re: Shapes and Grid

2 years ago
Hi
I've run these and have a couple of questions:
 
• do the results you've produced reflect what you wanted?
 
• if not, I can think of several types of tesselation and wonder which you're looking for
(1) a tesselation of squares or equilateral triangles (which we might call a strictly regular tesselation),
(2) a tesselation of diamonds or isosceles triangles which still follows an underlying grid (a uniformly stretched version of 1)
(3) what you have drawn, where I can tell there's an underlying grid but your shapes are non-uniformly stretched but regular in each row
(4) what I drew in my first answer, where each vertex is within a grid cell, but with no other constraints
(5) what I think of an Escher tesselation, where he's done someting clever with a shape but it still follows an underlying grid
(6) and there's one that's not (strictly) a tesselation at all which you can do only with triangles
 
• from your original post, I wonder if you're planning to press a key or choose at random which shape to use. Obviously, the points for a triangle-based tesselation can be recycled for an hexagonal one, and could probably be tweaked for a quadrilateral one.
 
string
 
BTW, I had a play with blobs inspired by your question, see here.

Re: Shapes and Grid

2 years ago
Hi string,

to answer your questions

a. Results are good just for the quads case - which is probably the easiest one. In my quad sketch there some params to control the invisible cell size (x and y) , the number of rows/cols (n - just assuming they are equal for the moment), and the finally the relative position of vertices within the invisible grid cell (px and py). This is what came to mind to control and implement your idea - don't know if there is a better way to do it. Have a look at image below to understand better what I mean.
so in the case of quads to make it regular or not is a matter to control px and py and make them equal to x/2 and y/2 respectively. To do it quickly I did a conditional statement within the foor loop

Copy code
  1. if (j %2 ==0 ) {
  2.         px = x/2;
  3.       } 
  4.       else {
  5.         px = x/2;
  6.       }

  7.       PVector a = new PVector ((px)+(i-1)*x+dx, (py)+j*y+dy);


b. I in my little project I gonna use as said , all regular tessellation such as Quads, Diamonds, Triangles and Hex.
c. Yes, in my final version shapes will be selected by user input either with  keypressed or possibly GUI.
 
Like in your image for triangles I am struggling to make easily rows of different number of points.
 
I saw your sketch - really nice!!!
 
Best

Re: Shapes and Grid

2 years ago
Hi
Deleted last - here's a better version.
I'm making two triangles each loop:
• when j % 2 == 0, one triangle below the start point, and a second to the right/below
• when j % 2 != 0, one triangle below/left the start point, and a second below
I've consistently found the vertices going clockwise from the start point.
Notice that I've fudged it to use a count of triangles - inelegant but effective.
string
 
Copy code
  1. int numColumns = 8;
    int numRows = 8;
    TriangleShape[]triangleShapes = new TriangleShape[2*numColumns*numRows];
    float triangleWidth, triangleHeight;


    VertexClass[][]vertices = new VertexClass[2*numColumns][numRows];

    int count = 0;


    void setup()
    {
      size(400, 300);
      background(255);
      smooth();
      stroke(0);
     
      triangleWidth = width / (numColumns - 2);
      triangleHeight = height / (numRows - 2);
     
      //populate vertices array with triangles' vertices
      for(int i = 0; i < numColumns; i++)
      {
        for(int j = 0; j < numRows; j++)
        {
          float xpos;
          if(j % 2 == 0) xpos = triangleWidth * i;
          else xpos = triangleWidth * (i - 0.5);
          float ypos = triangleHeight * j;
          vertices[i][j] = new VertexClass(xpos, ypos);
        }
      }
    //}
    //
    //void draw()
    //{
      background(255);
      noStroke();
     


      for(int j = 0; j < numRows - 1; j++)
      {
        if(j % 2 == 0)
        {
          for(int i = 0; i < numColumns - 1; i++)
          {
            vertices[i][j].display();
            //triangle vertices
            float startX = vertices[i][j].x;
            float startY = vertices[i][j].y;
            float rightX = vertices[i+1][j].x;
            float rightY = vertices[i+1][j].y;
            float downRightX = vertices[i+1][j+1].x;
            float downRightY = vertices[i+1][j+1].y;
            float downLeftX = vertices[i][j+1].x;
            float downLeftY = vertices[i][j+1].y;
            triangleShapes[count] = new TriangleShape(startX, startY, downRightX, downRightY, downLeftX, downLeftY, color(random(255)));
            count++;
            triangleShapes[count] = new TriangleShape(startX, startY, rightX, rightY, downRightX, downRightY, color(random(255)));
            count++;
          }
        }
        else
        {
          for(int i = 1; i < numColumns; i++)
          {
            vertices[i][j].display();
            //triangle vertices
            float startX = vertices[i][j].x;
            float startY = vertices[i][j].y;
            float downRightX = vertices[i][j+1].x;
            float downRightY = vertices[i][j+1].y;
            float downLeftX = vertices[i-1][j+1].x;
            float downLeftY = vertices[i-1][j+1].y;
            float leftX = vertices[i-1][j].x;
            float leftY = vertices[i-1][j].y;
            triangleShapes[count] = new TriangleShape(startX, startY, downLeftX, downLeftY, leftX, leftY, color(random(255)));
            count++;
            triangleShapes[count] = new TriangleShape(startX, startY, downRightX, downRightY, downLeftX, downLeftY, color(random(255)));
            count++;
          }
        }
      } 
      for(int k = 0; k < count; k++) 
      { 
        triangleShapes[k].display(); 
      } 

Copy code
    VertexClass class (or convert to use PVector)
     
    Copy code
    1. class VertexClass
      {
        float x, y;
       
        VertexClass(float x, float y)
        {
          this.x = x;
          this.y = y;
        }
       
        void display()
        {
          fill(0);
          ellipse(x, y, 10, 10);
        }
      }
    TriangleShape class
     
    Copy code
    1. class TriangleShape
      {
        float x0, y0, x1, y1, x2, y2;
        color colour;
       
        TriangleShape(float x0, float y0, float x1, float y1, float x2, float y2, color colour)
        {
          this.x0 = x0;
          this.y0 = y0;
          this.x1 = x1;
          this.y1 = y1;
          this.x2 = x2;
          this.y2 = y2;
          this.colour = colour;
        }
       
        void display()
        {
          fill(colour);
          triangle(x0, y0, x1, y1, x2, y2);
        }
      }

    Re: Shapes and Grid

    2 years ago
    Hey,

    awesome! 
    Now I'd like to tweak some bits and try to create more classes. For instance how would you suggest to organise data for making the grid? A global Shape class with different methods for different grids type (hex,quads, triang etc..)?

    Re: Shapes and Grid

    2 years ago
    here again...

    I was trying to code hexagons in a similar fashion how you did triangles but I finf it very tricky. I'd like to achieve something like
    vertices[i][j] = new VertexClass(xpos, ypos);  where each i,j is are vertices of my hexs. I tried with a typical approach to have a 2d matrix of point and then select only those I need to draw hexagons :( I have again duplicate points...going mad. I found an interesting article  http://gdreflections.com/2011/02/hexagonal-grid-math.html but what it does is create a basic shape and then replicate it over a grid..again duplicating vertices where edges are adjacent. 

    I liked you approach to build first a grid of unique points and then define within the grid the basic shape...! Really cant find a method for hexagons..I tried to tweak the triangles grid bu got lost. Any ideas?

    Re: Shapes and Grid

    2 years ago
    Hi
    I feel a diagram coming on ..
    string
     

    Re: Shapes and Grid

    2 years ago
    lol I was just replying with a diagram myself too!
    Yes that the strategy that came to mind as well..I was going for the first method. But how would you sort the indeces of the grid points to get the hexagon to make the tiling like in the picture below?

    Plus I guess I will have some unsed/unsorted point at the edge of my grid. (those within green lines).

    Re: Shapes and Grid

    2 years ago
    Hi
    Your picture hasn't loaded.
     
    Have a go at picking which vertices you need. I'd be thinking of using modulo(%).
    In my diagram, in the top row I know I need numbers 0, 1, (not 2) 3, 4, (not 5) and so on. The ones I don't want are all of the form
    3n+2
    so
    n % 3 = 2
    That should get you started.
     
    string

    Re: Shapes and Grid

    2 years ago
    mhh yes I reckon this but in this case unlikely with triangles hexagons spans over two rows and I find tricky..

    I I start stacking hexagon below the first in your picture then Ill have a a loop for all those and their indeces would be , I guess


    [i][j] 
    [i+1][j]
    [i+1][j+1]
    [i+2][j+1]
    [i+2][j]
    [i][j+1]

    as you said for the first row the loop will iterate excluding say i %3 = 2:

    Then I have to do the shifted hexagons...in another second loop , right?

    ps I see all images with Chrome

    Re: Shapes and Grid

    2 years ago



    So this is what I came up with...and really getting crazy and cant understand how to fix it here is the "wrong" code I used to sort indeces
    Copy code
    1. float side = w / (numCols - 2);
    2. particles = new Particle[numCols][numRows][2];
    3. for (int i=0; i<numCols; ++i){
    4. for(int j=0; j<numRows; ++j) {
    5. float xpos,ypos;
    6. if (j%2!=0  ){
    7. xpos = side*(i-0.5f);
    8. ypos = (0.866f*side) * j;
    9. } else{
    10. xpos = side*(i);
    11. ypos = (0.866f*side) *j;
    12. }
    13. verteces [i][j] = new PVector( xpos, ypos);
    14. }
    15. }
    16. for  (int j =0; j<numRows-2; ++j){
    17. for (int i=j%2*2; i<numCols-3; i+=3){
    18. PVector a = verteces[i][j][0];  
    19.  PVector b =verteces[i+1][j][0];
    20. PVector c = verteces[i+1][j+1][0];  
    21.  PVector d = verteces[i+1][j+2][0];
    22.  PVector e =verteces[i][j+2][0]; 
    23.  PVector f = verteces[i][j+1][0];   
    24.                   
    25.                
    26.                   
    27. }
    28. }
    I m also not sure how I did it...but was trying to manage all sorting stuff in one double loop...without many IFs...but indeces dont work well with i=j%2*2 ..so Vector c and f result shifted...:-( I was almost there...



    Re: Shapes and Grid

    2 years ago
    Hi
    [untested] On your even number rows, try
     
    PVector c = verteces[i + 2][j + 1][0];
     
    and odd
     
    PVector f = verteces[i - 1][j + 1][0];
     
    !
    string

    Re: Shapes and Grid

    2 years ago
    THanks Again!!!
    It works with your last advice! Im happy with it despite I have some unused points...but it seems unavoidable with this strategy.

    Tried the code (the 3-part one, with VertexClass and TriangleShape)
    , it's not running, errors...
     
    I had problem to copy it (Copy code problems),
    but after correcting thoses, I still get a run time error, in draw():
     
    ArrayOutOfBoundException: count=128
            triangleShapes[count] = new TriangleShape(startX, startY, downRightX, downRightY, downLeftX, downLeftY, color(random(255)));        
     
     
     

    Re: Shapes and Grid

    1 year ago
    Which bit? There's a least four blocks of code in this thread.