Search code examples
javaswingcellular-automata

How to build a Triangle-based Grid in Java using Swing?


How to build a Triangle-based Grid in Java using Swing.

Context:

I've been searching this for quite a while; I've seen many questions throughout my search of the internet.

However, as you can see; a majority of them only focus on one Triangle. I am attempting to make a Grid.

The Problem:

Below is a screenshot of my current predicament. I have successfully made row's of triangles however, I have clearly done something wrong. The spacing between row's are offset.

First off, I Apologies for how dark this image is. As you can see, each row contains four Triangles. You can just about see the "Rows"between the Yellow and Green Triangles.

(I apologies for the link, This is my first question, I do not have the ability to post embedded imagery)

The Code Snippet

I apologies in advanced this code looks poorly written.

This is the code I've come up with thus far, for making a Triangle Grid.

for (int x = 0; x < board.width; x++) {
  for (int y = 0; y < board.height; y++) {
    int numberOfSides = 3;
    double sideLength = cellSize;
    if(y%2==0) {
      if(x%2==0) {
        Polygon triA = new Polygon();
        for (int i = 0; i < numberOfSides; i++) {
          triA.addPoint(
            (int) ((cellSize) + (cellSize * x)
            + sideLength * Math.sin(i * 2 * Math.PI / numberOfSides)),
            (int) ((cellSize) + (cellSize * y)
            + sideLength * Math.cos(i * 2 * Math.PI / numberOfSides))
          );
         }
         g.setColor(Color.GREEN);
         g.drawPolygon(triA);
       } else {
         Polygon triA = new Polygon();
         for (int i = 0; i < numberOfSides; i++) {
           triA.addPoint(
             (int) ((cellSize) + (cellSize * x)
             - sideLength * Math.sin(i * 2 * Math.PI / numberOfSides)),
             (int) ((cellSize+sideLength/2) + (cellSize * y)
             - sideLength * Math.cos(i * 2 * Math.PI / numberOfSides))
           );
         }
         g.setColor(Color.RED);
         g.drawPolygon(triA);
       } else {
         if(x%2==0) {
           Polygon triA = new Polygon();
             for (int i = 0; i < numberOfSides; i++) {
               triA.addPoint(
                 (int) ((cellSize) + (cellSize * x)
                 - sideLength * Math.sin(i * 2 * Math.PI / numberOfSides)),
                 (int) ((cellSize+cellSize) + (cellSize * y)
                 - sideLength * Math.cos(i * 2 * Math.PI / numberOfSides))
               );
             }
             g.setColor(Color.YELLOW);
             g.drawPolygon(triA);
           } else {
             Polygon triA = new Polygon();
             for (int i = 0; i < numberOfSides; i++) {
               triA.addPoint(
                 (int) ((cellSize) + (cellSize * x)
                 + sideLength * Math.sin(i * 2 * Math.PI / numberOfSides)),
                 (int) ((cellSize+cellSize/2) + (cellSize * y)
                 + sideLength * Math.cos(i * 2 * Math.PI / numberOfSides))
               );
             }
             g.setColor(Color.BLUE);
             g.drawPolygon(triA);
           }
         }

The Obvious Issues

So, the main issue thus far is the Size and Spacing of Triangles. My code is obviously not the best in the world and I'm sure there are some much simpler solutions. This image below is what I am trying to replicate:

Here is my end Goal. I do not wish to make a small grid like this image, but using the same rules for the rows, I would like to make a Triangle Grid which fills an entire board. In this scenario, we can assume this is either a JPanel or JFrame.

The Purpose of this goal?

Once again, I wish to apologies for the vagueness of this question. I am trying to build a Triangle Grid for some research I am doing into Cellular Automata. The code snippet I have provided was once fashioned from a Hexagon Grid Generation Method I built. I changed the numberOfSides variable to three and adjusted the sideLength variable to try and remove spacing. This is where my problem has occured.

For those interested, here is a link to a blog by a Computer Scientist into Triangular Cellular Automata. I wish to replicate their results one day. Triangular Game of Life

End Note

I would greatly appreciate some guidance on how to build a Triangle Grid. I'm sure there are some much more accurate methods such as using DrawLine. I would also appreciate some feedback on my question. This is my first question on Stackoverflow, after using the website for quite some time. I will try my best to monitor this post throughout the day if anyone has any questions for me.


Solution

  • A Polygon can be reused in painting so you only need to create 2 Polygons, one with the triangle pointed up and the other with the triangle pointed down.

    Then when you do your painting you use the Graphic.translate(...) method to position the Polygon. Or another option is to create a custom class containing 3 properties:

    1. Polygon
    2. Point where the Polygon is painted
    3. Color of the polygon

    Then you add each cell to an ArrayList. In the painting code you then just iterate through the ArrayList to paint each cell. The advantage of this approach is that you are not doing all the calculations every time the panel needs to be repainted.

    The spacing between row's are offset.

    Once you have the Shape you want to paint, you can use the getBounds() method of the Shape. Then:

    1. for horizontal position you would use the width / 2
    2. for vertical position you would use the height.

    In this scenario, we can assume this is either a JPanel or JFrame.

    It would never be a JFrame. Custom painting is done by overriding paintComponent() of a JPanel (or JComponent). Then you add the panel to the frame.

    I'm sure there are some much simpler solutions.

    Not necessarily simpler, but you may want to check out Playing With Shapes for a reusable class that allows you to create some interesting shapes. It also allows you to rotate a given Shape.