Bonjour à vous,
J'ai à disposition un appareil qui me fournis la position 2D d'un outil de fouille (genre petite pelle hydraulique).
J'essaye d'afficher une courbe avec en abscisses l'éloignement de l'outil par rapport à une référence (x) et en ordonnées la profondeur atteinte de l'outils (y).
Pour m'aider à développer, j'affiche sur le même graphe un nuage de points qui correspond à tous les points renvoyés par l'outils, et ma courbe après traitement.
J'ai quelques difficultés pour gérer ma courbe lorsque l'outil repasse aux mêmes endroits avec des profondeurs différentes. Comme vous pouvez le voir sur la courbe en pièce jointe, j'ai quelques pics indésirables. J'ai dans un premier temps cherche différents algo pour identifier l'enveloppe inférieur du nuage de point, mais comme je fais ce traitement en temps réel sur un petit micro, je m'oriente actuellement vers un algo un peu plus "bête".
Le traitement pour chaque nouveau point est le suivant:
SI un point aillant le même x existe déjà dans mon graphe ET que le nouveau point a un y plus petit ALORS remplacer l'ancien avec le nouveau
SINON SI le nouveau point.x est plus petit ou plus grand que tous ceux déjà ajoutés, ALORS ajouter le nouveau point
SINON
{
Prendre les deux points existant adjacents à mon point.x, faire une extrapolation linéaire pour calculer la droite passant par ces deux points
SI y extrapolé en point.x est plus grand que point.y ALORS ajouter mon nouveau point
}
Tout ceci me donne un résultat assez proche de ce que je souhaite, mais j'ai encore quelques pics indésirables. Je pense qu'il faudrait encore quelques ajustements.
Ci-dessous le "vrai code". La partie en commentaire améliore un peu le filtrage mais ne suffit pas.
Merci à ceux qui s'y intéresseront...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 void DialogPlots::AddPoint(int graphNum, QPoint point) { QCPDataMap* map = ui->customPlot->graph(graphNum)->data(); if(true == map->isEmpty()) { map->insert(point.x(), QCPData(point.x(), point.y())); } else if(true == map->contains(point.x())) { if(map->value(point.x()).value > point.y() ) { map->insert(point.x(), QCPData(point.x(), point.y())); } } else { QList<double> keys = map->keys(); if((keys.first() > point.x()) || (keys.last() < point.x())) { map->insert(point.x(), QCPData(point.x(), point.y())); } else { int prev_key = point.x(); while(false == map->contains(--prev_key)); int x1 = prev_key; int y1 = map->value(prev_key).value; QMap<double, QCPData>::const_iterator next = map->upperBound(point.x()); int x2 = next.key(); int y2 = next.value().value; int p = (y2 - y1) / (x2 - x1); int y_virtual = p * (point.x() - x1) + y1; if(y_virtual > point.y()) map->insert(point.x(), QCPData(point.x(), point.y())); if(prev_key > keys.first()) { while(false == map->contains(--prev_key)); int x0 = prev_key; int y0 = map->value(prev_key).value; if((y1 > y0) && (y1 > point.y())) map->remove(x1); } next++; if(next.key() < keys.last()) { int x3 = next.key(); int y3 = next.value().value; if((y2 > y3) && (y2 > point.y())) map->remove(x2); } } } ui->customPlot->rescaleAxes(); ui->customPlot->replot(); }








Répondre avec citation










Partager