Chaos game

edited May 2017 in Share Your Work

After I saw the chaos game video from Numberphile, I recreated it that evening but spent much longer playing around with it. I am placing a basic version here thinking someone else may enjoy. * Edited with suggestions from @jeremydouglass

int N = 3; // Number of control points
int MAX_DIST = 60;
int MANY_TIMES = 2000;
float DIV = 2.0; // You can change the rules for drawing the pattern

// Control points
float[] px = new float[N];
float[] py = new float[N];

// The moving point, draws the pattern
float selx = 0;
float sely = 0;

boolean held = false;
int nearest = -1;

void setup()
{
  size(800,600,P2D);

  // Initial points, anywhere you like
  px[0] = width/4;
  py[0] = height/4;
  px[1] = width - (width/4);
  py[1] = height/4;
  px[2] = width - (width/4);
  py[2] = height - (height/4);

  noFill();
  frameRate(60);
  background(0);
}

void mouseMoved()
{
  float neardist = width + height;
  for (int i=0; i<N; i++)
  {
    float nd = dist(px[i],py[i], mouseX,mouseY);
    if (nd < neardist)
    {
      nearest = i;
      neardist = nd;
    }
  }
  if (MAX_DIST < neardist)
  {
    nearest = -1;
  }
}

void mousePressed()
{
  if (-1 != nearest)
  {
    held = true;
  }
}
void mouseReleased()
{
  held = false;
}

void draw()
{
  // This section allows you to move the control points
  if (held)
  {
    px[nearest] = constrain(mouseX,0,width);
    py[nearest] = constrain(mouseY,0,height);
    background(0);
  }
  // Still not to the pattern code

  // Show control points
  for (int i=0; i<N; i++)
  {
    if (i == nearest)
    {
      stroke(0,255,0);
    }
    else
    {
      stroke(0,0,255);
    }
    ellipse( px[i],py[i], MAX_DIST,MAX_DIST );
  }

  stroke(255);
  for (int i=0; i<MANY_TIMES; i++) // Draw many points
  {
    // These are the lines that actually generate the pattern.
    int thistime = (int)random(N);
    float nx = ((px[thistime] - selx) / DIV) + selx;
    float ny = ((py[thistime] - sely) / DIV) + sely;
    selx = nx;
    sely = ny;
    // Yep, that is it.

    point( nx, ny );
  }
}

Comments

  • Nice :)

  • Nice! Once suggestion:

      px[nearest] = constrain(mouseX,0,width);
      py[nearest] = constrain(mouseY,0,height);
    

    Currently it is easy to drag the control points off the screen, after which they are no longer useable.

  • Thanks @cameyo. @jeremydouglas Good point. I've made that change to the original. Thank you.

  • @noahbuddy -- it really is very surprising how little code there is in that final for loop.

    I know this is a small demo sketch, but I have another suggestion: to slightly change the mouse input. Right now any fast-dragging of the mouse causes the mouse distance from the control point to change too rapidly, so the mouse "drops" the control point. To fix that you could "pick up" (save the index of) the control point only on first frame that mousePressed registers, then move the known-index control point for as long as mouseDragged, then "drop" (clear the index of) the control point on mouseReleased. This would mean that the nearest point would only have to be computed on the first mousePressed frame and it would never be accidentally dropped.

  • @jeremydouglass - Updated. While it is a demo, I know that I prefer a software interface to behave as I 'expect'. I only noticed losing track when drawing a great number of points, slowing down the response. Thanks again.

Sign In or Register to comment.