2015-08-26 2 views
0

La réponse à ma question pourrait être évidente, je voudrais juste avoir une confirmation. J'ai une courbe avec un grand nombre de points à optimiser. Sur cette courbe je pourrais avoir à faire diverses opérations qui sont: 1. ajouter sur toile 2. déplacer sur toile 3. Étirez sur toile 4. toile pan 5. toile zoomWPF Points d'optimisation

Pour ce faire, je avoir une polyligne originale qui stocke tous les points d'origine. Ensuite, j'ai une deuxième polyligne qui stocke l'ensemble optimisé de points. Tout d'abord, mon optimisation semble triviale c'est-à-dire: 1. Les points sont des doubles vars mais à la fin sur l'écran sont des entiers. donc si point1 et points2 CONVERTED TO INTEGER sont les mêmes, je rejette point2. 2. Si un segment a à la fois un début et une fin hors du canevas (par exemple pour avoir fait un panoramique ou un zoom), je rejette les deux points.

Et je le fais pour tous les points. Ceci est très efficace car un exemple de spirale avec 1 million de points peut être réduit à 4000 points !! Ensuite, j'affiche toujours la courbe d'optimisation.


En ce qui concerne les différentes opérations effectuées sur la courbe. Bouger sur le canevas ---> ne nécessite pas de refaire l'optimisation (je ne peux pas le déplacer en dehors du canevas).

  1. Je déplace la courbe secondaire
  2. étirer sur le canevas ---> ne nécessite pas de refaire l'optimisation. J'étire la courbe secondaire
  3. canvas pan ---> nécessite de refaire des optimisations certains points peuvent être coupés du canevas. Canvas zoom ---> nécessite de refaire des optimisations certains points peuvent être coupés du canevas.

Est-ce correct?

Thanx pour aider Patrick

+0

coordonnées d'écran en WPF sont doubles valeurs, la méthode converti à entier devrait être remplacé par une méthode de distance minimale entre points. En général, il y a l'algorithme [Ramer-Douglas-Peucker] (https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm) pour réduire le nombre de points dans une polyligne . – Clemens

+0

Je vous remercie pour votre clarification, mais il y a toujours quelque chose que je ne peux pas comprendre. Parlons des pixels PHYSIQUES sur un moniteur. Disons que j'ai P1 = nouveau Point (0.0, 0.0); et P2 = nouveau point (0,001, 0,001). Je suis conscient que pour WPF ceux-ci sont différents mais en somme sont-ils différents sur l'écran? – Patrick

+0

Cela dépend de l'écran. Si vous aviez un écran imaginaire avec 96000 DPI, ils seraient en effet par différents. Vous devriez avoir un algorithme qui réduit le nombre de points d'une manière qui est indépendante de la résolution de l'écran. OMI, Douglas-Ramer-Peucker serait une approche raisonnable. Il en résulterait beaucoup moins de 4000 points, je suppose. – Clemens

Répondre

1

Vous pouvez utiliser le Douglas-Ramer-Peucker algorithm pour réduire le nombre de points dans un polyligne:

public static IList<Point> ReducePoints(IList<Point> points, double tolerance) 
{ 
    var indexes = new List<int>(2); 

    indexes.Add(0); 
    indexes.Add(points.Count - 1); 
    ReducePoints(points, tolerance, indexes, 0, points.Count - 1); 

    return indexes.OrderBy(i => i).Select(i => points[i]).ToList(); 
} 

private static void ReducePoints(
    IList<Point> points, double tolerance, List<int> indexes, int first, int last) 
{ 
    if (first + 1 < last) 
    { 
     var dx = points[first].X - points[last].X; 
     var dy = points[first].Y - points[last].Y; 
     var length = Math.Sqrt(dx * dx + dy * dy); 
     var maxDistance = 0d; 
     var farthest = 0; 

     for (var index = first + 1; index < last; index++) 
     { 
      var dxi = points[first].X - points[index].X; 
      var dyi = points[first].Y - points[index].Y; 

      // perpendicular distance from line segment first to last 
      var distance = Math.Abs(dx * dyi - dxi * dy)/length; 

      if (distance > maxDistance) 
      { 
       maxDistance = distance; 
       farthest = index; 
      } 
     } 

     if (maxDistance > tolerance) 
     { 
      indexes.Add(farthest); 
      ReducePoints(points, tolerance, indexes, first, farthest); 
      ReducePoints(points, tolerance, indexes, farthest, last); 
     } 
    } 
} 
+0

Thanx un million !! Je vais le marquer résolu! – Patrick