diff --git a/Cargo.lock b/Cargo.lock index 080cd68..be479e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,18 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] [[package]] name = "allocator-api2" @@ -10,9 +22,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "approx" @@ -30,10 +42,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] -name = "bitflags" -version = "2.13.0" +name = "bytemuck" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" @@ -47,26 +59,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" -dependencies = [ - "cfg-if", - "cpufeatures", - "rand_core", -] - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -107,7 +99,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01" dependencies = [ - "itertools", + "itertools 0.11.0", "num-traits", ] @@ -117,35 +109,22 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - [[package]] name = "float_next_after" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "geo" -version = "0.30.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4416397671d8997e9a3e7ad99714f4f00a22e9eaa9b966a5985d2194fc9e02e1" +checksum = "f811f663912a69249fa620dcd2a005db7254529da2d8a0b23942e81f47084501" dependencies = [ "earcutr", "float_next_after", "geo-types", "geographiclib-rs", - "i_overlay", "log", "num-traits", "robust 1.1.0", @@ -155,13 +134,12 @@ dependencies = [ [[package]] name = "geo-types" -version = "0.7.19" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94776032c45f950d30a13af6113c2ad5625316c9abfbccee4dd5a6695f8fe0f5" +checksum = "9ff16065e5720f376fbced200a5ae0f47ace85fd70b7e54269790281353b6d61" dependencies = [ "approx", "num-traits", - "rayon", "rstar", "serde", ] @@ -177,16 +155,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", - "r-efi", - "rand_core", - "wasip2", - "wasip3", + "wasi", ] [[package]] @@ -200,21 +175,14 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ + "ahash", "allocator-api2", - "equivalent", - "foldhash", ] -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - [[package]] name = "heapless" version = "0.8.0" @@ -225,74 +193,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "i_float" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85df3a416829bb955fdc2416c7b73680c8dcea8d731f2c7aa23e1042fe1b8343" -dependencies = [ - "serde", -] - -[[package]] -name = "i_key_sort" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347c253b4748a1a28baf94c9ce133b6b166f08573157e05afe718812bc599fcd" - -[[package]] -name = "i_overlay" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0542dfef184afdd42174a03dcc0625b6147fb73e1b974b1a08a2a42ac35cee49" -dependencies = [ - "i_float", - "i_key_sort", - "i_shape", - "i_tree", - "rayon", -] - -[[package]] -name = "i_shape" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a38f5a42678726718ff924f6d4a0e79b129776aeed298f71de4ceedbd091bce" -dependencies = [ - "i_float", - "serde", -] - -[[package]] -name = "i_tree" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155181bc97d770181cf9477da51218a19ee92a8e5be642e796661aee2b601139" - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", -] - [[package]] name = "itertools" version = "0.11.0" @@ -303,22 +203,25 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.18" +name = "itertools" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] [[package]] -name = "leb128fmt" -version = "0.1.0" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -333,10 +236,72 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] -name = "memchr" -version = "2.8.1" +name = "matrixmultiply" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "nalgebra" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d506eb7e08d6329505faa8a3a00a5dcc6de9f76e0c77e4b75763ae3c770831ff" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "rand", + "rand_distr", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] [[package]] name = "num-traits" @@ -349,20 +314,28 @@ dependencies = [ ] [[package]] -name = "prettyplease" -version = "0.2.37" +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -377,33 +350,56 @@ dependencies = [ ] [[package]] -name = "r-efi" -version = "6.0.0" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] [[package]] -name = "rand" -version = "0.10.1" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "chacha20", - "getrandom", + "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" -version = "0.10.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.12.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -411,9 +407,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.13.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -443,52 +439,55 @@ dependencies = [ ] [[package]] -name = "semver" -version = "1.0.28" +name = "safe_arch" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" dependencies = [ - "serde_core", - "serde_derive", + "bytemuck", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "serde" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.55", ] [[package]] -name = "serde_json" -version = "1.0.150" +name = "simba" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "f0b7840f121a46d63066ee7a99fc81dcabbc6105e437cae43528cea199b5a05f" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "simple_delaunay_lib" +version = "0.2.0" +source = "git+https://github.com/ibujah/simple_delaunay_lib#2812ea85f936723bb9ae3a1cd131589738b41821" +dependencies = [ + "anyhow", + "log", + "robust 1.1.0", ] [[package]] @@ -499,11 +498,11 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "spade" -version = "2.14.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a14e31a007e9f85c32784b04f89e6e194bb252a4d41b4a8ccd9e77245d901c8c" +checksum = "61addf9117b11d1f5b4bf6fe94242ba25f59d2d4b2080544b771bd647024fd00" dependencies = [ - "hashbrown 0.15.5", + "hashbrown", "num-traits", "robust 1.1.0", "smallvec", @@ -516,16 +515,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "syn" -version = "2.0.117" +name = "statrs" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "2d08e5e1748192713cc281da8b16924fb46be7b0c2431854eadc785823e5696e" +dependencies = [ + "approx", + "lazy_static", + "nalgebra", + "num-traits", + "rand", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -533,155 +562,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unicode-xid" -version = "0.2.6" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "wasip2" -version = "1.0.3+wasi-0.2.9" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wide" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "bytemuck", + "safe_arch", ] [[package]] @@ -690,12 +589,30 @@ version = "0.1.4" dependencies = [ "delaunator", "geo", + "geo-types", + "itertools 0.12.1", "rand", "rayon", + "simple_delaunay_lib", + "statrs", ] [[package]] -name = "zmij" -version = "1.0.21" +name = "zerocopy" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] diff --git a/Cargo.toml b/Cargo.toml index f89cbbb..19cfd20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,21 @@ [package] name = "xenobalanus" -version = "0.2.0" +version = "0.1.4" edition = "2021" -authors = ["Tobias Raayoni Last "] -repository = "https://github.com/randogoth/xenobalanus" -readme = "readme.md" -license = "MIT" -license-file = "LICENSE" -keywords = ["dtscan", "dbscan", "delfin", "cluster", "void", "delaunay", "astronomy", "attractor"] -categories = ["algorithms", "science", "mathematics"] [lib] name = "xenobalanus" +[features] +default = ["three-d"] +three-d = ["dep:simple_delaunay_lib"] + [dependencies] delaunator = "1.0.2" -geo = "0.30" -rand = "0.10" -rayon = "1.12" +geo = "0.28.0" +geo-types = "0.7.13" +itertools = "0.12.1" +rand = "0.8.5" +rayon = "1.9.0" +statrs = "0.16.0" +simple_delaunay_lib = { version = "0.2.0", git = "https://github.com/ibujah/simple_delaunay_lib", optional = true } \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 4763a89..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Tobias Raayoni Last - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/devbox.json b/devbox.json deleted file mode 100644 index c8f865f..0000000 --- a/devbox.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json", - "packages": ["rustup@latest"], - "shell": { - "init_hook": [ - "echo 'Welcome to devbox!' > /dev/null" - ], - "scripts": { - "test": [ - "echo \"Error: no test specified\" && exit 1" - ] - } - } -} diff --git a/devbox.lock b/devbox.lock deleted file mode 100644 index 818bec3..0000000 --- a/devbox.lock +++ /dev/null @@ -1,58 +0,0 @@ -{ - "lockfile_version": "1", - "packages": { - "github:NixOS/nixpkgs/nixpkgs-unstable": { - "last_modified": "2026-05-29T05:01:12Z", - "resolved": "github:NixOS/nixpkgs/e9a7635a57597d9754eccebdfc7045e6c8600e6b?lastModified=1780030872&narHash=sha256-u6WU%2Fyd%2Fo8iYQrHX3RAwO1hYa3LkoSL%2BWNQD0rJfJZQ%3D" - }, - "rustup@latest": { - "last_modified": "2026-05-21T08:15:18Z", - "plugin_version": "0.0.1", - "resolved": "github:NixOS/nixpkgs/4a29d733e8a7d5b824c3d8c958a946a9867b3eb2#rustup", - "source": "devbox-search", - "version": "1.29.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/nl70ay30nl2szm2g03xa0d7ai69dgbln-rustup-1.29.0", - "default": true - } - ], - "store_path": "/nix/store/nl70ay30nl2szm2g03xa0d7ai69dgbln-rustup-1.29.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/684175m8xqfisacqw9rdc97fn2vpp0fj-rustup-1.29.0", - "default": true - } - ], - "store_path": "/nix/store/684175m8xqfisacqw9rdc97fn2vpp0fj-rustup-1.29.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/4hqncs7jnqc64z49r1w09b235074li9q-rustup-1.29.0", - "default": true - } - ], - "store_path": "/nix/store/4hqncs7jnqc64z49r1w09b235074li9q-rustup-1.29.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/dpqx1vygrisrvnnwgym1226x317vqp4a-rustup-1.29.0", - "default": true - } - ], - "store_path": "/nix/store/dpqx1vygrisrvnnwgym1226x317vqp4a-rustup-1.29.0" - } - } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index d9b71a1..5873ad8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,35 +1,15 @@ -/* -MIT License - -Copyright (c) 2024 Tobias Raayoni Last - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - use delaunator::{triangulate, Point as DelaunatorPoint}; use geo::{Point as GeoPoint, Coord}; -use rand::RngExt; +use rand::Rng; use rayon::prelude::*; use std::cmp::{min, max}; use std::collections::{HashMap, HashSet}; use std::sync::{Arc, Mutex}; +#[cfg(feature = "three-d")] +use simple_delaunay_lib::delaunay_3d::delaunay_struct_3d::DelaunayStructure3D; +mod threedee; + #[derive(Debug, Clone, Copy)] pub struct Point { pub x: f32, @@ -196,6 +176,9 @@ pub struct Xenobalanus { geometry_data: GeometryData, points: Vec, triangulation: Vec, + #[cfg(feature = "three-d")] + nodes: Vec, + tetrahedra: DelaunayStructure3D, } impl Xenobalanus { @@ -204,6 +187,9 @@ impl Xenobalanus { geometry_data: GeometryData::new(), points: Vec::new(), triangulation: Vec::new(), + #[cfg(feature = "three-d")] + nodes: Vec::new(), + tetrahedra: DelaunayStructure3D::new(), } } @@ -265,10 +251,10 @@ impl Xenobalanus { let max_x = center.0 + side_length / 2.0; let min_y = center.1 - side_length / 2.0; let max_y = center.1 + side_length / 2.0; - let mut rng = rand::rng(); + let mut rng: rand::prelude::ThreadRng = rand::thread_rng(); for _ in 0..num_points { - let x = min_x + rng.random_range(0.0..=1.0) as f32 * ( max_x - min_x); - let y: f32 = min_y + rng.random_range(0.0..=1.0) as f32 * ( max_y - min_y); + let x = min_x + rng.gen_range(0.0..=1.0) as f32 * ( max_x - min_x); + let y: f32 = min_y + rng.gen_range(0.0..=1.0) as f32 * ( max_y - min_y); self.points.push(Point {x, y}); } } @@ -454,142 +440,4 @@ impl Xenobalanus { clusters } -} - -#[cfg(test)] -mod tests { - use super::*; - - // --- Point --- - - #[test] - fn point_distance_3_4_5() { - let a = Point::new(0.0, 0.0); - let b = Point::new(3.0, 4.0); - assert!((a.distance(b) - 5.0).abs() < 1e-5); - } - - #[test] - fn point_bearing_east_is_zero() { - let origin = Point::new(0.0, 0.0); - let east = Point::new(1.0, 0.0); - // delta_y=0, delta_x=1 → atan2(0,1)=0° → bearing=0° - assert!((origin.bearing(east) - 0.0).abs() < 1e-4); - } - - // --- random_points --- - - #[test] - fn random_points_count_and_bounds() { - let mut xb = Xenobalanus::new(); - xb.random_points((0.0, 0.0), 10.0, 100); - let pts = xb.points(); - assert_eq!(pts.len(), 100); - for (x, y) in pts { - assert!(x >= -5.0 && x <= 5.0, "x={x} out of [-5, 5]"); - assert!(y >= -5.0 && y <= 5.0, "y={y} out of [-5, 5]"); - } - } - - // --- delaunay --- - - fn unit_square() -> Vec { - vec![ - Point::new(0.0, 0.0), - Point::new(1.0, 0.0), - Point::new(1.0, 1.0), - Point::new(0.0, 1.0), - ] - } - - #[test] - fn delaunay_four_points_two_triangles() { - let mut xb = Xenobalanus::new(); - xb.set_points(unit_square()); - xb.delaunay(); - // 4 convex points → 2 triangles → 6 indices - assert_eq!(xb.triangles_flat().len(), 6); - } - - // --- preprocess --- - - #[test] - fn preprocess_sequential_builds_edges() { - let mut xb = Xenobalanus::new(); - xb.set_points(unit_square()); - xb.delaunay(); - xb.preprocess(0, false); - // unit square Delaunay: 4 boundary edges + 1 diagonal = 5 - assert_eq!(xb.edge_lengths().len(), 5); - } - - #[test] - fn preprocess_parallel_matches_sequential() { - let mut xb_seq = Xenobalanus::new(); - xb_seq.set_points(unit_square()); - xb_seq.delaunay(); - xb_seq.preprocess(0, false); - - let mut xb_par = Xenobalanus::new(); - xb_par.set_points(unit_square()); - xb_par.delaunay(); - xb_par.preprocess(0, true); - - assert_eq!(xb_seq.edge_lengths().len(), xb_par.edge_lengths().len()); - } - - // --- dtscan --- - - #[test] - fn dtscan_finds_cluster_in_grid() { - let mut xb = Xenobalanus::new(); - // 3×3 grid with spacing 1.0; diagonal ≈ 1.414 - let pts: Vec = (0..3) - .flat_map(|i| (0..3).map(move |j| Point::new(i as f32, j as f32))) - .collect(); - xb.set_points(pts); - xb.delaunay(); - xb.preprocess(0, false); - // max_closeness=1.5 covers all edges (max diagonal ≈ 1.414) - let clusters = xb.dtscan(2, 1.5); - assert!(!clusters.is_empty()); - } - - // --- delfin --- - - #[test] - fn delfin_smoke_test() { - let mut xb = Xenobalanus::new(); - xb.random_points((0.0, 0.0), 100.0, 200); - xb.delaunay(); - xb.preprocess(2, false); - // just verify it runs without panic - let _voids = xb.delfin(0.0, 0.0); - } - - // --- readme example --- - - #[test] - fn readme_example_pipeline() { - // Mirrors the workflow shown in the README exactly. - let dots: u32 = 10000; - let side_length: f32 = 10000.0; - let mut xeno = Xenobalanus::new(); - xeno.random_points((0.0, 0.0), side_length, dots); - - xeno.delaunay(); - xeno.preprocess(0, false); - - let min_area: f32 = 1000.0; - let min_distance: f32 = 200.0; - let void_polygons: Vec> = xeno.delfin(min_area, min_distance); - - let min_pts: usize = 5; - let max_closeness: f32 = 100.5; - let clusters: Vec> = xeno.dtscan(min_pts, max_closeness); - - // With 10 000 uniform random points both algorithms should find results. - assert!(!void_polygons.is_empty(), "delfin found no voids"); - assert!(!clusters.is_empty(), "dtscan found no clusters"); - } } \ No newline at end of file diff --git a/src/threedee.rs b/src/threedee.rs new file mode 100644 index 0000000..14151a2 --- /dev/null +++ b/src/threedee.rs @@ -0,0 +1,255 @@ +use rand::Rng; +use simple_delaunay_lib::delaunay_3d::delaunay_struct_3d::ExtendedTetrahedron; +use simple_delaunay_lib::delaunay_3d::simplicial_struct_3d::Node; +use std::cmp::{min, max}; +use std::collections::HashSet; + +use super::{Edge, Xenobalanus}; + +#[derive(Debug, Clone, Copy)] +pub struct Point3D { + pub x: f32, + pub y: f32, + pub z: f32, +} + +impl Point3D { + + pub fn new(coords: (f32, f32, f32)) -> Point3D { + Point3D {x: coords.0, y: coords.1, z: coords.2 } + } + + pub fn arr(&self) -> [f64; 3] { + [self.x as f64, self.y as f64, self.z as f64] + } + + pub fn distance(&self,point: &Point3D) -> f32 { + ( + (point.x - &self.x).powi(2) + + (point.y - &self.y).powi(2) + + (point.z - &self.z).powi(2) + ).sqrt() + } +} + +impl Xenobalanus { + + pub fn point_3d(&self, index: usize) -> Point3D { + self.nodes[index] + } + + pub fn points_3d(&self) -> Vec<(f32, f32, f32)> { + self.nodes.iter() + .map(|point| (point.x, point.y, point.z)) + .collect() + } + + pub fn tetrahedra(&self) -> Vec<[[f32; 3]; 2]> { + let total = self.tetrahedra.get_simplicial().get_nb_tetrahedra(); + let mut edges: Vec<[[f32; 3]; 2]> = vec![]; + for idx in 0..total { + match self.tetrahedra.get_extended_tetrahedron(idx) { + Ok(tet) => { + match tet { + ExtendedTetrahedron::Tetrahedron(te) => { + edges.push([ + [te[0][0] as f32, te[0][1] as f32, te[0][2] as f32], + [te[1][0] as f32, te[1][1] as f32, te[1][2] as f32] + ]); + edges.push([ + [te[1][0] as f32, te[1][1] as f32, te[1][2] as f32], + [te[2][0] as f32, te[2][1] as f32, te[2][2] as f32] + ]); + edges.push([ + [te[2][0] as f32, te[2][1] as f32, te[2][2] as f32], + [te[0][0] as f32, te[0][1] as f32, te[0][2] as f32] + ]); + edges.push([ + [te[3][0] as f32, te[3][1] as f32, te[3][2] as f32], + [te[0][0] as f32, te[0][1] as f32, te[0][2] as f32] + ]); + edges.push([ + [te[3][0] as f32, te[3][1] as f32, te[3][2] as f32], + [te[1][0] as f32, te[1][1] as f32, te[1][2] as f32] + ]); + edges.push([ + [te[3][0] as f32, te[3][1] as f32, te[3][2] as f32], + [te[2][0] as f32, te[2][1] as f32, te[2][2] as f32] + ]); + }, + ExtendedTetrahedron::Triangle(te) => { + edges.push([ + [te[0][0] as f32, te[0][1] as f32, te[0][2] as f32], + [te[1][0] as f32, te[1][1] as f32, te[1][2] as f32] + ]); + edges.push([ + [te[1][0] as f32, te[1][1] as f32, te[1][2] as f32], + [te[2][0] as f32, te[2][1] as f32, te[2][2] as f32] + ]); + edges.push([ + [te[2][0] as f32, te[2][1] as f32, te[2][2] as f32], + [te[0][0] as f32, te[0][1] as f32, te[0][2] as f32] + ]); + } + } + }, + Err(_) => { + println!("Error getting tetrahedron at index {}", idx); + continue; + } + } + } + edges + } + + pub fn random_points_3d(&mut self, center: (f32, f32, f32), side_length: f32, num_points: u32) { + + // generate random points in a cube + let min_x = center.0 - side_length / 2.0; + let max_x = center.0 + side_length / 2.0; + let min_y = center.1 - side_length / 2.0; + let max_y = center.1 + side_length / 2.0; + let min_z = center.2 - side_length / 2.0; + let max_z = center.2 + side_length / 2.0; + let mut rng: rand::prelude::ThreadRng = rand::thread_rng(); + for _ in 0..num_points { + let x = min_x + rng.gen_range(0.0..=1.0) as f32 * ( max_x - min_x); + let y: f32 = min_y + rng.gen_range(0.0..=1.0) as f32 * ( max_y - min_y); + let z: f32 = min_y + rng.gen_range(0.0..=1.0) as f32 * ( max_z - min_z); + self.nodes.push(Point3D {x, y, z}); + } + } + + pub fn delaunay_3d(&mut self) { + + let vertices: Vec<[f64; 3]> = self.nodes.iter().map(|node| { + node.arr() + }).collect(); + self.tetrahedra.insert_vertices(&vertices, true).unwrap_or_default(); + } + + pub fn add_triangle(&mut self, vertex1: usize, vertex2: usize, vertex3: usize) { + + let p1 = self.tetrahedra.get_vertices()[vertex1]; + let p2 = self.tetrahedra.get_vertices()[vertex2]; + let p3 = self.tetrahedra.get_vertices()[vertex3]; + + let n1 = Point3D::new((p1[0] as f32, p1[1] as f32, p1[2] as f32)); + let n2 = Point3D::new((p2[0] as f32, p2[1] as f32, p2[2] as f32)); + let n3 = Point3D::new((p3[0] as f32, p3[1] as f32, p3[2] as f32)); + + let l12 = n1.distance(&n2); + let l23 = n2.distance(&n3); + let l31 = n3.distance(&n1); + + let edge12 = Edge(min(vertex1, vertex2), max(vertex1, vertex2)); + let edge23 = Edge(min(vertex2, vertex3), max(vertex2, vertex3)); + let edge31 = Edge(min(vertex3, vertex1), max(vertex3, vertex1)); + + self.geometry_data.edge_lengths.insert(edge12, l12); + self.geometry_data.edge_lengths.insert(edge23, l23); + self.geometry_data.edge_lengths.insert(edge31, l31); + + self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex2); + self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex1); + + self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex3); + self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex2); + + self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex1); + self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex3); + + } + + pub fn add_tetrahedron(&mut self, vertex1: usize, vertex2: usize, vertex3: usize, vertex4: usize) { + + let p1 = self.tetrahedra.get_vertices()[vertex1]; + let p2 = self.tetrahedra.get_vertices()[vertex2]; + let p3 = self.tetrahedra.get_vertices()[vertex3]; + let p4 = self.tetrahedra.get_vertices()[vertex4]; + + let n1 = Point3D::new((p1[0] as f32, p1[1] as f32, p1[2] as f32)); + let n2 = Point3D::new((p2[0] as f32, p2[1] as f32, p2[2] as f32)); + let n3 = Point3D::new((p3[0] as f32, p3[1] as f32, p3[2] as f32)); + let n4 = Point3D::new((p4[0] as f32, p4[1] as f32, p4[2] as f32)); + + let l12 = &n1.distance(&n2); + let l23 = &n2.distance(&n3); + let l31 = &n3.distance(&n1); + let l41 = &n4.distance(&n1); + let l42 = &n4.distance(&n2); + let l43 = &n4.distance(&n3); + + let edge12 = Edge(min(vertex1, vertex2), max(vertex1, vertex2)); + let edge23 = Edge(min(vertex2, vertex3), max(vertex2, vertex3)); + let edge31 = Edge(min(vertex3, vertex1), max(vertex3, vertex1)); + let edge41 = Edge(min(vertex4, vertex1), max(vertex4, vertex1)); + let edge42 = Edge(min(vertex4, vertex2), max(vertex4, vertex2)); + let edge43 = Edge(min(vertex4, vertex3), max(vertex4, vertex3)); + + self.geometry_data.edge_lengths.insert(edge12, *l12); + self.geometry_data.edge_lengths.insert(edge23, *l23); + self.geometry_data.edge_lengths.insert(edge31, *l31); + self.geometry_data.edge_lengths.insert(edge41, *l41); + self.geometry_data.edge_lengths.insert(edge42, *l42); + self.geometry_data.edge_lengths.insert(edge43, *l43); + + self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex2); + self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex1); + + self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex3); + self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex2); + + self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex1); + self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex3); + + self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex1); + self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex4); + + self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex2); + self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex4); + + self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex3); + self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex4); + + } + + pub fn preprocess_3d(&mut self) { + let structure = self.tetrahedra.get_simplicial(); + let num_tetras = structure.get_nb_tetrahedra(); + + for tetra_idx in 0..num_tetras { + let tetrahedron = match self.tetrahedra.get_simplicial().get_tetrahedron(tetra_idx) { + Ok(tetra) => tetra.nodes(), + Err(_) => { + println!("Error getting tetrahedron at index {}", tetra_idx); + continue; // Skip this iteration and proceed with the next one + } + }; + + let [node1, node2, node3, node4] = tetrahedron; + match (node1, node2, node3, node4) { + (Node::Infinity, Node::Value(ind_v2), Node::Value(ind_v3), Node::Value(ind_v4)) => { + self.add_triangle(ind_v2, ind_v3, ind_v4); + }, + (Node::Value(ind_v1), Node::Infinity, Node::Value(ind_v3), Node::Value(ind_v4)) => { + self.add_triangle(ind_v3, ind_v4, ind_v1); + }, + (Node::Value(ind_v1), Node::Value(ind_v2), Node::Infinity, Node::Value(ind_v4)) => { + self.add_triangle(ind_v4, ind_v1, ind_v2); + }, + (Node::Value(ind_v1), Node::Value(ind_v2), Node::Value(ind_v3), Node::Infinity) => { + self.add_triangle(ind_v1, ind_v2, ind_v3); + }, + (Node::Value(ind_v1), Node::Value(ind_v2), Node::Value(ind_v3), Node::Value(ind_v4)) => { + self.add_tetrahedron(ind_v1, ind_v2, ind_v3, ind_v4); + }, + (_, _, _, _) => { + println!("Encountered an unexpected pattern of nodes"); + }, + }; + } + } + + +} \ No newline at end of file diff --git a/tests/threed.rs b/tests/threed.rs new file mode 100644 index 0000000..aabf4ba --- /dev/null +++ b/tests/threed.rs @@ -0,0 +1,12 @@ +use xenobalanus::Xenobalanus; + +#[test] +fn threed() { + let mut geodesic = Xenobalanus::new(); + geodesic.random_points_3d((0.0, 0.0, 0.0), 1.0, 1000); + geodesic.delaunay_3d(); + geodesic.preprocess_3d(); + let attractors = geodesic.dtscan(5, 0.085); + + println!("{:#?}", attractors); +} \ No newline at end of file