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;
}
fn is_on_line(x: i32, y: i32, x1: i32, y1: i32, x2: i32, y2: i32, thickness: i32)->bool{
let above = (x-x1)*(y2-y1)-(y+thickness-y1)*(x2-x1);
let below = (x-x1)*(y2-y1)-(y-thickness-y1)*(x2-x1);
return above.signum() != below.signum();
}
fn horizontal_lines(x: u32, y: u32, size: u32, seed: u32, hash_fn: fn(u32)->u32, thickness: i32)->bool{
let chunk_x = x/size;
let seed_x = hash_fn(chunk_x.wrapping_add(seed));
let y1 = seed_x%size;
//chunk to the right:
let seed_x_r = hash_fn(chunk_x.wrapping_add(1).wrapping_add(seed));
let y2 = seed_x_r%size;
let in_x = x%size;
let in_y = y%size;
return is_on_line(in_x as i32, in_y as i32, 0, y1 as i32, (size-1) as i32, y2 as i32, thickness);
}
:dep image = "0.23"
:dep evcxr_image = "1.1"
use evcxr_image::ImageDisplay;
image::ImageBuffer::from_fn(256, 256, |x, y| {
if horizontal_lines(x, y, 16, 0xa, hash_u32, 1) {
image::Rgb([255;3])
} else {
image::Rgb([0;3])
}
})
let chunk_size = 16;
let seed = 0xfcabd;
image::ImageBuffer::from_fn(256, 256, |x, y| {
let chunk_y = y/chunk_size;
let seed_y = hash_u32(chunk_y.wrapping_add(seed));
if horizontal_lines(x, y, chunk_size, seed_y, hash_u32, 2) {
image::Rgb([255;3])
} else {
image::Rgb([0;3])
}
})
fn randomized_horizontal_lines(x: u32, y: u32, size: u32, seed: u32, hash_fn: fn(u32)->u32, thickness: i32)->bool{
let chunk_y = y/size;
let seed_y = hash_u32(chunk_y.wrapping_add(seed));
return horizontal_lines(x, y, size, seed_y, hash_u32, thickness);
}
image::ImageBuffer::from_fn(256, 256, |x, y| {
//combine x,y | y,x to create a network:
if randomized_horizontal_lines(x, y, chunk_size, 0xabcd, hash_u32, 2) | randomized_horizontal_lines(y, x, chunk_size, 0xfff, hash_u32, 2){
image::Rgb([255;3])
} else {
image::Rgb([0;3])
}
})
fn horizontal_vornoi_texture(x: u32, y: u32, size: u32, seed: u32, hash_fn: fn(u32)->u32, thickness: i32)->(bool, u32){
let chunk_x = x/size;
let chunk_y = y/size;
let seed_x = hash_fn(chunk_x.wrapping_add(seed));
let chunk_seed = hash_fn(chunk_y.wrapping_add(seed_x));
let y1 = (chunk_seed%size) as i32;
//chunk to the right:
let seed_x_r = hash_fn(chunk_x.wrapping_add(1).wrapping_add(seed));
let seed_r = hash_fn(chunk_y.wrapping_add(seed_x_r));
let y2 = (seed_r%size) as i32;
let in_x = (x%size) as i32;
let in_y = (y%size) as i32;
let x1 = 0;
let x2 = (size-1) as i32;
let is_on_line = is_on_line(in_x, in_y, x1, y1, x2, y2 as i32, thickness);
let mut color_seed_here = hash_fn(chunk_y.wrapping_add(seed));
if ((in_x-x1)*(y2-y1)-(in_y-y1)*(x2-x1)).signum() < 0{
let seed_below = hash_fn(chunk_y.wrapping_add(seed).wrapping_add(1));
color_seed_here = seed_below;
}
return (is_on_line, color_seed_here);
}
image::ImageBuffer::from_fn(256, 256, |x, y| {
//combine x,y | y,x to create a network:
let (border, seed) = horizontal_vornoi_texture(x, y, 16, 0xabcdef, hash_u32, 2);
if border{
image::Rgb([0;3])
}else{
let byte_array = seed.to_ne_bytes();
let r = byte_array[0];
let g = byte_array[1];
let b = byte_array[2];
image::Rgb([r, g, b])
}
})
let chunk_size = 16;
let seed_1 = 0xabcdef;
let seed_2 = 0xfedcba;
//apply it on x, y and y, x dimensions to get vertical and horizontal variations:
image::ImageBuffer::from_fn(256, 256, |x, y| {
let x = x + 3000;
let y = y+3000;
//combine x,y | y,x to create a network: if not 2 different seeds where used, the texture would be symetrical around the diagonal
let (borderh, seedh) = horizontal_vornoi_texture(x, y, chunk_size, seed_1, hash_u32, 2);
let (borderv, seedv) = horizontal_vornoi_texture(y, x, chunk_size, seed_2, hash_u32, 2);
if borderh | borderv{
image::Rgb([0;3])
}else{
//return image::Rgb([255;3]);
let seed = seedh.wrapping_add(seedv);
let byte_array = seed.to_ne_bytes();
let r = byte_array[0];
let g = byte_array[1];
let b = byte_array[2];
image::Rgb([r, g, b])
}
})
let chunk_size = 64;
let seed_1 = 0xabcdef;
//demo of symmetry in case of one seed
//apply it on x, y and y, x dimensions to get vertical and horizontal variations:
image::ImageBuffer::from_fn(256, 256, |x, y| {
let x = x + 3000;
let y = y+3000;
//combine x,y | y,x to create a network: if not 2 different seeds where used, the texture would be symetrical around the diagonal
let (borderh, seedh) = horizontal_vornoi_texture(x, y, chunk_size, seed_1, hash_u32, 2);
let (borderv, seedv) = horizontal_vornoi_texture(y, x, chunk_size, seed_1, hash_u32, 2);
if borderh | borderv{
image::Rgb([0;3])
}else{
//return image::Rgb([255;3]);
let seed = seedh.wrapping_add(seedv);
let byte_array = seed.to_ne_bytes();
let r = byte_array[0];
let g = byte_array[1];
let b = byte_array[2];
image::Rgb([r, g, b])
}
})