The Chaos Game is a method of generating the attractor of an iterated function system (IFS).

One of the best-known and simplest examples creates a fractal, using a polygon and an initial point selected at random.



Task
Play the Chaos Game using the corners of an equilateral triangle as the reference points.   Add a starting point at random (preferably inside the triangle).   Then add the next point halfway between the starting point and one of the reference points.   This reference point is chosen at random.

After a sufficient number of iterations, the image of a Sierpinski Triangle should emerge.



See also
 The Game of Chaos


 
extern crate image;
extern crate rand;
 
use rand::prelude::*;
use std::f32;
 
fn main() {
    let max_iterations = 50_000;
    let img_side = 800;
    let tri_size = 400.0;
 
    // Create a new ImgBuf
    let mut imgbuf = image::ImageBuffer::new(img_side, img_side);
 
    // Create triangle vertices
    let mut vertices: [[f32; 2]; 3] = [[0.0, 0.0]; 3];
    for i in 0..vertices.len() {
        vertices[i][0] = (img_side as f32 / 2.0)
            + (tri_size / 2.0) * (f32::consts::PI * i as f32 * 2.0 / 3.0).cos();
        vertices[i][1] = (img_side as f32 / 2.0)
            + (tri_size / 2.0) * (f32::consts::PI * i as f32 * 2.0 / 3.0).sin();
    }
    for v in &vertices {
        imgbuf.put_pixel(v[0] as u32, v[1] as u32, image::Luma([255u8]));
    }
    println!("Verticies: {:?}", vertices);
 
    // Iterate chaos game
    let mut rng = rand::thread_rng();
    let mut x = img_side as f32 / 2.0;
    let mut y = img_side as f32 / 2.0;
    for _ in 0..max_iterations {
        let choice = rng.gen_range(0..vertices.len());
        x = (x + vertices[choice][0]) / 2.0;
        y = (y + vertices[choice][1]) / 2.0;
 
        imgbuf.put_pixel(x as u32, y as u32, image::Luma([255u8]));
    }
 
    // Save image
    imgbuf.save("fractal.png").unwrap();
}
 