first commit - hilbert 2d poly
This commit is contained in:
commit
ac732863d3
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
331
Cargo.lock
generated
Normal file
331
Cargo.lock
generated
Normal file
|
@ -0,0 +1,331 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hilbert"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"gif",
|
||||
"jpeg-decoder",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
"scoped_threadpool",
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
|
||||
dependencies = [
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
|
||||
dependencies = [
|
||||
"jpeg-decoder",
|
||||
"miniz_oxide 0.4.4",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "hilbert"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
image = "0.23.14"
|
141
src/main.rs
Normal file
141
src/main.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use image::{ImageBuffer, Rgb, RgbImage};
|
||||
|
||||
trait Distance<const N: usize> {
|
||||
fn dist(&self, a: [f64; N], b: [f64; N]) -> Result<f64, &'static str>;
|
||||
}
|
||||
|
||||
struct HilbertPoly {
|
||||
vertices: Vec<[f64; 2]>
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Euclidean<const N: usize>();
|
||||
|
||||
impl<const N: usize> Distance<N> for Euclidean<N> {
|
||||
fn dist(&self, a: [f64; N], b: [f64; N]) -> Result<f64, &'static str> {
|
||||
Ok(a.iter().zip(b.iter()).map(|x| (x.1 - x.0) * (x.1 - x.0)).sum::<f64>().sqrt())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Manhattan<const N: usize>();
|
||||
|
||||
impl<const N: usize> Distance<N> for Manhattan<N> {
|
||||
fn dist(&self, a: [f64; N], b: [f64; N]) -> Result<f64, &'static str> {
|
||||
Ok(a.iter().zip(b.iter()).map(|x| f64::abs(x.1 - x.0)).sum::<f64>())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Distance<N> for HilbertPoly {
|
||||
fn dist(&self, a: [f64; N], b: [f64; N]) -> Result<f64, &'static str> {
|
||||
|
||||
// 2d Hilbert Convex Polygon, 3d is slightly different as it will be to a side (edge of
|
||||
// convex set )
|
||||
if N != 2 {
|
||||
return Err("Dim != 2");
|
||||
};
|
||||
|
||||
// Get edges.
|
||||
let mut edges = self.vertices.windows(2).map(|x| [x[0], x[1]]).collect::<Vec<[[f64; 2]; 2]>>();
|
||||
edges.push([self.vertices[0], self.vertices[self.vertices.len() - 1]]);
|
||||
|
||||
// Assert that the Hilbert convex set is convex.
|
||||
let mut prev = 0.0;
|
||||
let mut curr;
|
||||
for i in 0..N {
|
||||
let edge_one = edges[i];
|
||||
let edge_two = edges[(i + 1) % N];
|
||||
curr = (edge_one[1][0] - edge_one[0][0]) * (edge_two[1][1] - edge_one[0][1]) -
|
||||
(edge_one[1][1] - edge_one[0][1]) * (edge_two[1][0] - edge_one[0][0]);
|
||||
if curr != 0.0 {
|
||||
if curr * prev < 0.0 {
|
||||
return Err("Not convex.");
|
||||
} else {
|
||||
prev = curr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if points are both inside the set
|
||||
let (mut i, mut j, mut c) = (0, self.vertices.len() - 1, false);
|
||||
loop {
|
||||
if i >= self.vertices.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((self.vertices[i][1] > a[1]) != (self.vertices[j][1] > a[1])) && (a[0] < (self.vertices[j][0] - self.vertices[i][0]) * (a[1] - self.vertices[i][1]) / (self.vertices[j][1] - self.vertices[i][1]) + self.vertices[i][0]) {
|
||||
c = !c;
|
||||
}
|
||||
j = i;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if !c {
|
||||
return Err("First point not in set.");
|
||||
}
|
||||
|
||||
|
||||
let (mut i, mut j, mut c) = (0, self.vertices.len() - 1, false);
|
||||
loop {
|
||||
if i >= self.vertices.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((self.vertices[i][1] > b[1]) != (self.vertices[j][1] > b[1])) && (b[0] < (self.vertices[j][0] - self.vertices[i][0]) * (b[1] - self.vertices[i][1]) / (self.vertices[j][1] - self.vertices[i][1]) + self.vertices[i][0]) {
|
||||
c = !c;
|
||||
}
|
||||
j = i;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if !c {
|
||||
return Err("Second point not in set.");
|
||||
}
|
||||
|
||||
// Intersect the line with each polygon side
|
||||
let slope = (b[1] - a[1]) / (b[0] - a[0]);
|
||||
let p_intersect = edges.into_iter().map(|p| {
|
||||
let edge_slope = (p[1][1] - p[0][1]) / (p[1][0] - p[0][0]);
|
||||
let d = edge_slope - slope;
|
||||
if d == 0.0 {
|
||||
None
|
||||
} else {
|
||||
Some([((edge_slope * p[0][0] - p[0][1]) - (slope * a[0] - a[1])) / d, ((slope * (edge_slope * p[0][0] - p[0][1])) - (edge_slope * (slope * a[0] - a[1]))) / d])
|
||||
}
|
||||
}).filter(|x| x.is_some()).map(|x| x.map_or([0.0, 0.0], |x| x)).collect::<Vec<[f64; 2]>>();
|
||||
|
||||
// Find the closest distance
|
||||
let a_closest = p_intersect.clone().into_iter().map(|p| (p, (p[0] - a[0]) * (p[0] - a[0]) + (p[1] - a[1]) * (p[1] - a[1]))).min_by(|a, b| a.1.partial_cmp(&b.1).unwrap()).unwrap();
|
||||
let b_closest = p_intersect.into_iter().map(|p| (p, (p[0] - b[0]) * (p[0] - b[0]) + (p[1] - b[1]) * (p[1] - b[1]))).min_by(|a, b| a.1.partial_cmp(&b.1).unwrap()).unwrap();
|
||||
|
||||
let pb = f64::sqrt((a_closest.0[0] - b[0]) * (a_closest.0[0] - b[0]) + (a_closest.0[1] - b[1]) * (a_closest.0[1] - b[1]));
|
||||
let pa = f64::sqrt(a_closest.1);
|
||||
let aq = f64::sqrt((b_closest.0[0] - a[0]) * (b_closest.0[0] - a[0]) + (b_closest.0[1] - a[1]) * (b_closest.0[1] - a[1]));
|
||||
let bq = f64::sqrt(b_closest.1);
|
||||
|
||||
Ok(f64::ln((pb * aq) / (pa * bq)))
|
||||
}
|
||||
}
|
||||
|
||||
fn naive_voronoi_2d(metric: &mut dyn Distance<2>, w: u32, h: u32, points: Vec<(u32, u32)>) {
|
||||
let mut image: RgbImage = ImageBuffer::new(w, h);
|
||||
// All points must be in the width / height
|
||||
for p in points {
|
||||
assert!(p.0 <= w);
|
||||
assert!(p.1 <= h);
|
||||
}
|
||||
|
||||
for i in 0..w {
|
||||
for j in 0..h {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let triangle = HilbertPoly { vertices: vec![[-8.0, 0.0], [8.0, 0.0], [0.0, 8.0]] };
|
||||
println!("{}", triangle.dist([-2.0, 2.0], [2.0, 2.0]).unwrap());
|
||||
}
|
Loading…
Reference in New Issue
Block a user