Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = ["poisson", "poisson-visualisation"]
resolver = "2"

[profile.test]
opt-level = 3
14 changes: 7 additions & 7 deletions poisson-visualisation/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "poisson-visualisation"
version = "0.1.0"
version = "0.11.0"
authors = ["WaDelma <>"]
edition = "2018"
edition = "2024"

[dependencies]
nalgebra = "0.17"
image = "0.21.0"
clap = "2.32.0"
rand = "0.6"
lab = "0.4"
nalgebra = { version = "0.34.1", features = ["alga", "rand"] }
image = "0.25.8"
clap = "4.5.48"
rand = "0.9.2"
lab = "0.11.0"
fnv = "1.0"
poisson = { path = "../poisson" }
171 changes: 105 additions & 66 deletions poisson-visualisation/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use clap::{App, Arg, ArgMatches, arg_enum, _clap_count_exprs, value_t};
use clap::{builder::PossibleValuesParser, Arg, ArgMatches, Command};

use poisson::{Builder, Type, algorithm::{Bridson, Ebeida}};
use poisson::{
algorithm::{Bridson, Ebeida},
Builder, Type,
};

use rand::{rngs::SmallRng, FromEntropy, Rng, seq::SliceRandom, SeedableRng};
use rand::rngs::SmallRng;
use rand::{rng, seq::SliceRandom, Rng, SeedableRng};

use nalgebra::Vector2;

Expand All @@ -13,89 +17,125 @@ use lab::Lab;
use fnv::FnvHasher;

use std::hash::Hasher;
use std::str::FromStr;

arg_enum! {
#[derive(PartialEq, Debug)]
pub enum Algo {
Ebeida,
Bridson
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Algo {
Ebeida,
Bridson,
}

impl FromStr for Algo {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"ebeida" => Ok(Algo::Ebeida),
"bridson" => Ok(Algo::Bridson),
_ => Err(format!("Invalid algorithm: {}", s)),
}
}
}

arg_enum! {
#[derive(PartialEq, Debug)]
pub enum Style {
Plain,
Colorful,
Dot
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Style {
Plain,
Colorful,
Dot,
}

impl FromStr for Style {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"plain" => Ok(Style::Plain),
"colorful" => Ok(Style::Colorful),
"dot" => Ok(Style::Dot),
_ => Err(format!("Invalid style: {}", s)),
}
}
}

fn main() {
let app = App::new("Poisson visualisation")
let app = Command::new("Poisson visualisation")
.author("delma")
.version("0.1.0")
.about("Visualisation for poisson library")
.arg(
Arg::with_name("OUTPUT")
Arg::new("OUTPUT")
.help("Output file that's generated")
.required(true)
.index(1)
)
.arg(
Arg::with_name("SEED")
.help("Seed for the generation")
.index(2)
.index(1),
)
.arg(Arg::new("SEED").help("Seed for the generation").index(2))
.arg(
Arg::with_name("radius")
.short("r")
.takes_value(true)
.help("Radius of the disks")
Arg::new("radius")
.short('r')
.value_name("RADIUS")
.help("Radius of the disks"),
)
.arg(
Arg::with_name("width")
.short("w")
.takes_value(true)
.help("Width of the generated image")
Arg::new("width")
.short('w')
.value_name("WIDTH")
.help("Width of the generated image"),
)
.arg(
Arg::with_name("height")
.short("h")
.takes_value(true)
.help("Height of the generated image")
Arg::new("height")
.short('h')
.value_name("HEIGHT")
.help("Height of the generated image"),
)
.arg(
Arg::with_name("style")
.short("s")
.takes_value(true)
Arg::new("style")
.short('s')
.value_name("STYLE")
.help("Style for the disks")
.possible_values(&Style::variants())
.value_parser(PossibleValuesParser::new(["plain", "colorful", "dot"])),
)
.arg(
Arg::with_name("algo")
.short("a")
Arg::new("algo")
.short('a')
.help("Algorithm that's used to generate image")
.takes_value(true)
.possible_values(&Algo::variants())
.value_name("ALGO")
.value_parser(PossibleValuesParser::new(["ebeida", "bridson"])),
);
visualise(app.get_matches());
}

fn visualise(m: ArgMatches) {
let width = value_t!(m, "width", u32).unwrap_or(1024);
let height = value_t!(m, "height", u32).unwrap_or(1024);
let radius = value_t!(m, "radius", f32).unwrap_or(0.02);
let algo = value_t!(m, "algo", Algo).unwrap_or(Algo::Ebeida);
let style = value_t!(m, "style", Style).unwrap_or(Style::Plain);
let name = m.value_of("OUTPUT").unwrap();
let master_rng = m.value_of("SEED").map(|s| {
let mut fnv = FnvHasher::with_key(0);
for b in s.bytes() {
fnv.write_u8(b);
}
SmallRng::seed_from_u64(fnv.finish())
}).unwrap_or_else(SmallRng::from_entropy);
let width: u32 = m
.get_one::<String>("width")
.and_then(|s| s.parse().ok())
.unwrap_or(1024);
let height: u32 = m
.get_one::<String>("height")
.and_then(|s| s.parse().ok())
.unwrap_or(1024);
let radius: f32 = m
.get_one::<String>("radius")
.and_then(|s| s.parse().ok())
.unwrap_or(0.02);
let algo = m
.get_one::<String>("algo")
.and_then(|s| Algo::from_str(s).ok())
.unwrap_or(Algo::Ebeida);
let style = m
.get_one::<String>("style")
.and_then(|s| Style::from_str(s).ok())
.unwrap_or(Style::Plain);
let name = m.get_one::<String>("OUTPUT").expect("OUTPUT argument is required");
let master_rng = m
.get_one::<String>("SEED")
.map(|s| {
let mut fnv = FnvHasher::with_key(0);
for b in s.bytes() {
fnv.write_u8(b);
}
SmallRng::seed_from_u64(fnv.finish())
})
.unwrap_or_else(|| SmallRng::from_rng(&mut rng()));

let mut style_rng = master_rng.clone();

Expand All @@ -111,14 +151,13 @@ fn visualise(m: ArgMatches) {

let mut image = ImageBuffer::new(width, height);
for p in points {
let pp = ps.pop().unwrap();
let col = Rgb {
data: Lab {
l: style_rng.gen::<f32>() * 80. + 10.,
a: pp.x * 256. - 128.,
b: pp.y * 256. - 128.
}.to_rgb()
};
let pp = ps.pop().expect("ps should have same length as points");
let col = Rgb(Lab {
l: style_rng.random::<f32>() * 80. + 10.,
a: pp.x * 256. - 128.,
b: pp.y * 256. - 128.,
}
.to_rgb());

let x = p.x * width as f32;
let y = p.y * height as f32;
Expand Down Expand Up @@ -150,13 +189,13 @@ fn visualise(m: ArgMatches) {
if style == Style::Colorful {
image[(xxx, yyy)] = col;
} else {
image[(xxx, yyy)] = Rgb { data: [255, 255, 255] };
image[(xxx, yyy)] = Rgb([255, 255, 255]);
}
if style == Style::Plain && (xx == 0. || yy == 0.) {
image[(xxx, yyy)] = Rgb { data: [255, 0, 0] };
image[(xxx, yyy)] = Rgb([255, 0, 0]);
}
}
}
}
image.save(name).unwrap();
image.save(name).expect("Failed to save generated image");
}
12 changes: 6 additions & 6 deletions poisson/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
[package]
name = "poisson"
version = "0.10.1"
version = "0.11.0"
authors = ["WaDelma <>"]
description = "Poisson-disk distribution generator."
repository = "https://github.com/WaDelma/poisson"
readme = "../README.md"
category = [ "algorithms" ]
keywords = [ "distribution", "poisson-disk", "multidimensional", "sampling" ]
license = "MIT"
edition = "2018"
edition = "2024"

[badges]
travis-ci = { repository = "WaDelma/poisson" }
coveralls = { repository = "WaDelma/poisson", service = "github" }

