#![feature(generic_const_exprs)] #![feature(let_chains)] mod system; mod cli; use std::fs::File; use std::os::unix::fs::symlink; use bevy::tasks::ParallelSlice; use crate::system::spaces::square_grid::{Grid2D, Grid3D}; use itertools::{Itertools, MinMaxResult}; use clap::Parser; use crate::cli::cli::OutputFormat; use crate::system::{GriddedPosition, Position}; use crate::system::model::HistoryLine; fn box_count_2d(data: &Vec, size: u32) -> usize { let n = data.len(); let x_min = data .iter() .min_by(|Grid2D { x: x1, y: y1 }, Grid2D { x: x2, y: y2 }| x1.cmp(x2)) .unwrap().x; let x_max = data .iter() .max_by(|Grid2D { x: x1, y: y1 }, Grid2D { x: x2, y: y2 }| x1.cmp(x2)) .unwrap().x; let y_min = data .iter() .min_by(|Grid2D { x: x1, y: y1 }, Grid2D { x: x2, y: y2 }| y1.cmp(y2)) .unwrap().y; let y_max = data .iter() .max_by(|Grid2D { x: x1, y: y1 }, Grid2D { x: x2, y: y2 }| y1.cmp(y2)) .unwrap().y; let x_range = (x_max - x_min) as f64; let y_range = (y_max - y_min) as f64; let w: f64 = x_range / (size as f64); // let n_x = size; // let n_y = (y_range / w).ceil() as u32; let grid_points = data.iter() .map(|Grid2D { x, y }| [((x - x_min) as f64 / w) as u32, ((y - y_min) as f64 / w) as u32]) .collect::>(); return grid_points.iter() .unique() .count(); } fn box_count_3d(data: &Vec, size: u32) -> usize { let n = data.len(); let x_min = data .iter() .min_by(|Grid3D { x: x1, .. }, Grid3D { x: x2, .. }| x1.cmp(x2)) .unwrap().x; let x_max = data .iter() .max_by(|Grid3D { x: x1, .. }, Grid3D { x: x2, .. }| x1.cmp(x2)) .unwrap().x; let y_min = data .iter() .min_by(|Grid3D { y: v1, .. }, Grid3D { y: v2, .. }| v1.cmp(v2)) .unwrap().y; let y_max = data .iter() .max_by(|Grid3D { y: v1, .. }, Grid3D { y: v2, .. }| v1.cmp(v2)) .unwrap().y; let z_min = data .iter() .min_by(|Grid3D { z: v1, .. }, Grid3D { z: v2, .. }| v1.cmp(v2)) .unwrap().y; let z_max = data .iter() .max_by(|Grid3D { z: v1, .. }, Grid3D { z: v2, .. }| v1.cmp(v2)) .unwrap().y; let x_range = (x_max - x_min) as f64; let y_range = (y_max - y_min) as f64; let z_range = (z_max - z_min) as f64; let w: f64 = x_range / (size as f64); let grid_points = data.iter() .map(|Grid3D { x, y, z }| [ ((x - x_min) as f64 / w) as i32, ((y - y_min) as f64 / w) as i32, ((z - z_min) as f64 / w) as i32, ]) .collect::>(); return grid_points.iter() .unique() .count(); } fn box_count_nd(data: &Vec<[f32; N]>, size: u32) -> usize { let ranges = (0..N).map(|n| match data.iter() .minmax_by(|a, b| a[n].total_cmp(&b[n])) { MinMaxResult::NoElements => panic!("No data"), MinMaxResult::OneElement(_) => panic!("Needs more than one point to compute boxcount"), MinMaxResult::MinMax(min, max) => [min[n], min[n]], }).collect::>(); let w: f32 = (ranges[0][1] - ranges[0][0]) / (size as f32); return data.iter() .map(|point| -> [i32; N] { std::array::from_fn(|n| ((point[n] - ranges[n][0]) / w) as i32) }) .unique() .count(); } #[derive(Parser)] struct FDArgs { format: OutputFormat, path: std::path::PathBuf, } fn main() { let args = FDArgs::parse(); let qa = match args.format { OutputFormat::FullDataJson => { serde_json::from_reader::<_, Vec>>(File::open(args.path).unwrap()) .expect("Failed to read json") .iter() .map(|l| l.position.clone()) .collect::>() } OutputFormat::Positions => { csv::Reader::from_path(args.path).unwrap().deserialize::() .collect::, _>>() .unwrap() } }; assert_eq!(qa.iter().unique().collect::>().len(), qa.len()); for size in 1..250 { println!("[{}, {:?}],", size, box_count_3d(&qa, size)); } }