In [2]:
fn hash_u32(mut a: u32) -> u32 {
        a = a.wrapping_add(0x7ed55d16).wrapping_add(a.rotate_left(12));
        a = (a ^ 0xc761c23c) ^ a.rotate_right(19);
        a = a.wrapping_add(0x165667b1).wrapping_add(a.rotate_left(5));
        a = a.wrapping_add(0xd3a2646c) ^ a.rotate_left(9);
        a = a.wrapping_add(0xfd7046c5).wrapping_add(a.rotate_left(3));
        a = (a ^ 0xb55a4f09) ^ a.rotate_right(16);
        return a;
    }
In [3]:
fn truchet_pattern(x: u32, y: u32, size: u32, seed: u32, hash_fn: fn(u32)->u32)->bool{
    let chunk_x = x/size;
    let chunk_y = y/size;
    let seed_x = hash_fn(chunk_x.wrapping_add(seed));
    let seed = hash_fn(chunk_y.wrapping_add(seed_x));
    let should_mirror = seed%2 == 0;
    let mut in_x = x%size;
    let in_y = y%size;
    if should_mirror{
        in_x = size - 1 - in_x;
    }
    let mut result = (in_x as i64 - in_y as i64).abs() < size as i64/2;
    let flip_result = (chunk_x.wrapping_add(chunk_y))%2 == 0;
    if should_mirror{
        result = !result;
    }
    if flip_result{
        return !result;
    }
    result
}
In [10]:
:dep image = "0.23"
:dep evcxr_image = "1.1"
use evcxr_image::ImageDisplay;

image::ImageBuffer::from_fn(256, 256, |x, y| {
    if truchet_pattern(x, y, 4, 0xfdc, hash_u32) {
        image::Rgb([255;3])
    } else {
        image::Rgb([0;3])
    }
})
Out[10]:
In [5]:
image::ImageBuffer::from_fn(256, 256, |x, y| {
    if truchet_pattern(x, y, 4, 0xfacb, hash_u32) & truchet_pattern(x, y, 16, 0xfacbd, hash_u32){
        image::Rgb([255;3])
    } else {
        image::Rgb([0;3])
    }
})
Out[5]:
In [6]:
image::ImageBuffer::from_fn(64, 64, |x, y| {
    let mut x = x;
    let mut y = y;
    if (64-y)<x{
        x = 64-x;
        y = 64-y;
    }
    if x*x+y*y < 64*64*2/9{
        image::Rgb([0;3])
    } else {
        image::Rgb([255;3])
    }
})
Out[6]:
In [7]:
fn truchet_pattern_circle(x: u32, y: u32, size: u32, seed: u32, hash_fn: fn(u32)->u32)->bool{
    let chunk_x = x/size;
    let chunk_y = y/size;
    let seed_x = hash_fn(chunk_x.wrapping_add(seed));
    let seed = hash_fn(chunk_y.wrapping_add(seed_x));
    let should_mirror = seed%2 == 0;
    let mut in_x = x%size;
    let mut in_y = y%size;
    if should_mirror{
        in_x = size - 1 - in_x;
    }
    if (size-in_y) < in_x{
        in_x = size-in_x-1;
        in_y = size-in_y-1;
    }
    let mut result = (in_x*in_x + in_y*in_y) < size*size*2/9;
    let flip_result = (chunk_x.wrapping_add(chunk_y))%2 == 0;
    if should_mirror{
        result = !result;
    }
    if flip_result{
        return !result;
    }
    result
}
In [8]:
image::ImageBuffer::from_fn(256, 256, |x, y| {
    if truchet_pattern_circle(x, y, 32, 0xfdc, hash_u32) {
        image::Rgb([255;3])
    } else {
        image::Rgb([0;3])
    }
})
Out[8]:
In [9]:
image::ImageBuffer::from_fn(256, 256, |x, y| {
    if truchet_pattern_circle(x, y, 16, 0xfdc, hash_u32){
        image::Rgb([255;3])
    } else {
        image::Rgb([0;3])
    }
})
Out[9]:
In [ ]: