Search code examples
javaorganizationcode-organizationfractalschaos

How do I organize this list of polygons in java so that they are easy to work with?


My question involves address spaces of fractals that can be generated using the chaos game. These address spaces are simply transformations of a main shape with relation to one-another.

enter image description here

In the image here, you can see that there is a triangle labeled "2". Triangles "21", "22", and "23" are related to triangle 2 because you must transform it to get these smaller child triangles.

This is what I want to do..... given the following parameters:

  • Int s: The number of sides in the original shape
  • Int d: The depth down the tree of shapes we want (in the image, d=2 because we generate the 3 smaller triangles of a main triangle, and then generate their children as well)
  • Polygon p: The original shape which we intend to make children from

... I would like to take those parameters and start iterating down each depth level with a counter "i". You can check that at level i, there are s^d shapes that are needed. Each of these shapes will depend on a poly that is in the level above, so how do I store these in some way where I can create lots of levels of depth in a way that makes simple sense, and can also use for loops or some other efficient and simple way? My best hope is that at each depth level i can access parents for the triangles I want to create at this level. I also want to reference the shapes later, either by direct name since this is a unique id, or some other simple way.

My original plan was to somehow work with the name for each shape (the labels seen in the image). I could have a massive array of shapes somehow but only populate indexes "1", "2", "3", "11", "12", "13", "21", "22", etc. However this seems not only messy and inefficient, but seems nonsensical as i would have to work at a way to get these permutations of 1, 2, and 3 in a way i can handle. There must be a better way!

In case it helps, I have provided my source code:

package chaosaddresses;

import java.util.ArrayList;
//import java.awt.Polygon;

public class AddressManager
{
public Address originalPoly;
public ArrayList<Address>[] array;
public int depth;
public int sides;


public AddressManager(int d, int s, Address a)
{
    depth = d;
    sides = s;
    originalPoly = a;
    initArray();
}

private void initArray()
{
    //loop through each depth and get all needed polygons
    //number of polys at each depth is s^d.
    for (int i=1; i <= depth; i++)
    {
        int numPolys = (int)Math.pow(sides,i);
        int numParentPolys = array[i-1].size();
        ArrayList<Address> thisLevel = new ArrayList<>();

        //iterate parent polys and have each generate their children
        for (int j= 0; j < numParentPolys; j++)
        {
            Address[] babies = array[i-1].get(j).makeChildren();

            //add babies to current level
            for (int k=0; k < babies.length; k++)
            {
                thisLevel.add(babies[k]);
            }
        }
        array[i] = thisLevel;
    }
}


}

Solution

  • Fractals lend themselves to recursion, since their calculation is recursive by nature. One way to organize this is to have each level hold a reference to the instances of the next level, giving you a tree of levels, each which have recursively created their children.


    Edit
    For example, something along this order:

    public class Sierpinski {
       public static int MAX_LEVEL = 6;
       private int level;
       private Point2D[] points = new Point2D[3];
       private Sierpinski[] childTriangles = null;
    
       private Sierpinski(int level, Point2D[] points) {
          this.level = level;
          this.points = points;
    
          if (level < MAX_LEVEL) {
             childTriangles = createChildren();
          }
       }
    
       public int getLevel() {
          return level;
       }
    
       public Point2D[] getPoints() {
          return points;
       }
    
       private Sierpinski[] createChildren() {
          // TODO finish method....
       }
    
       public void draw(Graphics2D g2) {
          // TODO finish method:
          // ....  draw this triangle
    
          if (childTriangles != null) {
             for (Sierpinski childTriangle : childTriangles) {
                childTriangle.draw(g2);
             }
          }
       }
    }