Basic Delaunay triangulation
This commit is contained in:
commit
3be8db1fdc
8
.editorconfig
Normal file
8
.editorconfig
Normal file
|
@ -0,0 +1,8 @@
|
|||
[*.rs]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = false
|
||||
max_line_length = 90
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
431
Cargo.lock
generated
Normal file
431
Cargo.lock
generated
Normal file
|
@ -0,0 +1,431 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
||||
|
||||
[[package]]
|
||||
name = "audir-sles"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea47348666a8edb7ad80cbee3940eb2bccf70df0e6ce09009abe1a836cb779f5"
|
||||
|
||||
[[package]]
|
||||
name = "audrey"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58b92a84e89497e3cd25d3672cd5d1c288abaac02c18ff21283f17d118b889b8"
|
||||
dependencies = [
|
||||
"dasp_frame",
|
||||
"dasp_sample",
|
||||
"hound",
|
||||
"lewton",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
|
||||
[[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.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dasp_frame"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2a3937f5fe2135702897535c8d4a5553f8b116f76c1529088797f2eee7c5cd6"
|
||||
dependencies = [
|
||||
"dasp_sample",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dasp_sample"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdue"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75712fff1702bac51b7eaa5a5ca9f9853b8055ef5906088a32f4fe196595a1d"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "333928d5eb103c5d4050533cec0384302db6be8ef7d3cebd30ec6a35350353da"
|
||||
|
||||
[[package]]
|
||||
name = "glow"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"macroquad",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hound"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lewton"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d542c1a317036c45c2aa1cf10cc9d403ca91eb2d333ef1a4917e5cb10628bd0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"ogg",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
||||
|
||||
[[package]]
|
||||
name = "macroquad"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54a31d3996831b27b429f8e9d7b948aa589d3571305eba39f57b4600bd2cd01"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"fontdue",
|
||||
"glam",
|
||||
"image",
|
||||
"macroquad_macro",
|
||||
"miniquad",
|
||||
"quad-rand",
|
||||
"quad-snd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macroquad_macro"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5cecfede1e530599c8686f7f2d609489101d3d63741a6dc423afc997ce3fcc8"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "miniquad"
|
||||
version = "0.3.0-alpha.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6793a3ef846953fc7c01302093abf8749be22742c63db05c66ef0a2c889a7fbb"
|
||||
dependencies = [
|
||||
"sapp-android",
|
||||
"sapp-darwin",
|
||||
"sapp-dummy",
|
||||
"sapp-ios",
|
||||
"sapp-linux",
|
||||
"sapp-wasm",
|
||||
"sapp-windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
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.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ogg"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e571c3517af9e1729d4c63571a27edd660ade0667973bfc74a67c660c2b651"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quad-alsa-sys"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66c2f04a6946293477973d85adc251d502da51c57b08cd9c997f0cfd8dcd4b5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quad-rand"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658fa1faf7a4cc5f057c9ee5ef560f717ad9d8dc66d975267f709624d6e1ab88"
|
||||
|
||||
[[package]]
|
||||
name = "quad-snd"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86e0b4259cfd6a317a46df7b7cb4c09a08ba150642e6f6fb7df5a6b3450a0a29"
|
||||
dependencies = [
|
||||
"audir-sles",
|
||||
"audrey",
|
||||
"libc",
|
||||
"quad-alsa-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-android"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a4a81f462ba2783213978528560aa138adf2f94da1ac940c1b5c854c03e1724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"ndk-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-darwin"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0310e2445f307468aa13f1cde94d6fba6b8fd329afbb642dedbe3faf1a145f31"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-dummy"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66f1ad26a5b6c682b9ca27c66db9aa91002b8d98a82ac7101ded57285215a478"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-ios"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "081e6e5261c9ac2e938979b6a854a53b439f065fc3c897205ce7e69d3028b4a9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-linux"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbdb2f8011955c62544d9e626a58333e788810d00bd7411d52b81611b92af142"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sapp-wasm"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00e859e8645a3bcb85aecd40bab883438e4105f21b21bccbeac2348760f508bb"
|
||||
|
||||
[[package]]
|
||||
name = "sapp-windows"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8faec983cb54ce5e9529815fc0aae6c36bab9fba9cd0ae5590dfa17bc0719fa"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
|
||||
dependencies = [
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "glow"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
macroquad = "0.3"
|
||||
#itertools = "0.10.1"
|
283
src/main.rs
Normal file
283
src/main.rs
Normal file
|
@ -0,0 +1,283 @@
|
|||
use std::collections::HashSet;
|
||||
use core::f32::consts::PI;
|
||||
use macroquad::prelude::draw_circle_lines;
|
||||
use macroquad::prelude::mouse_position;
|
||||
use macroquad::prelude::is_mouse_button_pressed;
|
||||
use macroquad::prelude::Vec2;
|
||||
use core::ops::DerefMut;
|
||||
use core::ops::Deref;
|
||||
use macroquad::prelude::draw_line;
|
||||
use core::hash::Hasher;
|
||||
use core::hash::Hash;
|
||||
use macroquad::prelude::screen_height;
|
||||
use macroquad::prelude::next_frame;
|
||||
use macroquad::prelude::screen_width;
|
||||
use macroquad::prelude::draw_circle;
|
||||
use macroquad::prelude::clear_background;
|
||||
use macroquad::prelude::Color;
|
||||
use macroquad::input::MouseButton;
|
||||
use std::sync::Arc;
|
||||
|
||||
const BG: Color = Color::new(0.16863, 0.23922, 0.21176, 1.0);
|
||||
const FG: Color = Color::new(0.91569, 0.71765, 0.00000, 1.0);
|
||||
const DIM_FG: Color = Color::new(0.29412, 0.27451, 0.13333, 1.0);
|
||||
const HIL_FG: Color = Color::new(0.25806, 0.61290, 1.09032, 1.0);
|
||||
|
||||
#[macroquad::main("BasicShapes")]
|
||||
async fn main() {
|
||||
let mut dd = DelaunayDemo::default();
|
||||
loop {
|
||||
if is_mouse_button_pressed(MouseButton::Left) {
|
||||
dd.click(mouse_position().into())
|
||||
}
|
||||
dd.draw();
|
||||
next_frame().await;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DelaunayDemo {
|
||||
pub nodes: Vec<Arc<Node>>,
|
||||
pub triangles: Vec<Triangle>,
|
||||
pub edges: Vec<Edge>,
|
||||
}
|
||||
|
||||
impl Default for DelaunayDemo {
|
||||
fn default() -> Self {
|
||||
let nodes: Vec<Arc<Node>> = vec![
|
||||
Arc::new((0.0, 0.0).into()),
|
||||
Arc::new((0.0, screen_height()).into()),
|
||||
Arc::new((screen_width(), 0.0).into()),
|
||||
Arc::new((screen_width(), screen_height()).into()),
|
||||
];
|
||||
let edges = vec![
|
||||
Edge(nodes[2].clone(), nodes[0].clone()),
|
||||
Edge(nodes[0].clone(), nodes[1].clone()),
|
||||
Edge(nodes[1].clone(), nodes[2].clone()),
|
||||
Edge(nodes[2].clone(), nodes[3].clone()),
|
||||
Edge(nodes[3].clone(), nodes[1].clone()),
|
||||
];
|
||||
let triangles = vec![
|
||||
Triangle::new(
|
||||
[edges[0].clone(), edges[1].clone(), edges[2].clone()],
|
||||
),
|
||||
Triangle::new(
|
||||
[edges[2].clone(), edges[3].clone(), edges[4].clone()],
|
||||
),
|
||||
];
|
||||
DelaunayDemo {
|
||||
nodes, edges, triangles,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Node(Vec2);
|
||||
|
||||
impl Deref for Node {
|
||||
type Target = Vec2;
|
||||
|
||||
fn deref(&self) -> &Vec2 {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Node {
|
||||
fn deref_mut(&mut self) -> &mut Vec2 {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(f32, f32)> for Node {
|
||||
fn from((x, y): (f32, f32)) -> Node {
|
||||
Node(Vec2::new(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Edge(Arc<Node>, Arc<Node>);
|
||||
|
||||
impl PartialEq for Edge {
|
||||
fn eq(&self, other: &Edge) -> bool {
|
||||
let mut our_ptrs = [
|
||||
Arc::as_ptr(&self.0),
|
||||
Arc::as_ptr(&self.1),
|
||||
];
|
||||
let mut other_ptrs = [
|
||||
Arc::as_ptr(&other.0),
|
||||
Arc::as_ptr(&other.1),
|
||||
];
|
||||
our_ptrs.sort_unstable();
|
||||
other_ptrs.sort_unstable();
|
||||
|
||||
our_ptrs[0] == other_ptrs[0] && our_ptrs[1] == other_ptrs[1]
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Edge {}
|
||||
|
||||
impl Hash for Edge {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let mut ptrs = [
|
||||
Arc::as_ptr(&self.0),
|
||||
Arc::as_ptr(&self.1),
|
||||
];
|
||||
ptrs.sort_unstable();
|
||||
ptrs.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Triangle {
|
||||
nodes: [Arc<Node>; 3],
|
||||
edges: [Edge; 3],
|
||||
circumcenter: Vec2,
|
||||
radius: f32,
|
||||
}
|
||||
|
||||
impl Triangle {
|
||||
pub fn new(edges: [Edge; 3]) -> Triangle {
|
||||
let nodes = [
|
||||
edges[0].0.clone(),
|
||||
edges[0].1.clone(),
|
||||
if Arc::ptr_eq(&edges[1].0, &edges[0].0) || Arc::ptr_eq(&edges[1].0, &edges[0].1) {
|
||||
edges[1].1.clone()
|
||||
} else {
|
||||
edges[1].0.clone()
|
||||
}
|
||||
];
|
||||
let circumcenter = Self::circumcenter(**nodes[0], **nodes[1], **nodes[2]);
|
||||
let radius = circumcenter.distance(**nodes[0]);
|
||||
Triangle {
|
||||
nodes,
|
||||
edges,
|
||||
circumcenter,
|
||||
radius,
|
||||
}
|
||||
}
|
||||
|
||||
fn circumcenter(a: Vec2, b: Vec2, c: Vec2) -> Vec2 {
|
||||
let len_a = b.distance(c);
|
||||
let len_b = c.distance(a);
|
||||
let len_c = a.distance(b);
|
||||
|
||||
let cos_a = (len_b.powf(2.0) + len_c.powf(2.0) - len_a.powf(2.0)) / (2.0 * len_b * len_c );
|
||||
let cos_b = (len_c.powf(2.0) + len_a.powf(2.0) - len_b.powf(2.0)) / (2.0 * len_c * len_a );
|
||||
|
||||
let ang_a = f32::acos(cos_a);
|
||||
let ang_b = f32::acos(cos_b);
|
||||
let ang_c = PI - ang_a - ang_b;
|
||||
|
||||
let sin_2a = f32::sin(2.0 * ang_a);
|
||||
let sin_2b = f32::sin(2.0 * ang_b);
|
||||
let sin_2c = f32::sin(2.0 * ang_c);
|
||||
|
||||
Vec2::new(
|
||||
(a.x * sin_2a + b.x * sin_2b + c.x * sin_2c) / (sin_2a + sin_2b + sin_2c),
|
||||
(a.y * sin_2a + b.y * sin_2b + c.y * sin_2c) / (sin_2a + sin_2b + sin_2c),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn invalidated_by_point(&self, point: Vec2) -> bool {
|
||||
self.circumcenter.distance(point) < self.radius
|
||||
}
|
||||
}
|
||||
|
||||
impl DelaunayDemo {
|
||||
fn draw(&self) {
|
||||
clear_background(BG);
|
||||
let mut danger_lines = Vec::with_capacity(3);
|
||||
for triangle in &self.triangles {
|
||||
let c = triangle.circumcenter;
|
||||
let color = if c.distance(mouse_position().into()) < triangle.radius {
|
||||
danger_lines.extend(&triangle.edges);
|
||||
DIM_FG //HIL_FG
|
||||
} else {
|
||||
DIM_FG
|
||||
};
|
||||
draw_circle_lines(c.x, c.y, triangle.radius, 1.0, color);
|
||||
}
|
||||
for edge in &self.edges {
|
||||
let color = if danger_lines.contains(&edge) {
|
||||
FG //HIL_FG
|
||||
} else {
|
||||
FG
|
||||
};
|
||||
draw_line(edge.0.x, edge.0.y, edge.1.x, edge.1.y, 3.0, color);
|
||||
}
|
||||
for node in &self.nodes {
|
||||
draw_circle(node.x, node.y, 10.0, FG);
|
||||
}
|
||||
}
|
||||
|
||||
fn click(&mut self, pos: Vec2) {
|
||||
self.add_point(Node(pos));
|
||||
}
|
||||
|
||||
fn add_point(&mut self, node: Node) {
|
||||
|
||||
// Remove invalid triangles and coalesce their edges
|
||||
let mut bad_triangle_sides: Vec<_> = Vec::with_capacity(self.triangles.len() * 3);
|
||||
let mut i = 0;
|
||||
while i < self.triangles.len() {
|
||||
let triangle = &self.triangles[i];
|
||||
if triangle.invalidated_by_point(*node) {
|
||||
bad_triangle_sides.extend(
|
||||
self.triangles.remove(i).edges
|
||||
);
|
||||
} else {
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// For every edge
|
||||
|
||||
// If it has a duplicate later in the list
|
||||
|
||||
// Remove the edge from existance
|
||||
|
||||
// Otherwise
|
||||
|
||||
// Form a new triangle with that edge and this point
|
||||
|
||||
let node = Arc::new(node);
|
||||
let mut new_edges = HashSet::with_capacity(bad_triangle_sides.len());
|
||||
i = 0;
|
||||
while i < bad_triangle_sides.len() {
|
||||
let edge = &bad_triangle_sides[i];
|
||||
let other_edge_i = bad_triangle_sides[(i + 1)..].iter()
|
||||
.position(|other_edge| edge == other_edge);
|
||||
|
||||
if let Some(other_edge_i) = other_edge_i {
|
||||
bad_triangle_sides.remove(other_edge_i + i + 1);
|
||||
i = i + 1;
|
||||
} else {
|
||||
let edge = bad_triangle_sides.remove(i);
|
||||
let new_edge_a = Edge(edge.0.clone(), node.clone());
|
||||
let new_edge_b = Edge(edge.1.clone(), node.clone());
|
||||
self.triangles.push(Triangle::new([
|
||||
edge,
|
||||
new_edge_a.clone(),
|
||||
new_edge_b.clone(),
|
||||
]));
|
||||
new_edges.extend([new_edge_a, new_edge_b]);
|
||||
}
|
||||
}
|
||||
self.edges.retain(|e| !bad_triangle_sides.iter().any(|bad_e| e == bad_e));
|
||||
self.edges.extend(new_edges);
|
||||
self.nodes.push(node);
|
||||
}
|
||||
|
||||
/*fn move_point(&mut self, node: Arc<Node>) {
|
||||
|
||||
// Update position
|
||||
|
||||
// Check for broken triangles
|
||||
|
||||
// Remove triange
|
||||
|
||||
// Remove triangle consisting of common points + self
|
||||
|
||||
// Form triangle consisting of common point A + self + opposite
|
||||
|
||||
// Form triangle consisting of common point B + self + opposite
|
||||
}*/
|
||||
}
|
0
src/util.rs
Normal file
0
src/util.rs
Normal file
Loading…
Reference in a new issue