Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.85 KB | None | 0 0
  1. use std::f64;
  2.  
  3. #[derive(Clone)]
  4. pub struct Point {
  5. pub lat: f64, // plutôt y (cf le pâté en bas)
  6. pub lon: f64, // plutôt x
  7. }
  8.  
  9. // la convention est plutôt d’avoir juste new. Point::new est moins redondant que Point::new_point
  10. // Cependant, tout particulièrement dans le cas des coordonnées l’ordre est source de confusion.
  11. // Typiquement, tu utilises des coordonnées cartésiennes (distance euclidiennes), pas sphériques)
  12. // On s’attendrait donc à saisir (x, y) et non pas (y, x) comme tu l’as fait là
  13. // Il vaut donc mieux donc obliger être explicite et donc faire :
  14. // Point { lat: 2.0, lon: 1.0} et ne pas avoir de constructeur du tout
  15. fn new_point(lat: f64, lon: f64) -> Point {
  16. Point { lat, lon }
  17. }
  18.  
  19. fn main() {
  20. let a = vec![new_point(1.0, 1.0), new_point(2.0, 1.0), new_point(2.0, 2.0)];
  21. let b = vec![new_point(2.0, 2.0), new_point(0.0, 1.0), new_point(2.0, 4.0)];
  22. println!("{}", dist_frechet(&a, &b));
  23. }
  24.  
  25. pub struct Data {
  26. cache: Vec<Vec<f64>>,
  27. linestring_a: Vec<Point>,
  28. linestring_b: Vec<Point>,
  29. }
  30.  
  31. impl Data {
  32. fn c(&mut self, i: usize, j: usize) -> f64 {
  33. if self.cache[i][j] > -1.0 {
  34. return self.cache[i][j];
  35. // Essayer de voir si c’est possible à coups de match :)
  36. } else if i == 1 && j == 1 {
  37. self.cache[i][j] = self.eucl_dist(0, 0)
  38. } else if i > 1 && j == 1 {
  39. // En fait, à chaque fois, c’est eucl_dist(i,j) qui est appelé
  40. // Le mettre en constante en début sera probablement plus lisible
  41. // Et évitera d’avoir specifique à Data
  42. self.cache[i][j] = self.c(i - 1, 1).max(self.eucl_dist(i, 0))
  43. } else if i == 1 && j > 1 {
  44. self.cache[i][j] = self.c(1, j - 1).max(self.eucl_dist(0, j))
  45. } else if i > 1 && j > 1 {
  46. self.cache[i][j] = ((self.c(i - 1, j).min(self.c(i - 1, j - 1))).min(self.c(i, j - 1)))
  47. .max(self.eucl_dist(i, j))
  48. } else {
  49. self.cache[i][j] = f64::INFINITY
  50. }
  51. return self.cache[i][j];
  52. }
  53.  
  54. fn eucl_dist(&self, i: usize, j: usize) -> f64 {
  55. eucl_dist(&self.linestring_a[i], &self.linestring_a[j])
  56. }
  57.  
  58. // Quitte à avoir un constructeur, autant utiliser le constructeur poun initialiser le cache ;)
  59. fn new(cache: Vec<Vec<f64>>, linestring_a: Vec<Point>, linestring_b: Vec<Point>) -> Self {
  60. Data {
  61. cache,
  62. linestring_a,
  63. linestring_b,
  64. }
  65. }
  66. }
  67.  
  68. fn dist_frechet(p: &Vec<Point>, q: &Vec<Point>) -> f64 {
  69. let mut d = Data::new(vec![vec![-1.; q.len()]; p.len()], p.to_vec(), q.to_vec());
  70. // Pas besoin de définir une constante pour la retourner immédiatement, autant retourner directement le résultat
  71. let dist = d.c(p.len()-1, q.len()-1);
  72. dist
  73. }
  74.  
  75. fn eucl_dist(p: &Point, q: &Point) -> f64 {
  76. ((p.lat - q.lat).powi(2) + (p.lon - q.lon).powi(2)).sqrt()
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement