Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::f64;
- #[derive(Clone)]
- pub struct Point {
- pub lat: f64, // plutôt y (cf le pâté en bas)
- pub lon: f64, // plutôt x
- }
- // la convention est plutôt d’avoir juste new. Point::new est moins redondant que Point::new_point
- // Cependant, tout particulièrement dans le cas des coordonnées l’ordre est source de confusion.
- // Typiquement, tu utilises des coordonnées cartésiennes (distance euclidiennes), pas sphériques)
- // On s’attendrait donc à saisir (x, y) et non pas (y, x) comme tu l’as fait là
- // Il vaut donc mieux donc obliger être explicite et donc faire :
- // Point { lat: 2.0, lon: 1.0} et ne pas avoir de constructeur du tout
- fn new_point(lat: f64, lon: f64) -> Point {
- Point { lat, lon }
- }
- fn main() {
- let a = vec![new_point(1.0, 1.0), new_point(2.0, 1.0), new_point(2.0, 2.0)];
- let b = vec![new_point(2.0, 2.0), new_point(0.0, 1.0), new_point(2.0, 4.0)];
- println!("{}", dist_frechet(&a, &b));
- }
- pub struct Data {
- cache: Vec<Vec<f64>>,
- linestring_a: Vec<Point>,
- linestring_b: Vec<Point>,
- }
- impl Data {
- fn c(&mut self, i: usize, j: usize) -> f64 {
- if self.cache[i][j] > -1.0 {
- return self.cache[i][j];
- // Essayer de voir si c’est possible à coups de match :)
- } else if i == 1 && j == 1 {
- self.cache[i][j] = self.eucl_dist(0, 0)
- } else if i > 1 && j == 1 {
- // En fait, à chaque fois, c’est eucl_dist(i,j) qui est appelé
- // Le mettre en constante en début sera probablement plus lisible
- // Et évitera d’avoir specifique à Data
- self.cache[i][j] = self.c(i - 1, 1).max(self.eucl_dist(i, 0))
- } else if i == 1 && j > 1 {
- self.cache[i][j] = self.c(1, j - 1).max(self.eucl_dist(0, j))
- } else if i > 1 && j > 1 {
- self.cache[i][j] = ((self.c(i - 1, j).min(self.c(i - 1, j - 1))).min(self.c(i, j - 1)))
- .max(self.eucl_dist(i, j))
- } else {
- self.cache[i][j] = f64::INFINITY
- }
- return self.cache[i][j];
- }
- fn eucl_dist(&self, i: usize, j: usize) -> f64 {
- eucl_dist(&self.linestring_a[i], &self.linestring_a[j])
- }
- // Quitte à avoir un constructeur, autant utiliser le constructeur poun initialiser le cache ;)
- fn new(cache: Vec<Vec<f64>>, linestring_a: Vec<Point>, linestring_b: Vec<Point>) -> Self {
- Data {
- cache,
- linestring_a,
- linestring_b,
- }
- }
- }
- fn dist_frechet(p: &Vec<Point>, q: &Vec<Point>) -> f64 {
- let mut d = Data::new(vec![vec![-1.; q.len()]; p.len()], p.to_vec(), q.to_vec());
- // Pas besoin de définir une constante pour la retourner immédiatement, autant retourner directement le résultat
- let dist = d.c(p.len()-1, q.len()-1);
- dist
- }
- fn eucl_dist(p: &Point, q: &Point) -> f64 {
- ((p.lat - q.lat).powi(2) + (p.lon - q.lon).powi(2)).sqrt()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement