commit 718d42f825d2e619552214dd1bada66316b9507a Author: Bendik Aagaard Lynghaug Date: Sat Oct 26 21:31:03 2024 +0200 First things first Started the typing up of a turning function and path generator diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa8d85a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Cargo.lock +target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3070ba0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "redoal" +version = "0.1.0" +edition = "2021" + +[dependencies] +approx = "0.5.1" +lyon = "1.0.1" diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..50f1a22 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,20 @@ +# Redoal + +A library to quantize input path data as a search tree enabling the core functionality of a DHT based path lookup. + +# What it does + +1. Optionally we preprocess input data, normalize, center weight and ensure it's not out of bounds, as a turning function. + +2. + + + + + +# Deserialize and Serialize +To encode and decode path data from + +# Testing + +Visual tests can render and offer manual input data input that renders using the lyon crate. \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..b3a8b1d --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,129 @@ +use lyon::math::point; +use lyon::path::Path; + +#[derive(Clone)] +struct TurningFunction { + steps: Vec, + turns: Vec, + trajectory: f32, +} + +impl TurningFunction { + fn new(trajectory: f32) -> Self { + TurningFunction { + steps: Vec::new(), + turns: Vec::new(), + trajectory, + } + } + + // update current trajectory and add increment + fn add_increment(&mut self, step: i32, direction: f32) { + let radian_diff = direction - self.trajectory; + self.steps.push(step); + self.turns.push(radian_diff); + self.trajectory = self.trajectory + radian_diff; + } + + fn to_coordinates(&self) -> Vec<[f32; 2]> { + let mut coordinates = Vec::new(); + let mut x = 0.0; + let mut y = 0.0; + let mut tracking_trajectory = 0.0; + + for (turn, step) in self.turns.iter().zip(self.steps.iter()) { + tracking_trajectory += *turn as f64; + + // Calculate the new position based on current position and angle of rotation + let dx = (tracking_trajectory.sin() as i32 * step) as f64; + let dy = (tracking_trajectory.cos() as i32 * step) as f64; + + x += dx; + y += dy; + + coordinates.push([x as f32, y as f32]); + } + + coordinates + } +} + +struct PathGenerator { + from: [f32; 2], + turning_function: TurningFunction, + to: [f32; 2], +} + +impl PathGenerator { + // A function to calculate the path based on the turning function + fn generate_path(&self) -> Path { + let mut builder = lyon::path::Path::builder(); + + // Start at the from point + builder.begin(point(self.from[0], self.from[1])); + + // Draw lines between each coordinate point and transpose with starting point + for coord in self.turning_function.clone().to_coordinates() { + builder.line_to(point(coord[0] + self.from[0], coord[1] + self.from[1])); + } + + // Build and return the path + builder.build() + } +} + +// Euclidian distance between two points in 2-dimensional space +pub fn euclidean_distance(a: &[f64], b: &[f64]) -> f64 { + a.into_iter() + .zip(b) + .map(|(x, y)| (x - y).powi(2)) + .sum::() + .sqrt() +} + +#[cfg(test)] +mod tests { + use super::*; + use approx::assert_relative_eq; + + #[test] + fn test_euclidean_distance() { + let p1 = [1.0, 2.0]; + let p2 = [3.0, 4.0]; + + assert_relative_eq!(2.8, euclidean_distance(&p1, &p2), epsilon = 0.1); + } + + // #[test] + // fn test_path_generator() { + // let from = [0.0, 0.0]; + // let tf = TurningFunction::new(0.0); + // let to = [1.5, 2.3]; + + // let pg = PathGenerator { + // from, + // turning_function: tf, + // to, + // }; + + // let path = pg.generate_path(); + + // // Test that the generated path starts at the "from" point + // assert_eq!(path.iter().first(), Some(&point(from[0], from[1]))); + + // // Test that the generated path ends at the "to" point + // assert_eq!(path.iter().last(), Some(&point(to[0], to[1]))); + // } + + #[test] + fn test_turning_function_to_coords() { + let mut tf = TurningFunction::new(0.0); + tf.add_increment(1, 0.5); + tf.add_increment(2, -0.3); + let coords = tf.to_coordinates(); + + println!("{:?}", coords); + + assert_eq!(coords.len(), 2); + } +}