[dependencies]
rand = "0.6"
alga = "0.8"
rand = {version="0.9.2", features=["small_rng", "std", "std_rng"]}
rand_distr = "0.5.1"
alga = "0.9.3"
num-traits = "0.2"
lazy_static = "1.3"
modulo = "0.1"
sphere = "0.3"

[dev-dependencies]
nalgebra = "0.17"
nalgebra = { version = "0.34.1", features = ["alga", "rand"] }
19 changes: 18 additions & 1 deletion poisson/benches/dim2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rand::{rngs::SmallRng, SeedableRng};
extern crate nalgebra as na;
pub type Vect = na::Vector2<f64>;

const SEED: [u8; 16] = [
const SEED: [u8; 32] = [
(3 + 2741) as u8,
(7 + 2729) as u8,
(13 + 2713) as u8,
Expand All @@ -27,6 +27,23 @@ const SEED: [u8; 16] = [
(107 + 2549) as u8,
(113 + 2539) as u8,
(131 + 2521) as u8,
// Additional 16 bytes for 32-byte seed
(137 + 2503) as u8,
(149 + 2477) as u8,
(157 + 2459) as u8,
(163 + 2447) as u8,
(173 + 2423) as u8,
(179 + 2411) as u8,
(181 + 2399) as u8,
(191 + 2389) as u8,
(193 + 2383) as u8,
(197 + 2377) as u8,
(199 + 2371) as u8,
(211 + 2357) as u8,
(223 + 2347) as u8,
(227 + 2341) as u8,
(229 + 2339) as u8,
(233 + 2333) as u8,
];

#[bench]
Expand Down
19 changes: 18 additions & 1 deletion poisson/benches/dim3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rand::{rngs::SmallRng, SeedableRng};
extern crate nalgebra as na;
pub type Vect = na::Vector3<f64>;

const SEED: [u8; 16] = [
const SEED: [u8; 32] = [
(3 + 2741) as u8,
(7 + 2729) as u8,
(13 + 2713) as u8,
Expand All @@ -27,6 +27,23 @@ const SEED: [u8; 16] = [
(107 + 2549) as u8,
(113 + 2539) as u8,
(131 + 2521) as u8,
// Additional 16 bytes for 32-byte seed
(137 + 2503) as u8,
(149 + 2477) as u8,
(157 + 2459) as u8,
(163 + 2447) as u8,
(173 + 2423) as u8,
(179 + 2411) as u8,
(181 + 2399) as u8,
(191 + 2389) as u8,
(193 + 2383) as u8,
(197 + 2377) as u8,
(199 + 2371) as u8,
(211 + 2357) as u8,
(223 + 2347) as u8,
(227 + 2341) as u8,
(229 + 2339) as u8,
(233 + 2333) as u8,
];

#[bench]
Expand Down
19 changes: 18 additions & 1 deletion poisson/benches/dim4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rand::{rngs::SmallRng, SeedableRng};
extern crate nalgebra as na;
pub type Vect = na::Vector4<f64>;

const SEED: [u8; 16] = [
const SEED: [u8; 32] = [
(3 + 2741) as u8,
(7 + 2729) as u8,
(13 + 2713) as u8,
Expand All @@ -27,6 +27,23 @@ const SEED: [u8; 16] = [
(107 + 2549) as u8,
(113 + 2539) as u8,
(131 + 2521) as u8,
// Additional 16 bytes for 32-byte seed
(137 + 2503) as u8,
(149 + 2477) as u8,
(157 + 2459) as u8,
(163 + 2447) as u8,
(173 + 2423) as u8,
(179 + 2411) as u8,
(181 + 2399) as u8,
(191 + 2389) as u8,
(193 + 2383) as u8,
(197 + 2377) as u8,
(199 + 2371) as u8,
(211 + 2357) as u8,
(223 + 2347) as u8,
(227 + 2341) as u8,
(229 + 2339) as u8,
(233 + 2333) as u8,
];

#[bench]
Expand Down
Loading