From 59b29bb678f9a20e3ccf832bb4ef8ba4320a17f0 Mon Sep 17 00:00:00 2001 From: randogoth Date: Tue, 26 Mar 2024 10:25:47 +0200 Subject: [PATCH] update, cleanup --- src/main.rs | 83 ++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/src/main.rs b/src/main.rs index e0b3ac3..82b4394 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,11 @@ -use geo::{Point, Polygon, LineString, EuclideanDistance, Area}; -use std::collections::{HashMap, HashSet}; -use std::cmp::{min, max}; +use delaunator::{triangulate, Point as DelaunatorPoint}; +use geo::{Point, Polygon, LineString, Area}; +use itertools::Itertools; use rand::Rng; use rayon::prelude::*; -use delaunator::{triangulate, Point as DelaunatorPoint}; -use itertools::Itertools; +use std::cmp::{min, max}; +use std::collections::{HashMap, HashSet}; use std::sync::{Arc, Mutex}; -use std::time::Instant; -use std::mem; #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] struct Edge(usize, usize); @@ -16,7 +14,8 @@ struct Edge(usize, usize); struct TriangleData { index: usize, area: Option, - terminal_edge: Option + terminal_edge: Option, + vertices: Vec } #[derive(Debug)] @@ -42,11 +41,14 @@ impl GeometryData { let point_b: Point = points[tri_idx[1]]; let point_c: Point = points[tri_idx[2]]; + let mut vertices = vec![tri_idx[0], tri_idx[1], tri_idx[2]]; + vertices.sort_unstable(); + // Temporarily store edges_with_lengths for sorting and determining the terminal_edge. let mut edges_with_lengths_temp = [ - (Edge(min(tri_idx[0], tri_idx[1]), max(tri_idx[0], tri_idx[1])), point_a.euclidean_distance(&point_b)), - (Edge(min(tri_idx[1], tri_idx[2]), max(tri_idx[1], tri_idx[2])), point_b.euclidean_distance(&point_c)), - (Edge(min(tri_idx[2], tri_idx[0]), max(tri_idx[2], tri_idx[0])), point_c.euclidean_distance(&point_a)), + (Edge(min(tri_idx[0], tri_idx[1]), max(tri_idx[0], tri_idx[1])), distance(point_a.x(), point_a.y(), point_b.x(), point_b.y())), + (Edge(min(tri_idx[1], tri_idx[2]), max(tri_idx[1], tri_idx[2])), distance(point_b.x(), point_b.y(), point_c.x(), point_c.y())), + (Edge(min(tri_idx[2], tri_idx[0]), max(tri_idx[2], tri_idx[0])), distance(point_c.x(), point_c.y(), point_a.x(), point_a.y())), ].to_vec(); // Sort edges by length to ensure the longest edge is identified. @@ -83,25 +85,28 @@ impl GeometryData { self.triangles.push(TriangleData { index, area, - terminal_edge + terminal_edge, + vertices }); } } } -pub fn random_points(center: (f32, f32), radius: f32, num_points: usize) -> Vec> { - let mut rng: rand::prelude::ThreadRng = rand::thread_rng(); - let mut points: Vec> = Vec::with_capacity(num_points); +fn distance(x1: f32, y1: f32, x2: f32, y2: f32) -> f32 { + ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt() +} +pub fn random_points(center: (f32, f32), side_length: f32, num_points: u32) -> Vec> { + // generate random points in a square that is 5% larger than the target circle + 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 mut points: Vec> = Vec::with_capacity(num_points as usize); + let mut rng: rand::prelude::ThreadRng = rand::thread_rng(); for _ in 0..num_points { - // Generate a random angle between 0 and 2*PI. - let angle: f32 = rng.gen_range(0.0..(2.0 * std::f32::consts::PI)); - // Generate a random radius to ensure uniform distribution within the circle. - let r: f32 = (rng.gen_range(0.0..=1.0) as f32).sqrt() * radius; - // Calculate x and y coordinates based on the random angle and radius. - let x: f32 = center.0 + r * angle.cos(); - let y: f32 = center.1 + r * angle.sin(); - // Add the generated point to the points vector. + 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); points.push(Point::new(x, y)); } @@ -283,40 +288,28 @@ fn dtscan( } fn main() { - let dots: usize = 225424; - let radius: f32 = 1000.0; - let mut start = Instant::now(); - let points: Vec> = random_points((0.0, 0.0), radius, dots); - let mut duration = start.elapsed(); - println!("Generated {:#?} random dots in: {:#?}", dots, duration); - start = Instant::now(); + let dots: u32 = 10000; + let side_length: f32 = 10000.0; + let points: Vec> = random_points((0.0, 0.0), side_length, dots); + println!("Generated {:#?} random dots", dots); let triangles_indices: Vec = delaunay(&points); - duration = start.elapsed(); - println!("Generated Delaunay triangulation in: {:#?}", duration); + println!("Generated Delaunay triangulation"); - start = Instant::now(); let geometry_data: GeometryData = preprocess(&points, &triangles_indices, 0); - duration = start.elapsed(); - println!("Preprocessed Triangles using {:#?} bytes of RAM in: {:#?}", mem::size_of_val(&geometry_data), duration); // Define minimum area and minimum distance for delfin function - let min_area: f32 = 75.0; // threshold for voidness - let min_distance: f32 = 10.0; // threshold for minimum distance + let min_area: f32 = 1000.0; // threshold for voidness + let min_distance: f32 = 200.0; // threshold for minimum distance // Parameters for DTSCAN let min_pts: usize = 5; // threshold for minimum number of points - let max_closeness: f32 = 1.5; // threshold for maximum closeness + let max_closeness: f32 = 100.5; // threshold for maximum closeness // Execute delfin function with the generated GeometryData - start = Instant::now(); let void_polygons: Vec> = delfin(&geometry_data, min_area, min_distance); - duration = start.elapsed(); - println!("Found {:#?} Voids using {:#?} bytes of RAM in: {:#?}", void_polygons.len(), mem::size_of_val(&void_polygons), duration); + println!("Found {:#?} Voids", void_polygons.len()); // Execute DTSCAN with the prepared data - start = Instant::now(); let clusters: Vec> = dtscan(&geometry_data, min_pts, max_closeness); - duration = start.elapsed(); - println!("Found {:#?} Attractors using {:#?} bytes of RAM in: {:#?}", clusters.len(), mem::size_of_val(&clusters), duration); - // println!("{:#?}", (void_polygons, clusters)) + println!("Found {:#?} Attractors", clusters.len()); } \ No newline at end of file