41 /* |
42 /* |
42 * Lit les noeuds de l'historique du squelette afin de détecter un cercle. |
43 * Lit les noeuds de l'historique du squelette afin de détecter un cercle. |
43 * Règles : |
44 * Règles : |
44 * Se fait avec une main. |
45 * Se fait avec une main. |
45 * Chaque point est à la même distance du barycentre. |
46 * Chaque point est à la même distance du barycentre. |
46 * Traitement : |
47 * On regarde pour la main gauche. |
47 * On . |
|
48 */ |
48 */ |
49 public bool CheckForCircle() |
49 public bool CheckForLeftCircle() |
50 { |
50 { |
|
51 //Indique si la main gauche a décrit un cercle. |
|
52 bool leftHandDoCircle = true; |
|
53 |
51 //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s. |
54 //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s. |
52 List<List<Joint>> localHistory = new List<List<Joint>>(history); |
55 List<List<Joint>> localHistory = new List<List<Joint>>(history); |
53 |
56 |
54 //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste. |
57 //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste. |
55 if (localHistory.Count < indexesToCheck + 1) |
58 if (localHistory.Count < indexesToCheck + 1) |
56 return false; |
59 return false; |
57 |
60 |
58 //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules. |
61 //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules. |
59 refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y); |
62 refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y); |
60 //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière). |
63 //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière). |
61 startPoint = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position; |
64 SkeletonPoint startPointLeft = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position; |
62 |
65 |
63 //Barycentres pour les mains. |
66 //Barycentres pour les mains. |
64 PointF leftBarycenter = new PointF(0, 0); |
67 PointF leftBarycenter = new PointF(0, 0); |
65 PointF rightBarycenter = new PointF(0, 0); |
|
66 //Distances moyennes des points aux barycentres. |
68 //Distances moyennes des points aux barycentres. |
67 float averageDistToLeftBarycenter = 0; |
69 float averageDistToLeftBarycenter = 0; |
68 float averageDistToRightBarycenter = 0; |
70 |
69 |
|
70 //Index du point de départ dans la détection. |
71 //Index du point de départ dans la détection. |
71 int beginIndex = localHistory.Count - indexesToCheck; |
72 int beginIndex = localHistory.Count - indexesToCheck; |
72 |
73 |
73 //Calcul du barycentre de la main gauche. |
74 //Calcul du barycentre de la main gauche. |
74 for (int i = beginIndex; i > 0; i--) |
75 for (int i = beginIndex; i > 0; i--) |
76 leftBarycenter.X += localHistory[i][(int)JointType.HandLeft].Position.X; |
77 leftBarycenter.X += localHistory[i][(int)JointType.HandLeft].Position.X; |
77 leftBarycenter.Y += localHistory[i][(int)JointType.HandLeft].Position.Y; |
78 leftBarycenter.Y += localHistory[i][(int)JointType.HandLeft].Position.Y; |
78 } |
79 } |
79 leftBarycenter.X /= indexesToCheck; |
80 leftBarycenter.X /= indexesToCheck; |
80 leftBarycenter.Y /= indexesToCheck; |
81 leftBarycenter.Y /= indexesToCheck; |
81 |
|
82 //Calcul du barycentre de la main droite. |
|
83 for (int i = beginIndex; i > 0; i--) |
|
84 { |
|
85 rightBarycenter.X += localHistory[i][(int)JointType.HandRight].Position.X; |
|
86 rightBarycenter.Y += localHistory[i][(int)JointType.HandRight].Position.Y; |
|
87 } |
|
88 rightBarycenter.X /= indexesToCheck; |
|
89 rightBarycenter.Y /= indexesToCheck; |
|
90 |
82 |
91 //Estimation de la distance moyenne d'un point au barycentre gauche. |
83 //Estimation de la distance moyenne d'un point au barycentre gauche. |
92 for (int i = beginIndex; i > 0; i--) |
84 for (int i = beginIndex; i > 0; i--) |
93 { |
85 { |
94 float ptX = localHistory[i][(int)JointType.HandLeft].Position.X; |
86 float ptX = localHistory[i][(int)JointType.HandLeft].Position.X; |
95 float ptY = localHistory[i][(int)JointType.HandLeft].Position.Y; |
87 float ptY = localHistory[i][(int)JointType.HandLeft].Position.Y; |
96 averageDistToLeftBarycenter += (float)Distance2D(ptX, leftBarycenter.X, ptY, leftBarycenter.Y); |
88 averageDistToLeftBarycenter += (float)Distance2D(ptX, leftBarycenter.X, ptY, leftBarycenter.Y); |
97 } |
89 } |
98 averageDistToLeftBarycenter /= indexesToCheck; |
90 averageDistToLeftBarycenter /= indexesToCheck; |
99 |
91 |
|
92 //Pour les points, on suit l'algorithme. |
|
93 |
|
94 //Si la distance moyenne de chaque point de la main gauche au barycentre gauche est trop faible |
|
95 //Alors la main gauche n'a pas décrit de cercle. |
|
96 if (averageDistToLeftBarycenter < refDistance / 2) |
|
97 leftHandDoCircle = false; |
|
98 |
|
99 //Indique si on a atteint le point d'arrivée pour la main gauche. |
|
100 bool endLeftReached = false; |
|
101 |
|
102 if(leftHandDoCircle) |
|
103 for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++) |
|
104 { |
|
105 //Si la distance d'un point de la main gauche excède à la distance moyenne au barycentre gauche avec une erreur N |
|
106 //OU si le point de départ de la main gauche est plus éloigné du point d'arrivée de la main gauche de N. |
|
107 //Alors la main gauche n'a pas décrit de cercle. |
|
108 float X = localHistory[i][(int)JointType.HandLeft].Position.X; |
|
109 float Y = localHistory[i][(int)JointType.HandLeft].Position.Y; |
|
110 |
|
111 //Si un point est proche du point de départ. |
|
112 if(Distance2D(X, Y, startPointLeft.X, startPointLeft.Y) < refDistance / 5 && X != startPointLeft.X && Y != startPointLeft.Y) |
|
113 endLeftReached = true; |
|
114 |
|
115 if (Math.Abs((double)Distance2D(X, Y, leftBarycenter.X, leftBarycenter.Y) - averageDistToLeftBarycenter) > refDistance / 5) |
|
116 { |
|
117 leftHandDoCircle = false; |
|
118 break; |
|
119 } |
|
120 |
|
121 //Si la main gauche a atteint une position proche de son point de départ. |
|
122 if (endLeftReached) |
|
123 { |
|
124 //S'il y a trop peu de points |
|
125 if (i - (localHistory.Count - indexesToCheck + 1) < (indexesToCheck / 2)) |
|
126 leftHandDoCircle = false; |
|
127 break; |
|
128 } |
|
129 } |
|
130 |
|
131 //On supprime l'historique local. |
|
132 localHistory.Clear(); |
|
133 //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe left ont été remplies. |
|
134 return leftHandDoCircle; |
|
135 } |
|
136 |
|
137 /* |
|
138 * Lit les noeuds de l'historique du squelette afin de détecter un cercle. |
|
139 * Règles : |
|
140 * Se fait avec une main. |
|
141 * Chaque point est à la même distance du barycentre. |
|
142 * On regarde pour la main droite. |
|
143 */ |
|
144 public bool CheckForRightCircle() |
|
145 { |
|
146 //Indique si la main droite a décrit un cercle. |
|
147 bool rightHandDoCircle = true; |
|
148 |
|
149 //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s. |
|
150 List<List<Joint>> localHistory = new List<List<Joint>>(history); |
|
151 |
|
152 //if (Math.Abs(Math.Abs(localHistory[0][(int)JointType.HandLeft].Position.X - localHistory[0][(int)JointType.HandRight].Position.X) - refDistance) < 10) |
|
153 // Console.Out.WriteLine("REF"); |
|
154 |
|
155 //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste. |
|
156 if (localHistory.Count < indexesToCheck + 1) |
|
157 return false; |
|
158 |
|
159 //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules. |
|
160 refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y); |
|
161 //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière). |
|
162 SkeletonPoint startPointRight = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position; |
|
163 |
|
164 //Barycentres pour la main droite. |
|
165 PointF rightBarycenter = new PointF(0, 0); |
|
166 //Distances moyennes des points aux barycentres. |
|
167 float averageDistToRightBarycenter = 0; |
|
168 |
|
169 //Index du point de départ dans la détection. |
|
170 int beginIndex = localHistory.Count - indexesToCheck; |
|
171 |
|
172 //Index du point d'arrivée. |
|
173 int endRightIndex = 0; |
|
174 |
|
175 //On cherche le point d'arrivée. |
|
176 /*for (int i = beginIndex; i > 0; i--) |
|
177 { |
|
178 float X = localHistory[i][(int)JointType.HandRight].Position.X; |
|
179 float Y = localHistory[i][(int)JointType.HandRight].Position.Y; |
|
180 |
|
181 //Si un point est proche du point de départ. |
|
182 if (Distance2D(X, Y, startPointRight.X, startPointRight.Y) < refDistance / 2 && X != startPointRight.X && Y != startPointRight.Y) |
|
183 { |
|
184 Console.Out.WriteLine("REACHED"); |
|
185 endRightIndex = i; |
|
186 break; |
|
187 } |
|
188 }*/ |
|
189 |
|
190 /*//S'il n'y a pas assez de points. |
|
191 if (beginIndex - endRightIndex < indexesToCheck) |
|
192 return false;*/ |
|
193 |
|
194 //Calcul du barycentre de la main droite. |
|
195 for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++) |
|
196 { |
|
197 rightBarycenter.X += localHistory[i][(int)JointType.HandRight].Position.X; |
|
198 rightBarycenter.Y += localHistory[i][(int)JointType.HandRight].Position.Y; |
|
199 } |
|
200 rightBarycenter.X /= indexesToCheck; |
|
201 rightBarycenter.Y /= indexesToCheck; |
|
202 |
100 //Estimation de la distance moyenne d'un point au barycentre droit. |
203 //Estimation de la distance moyenne d'un point au barycentre droit. |
101 for (int i = beginIndex; i > 0; i--) |
204 for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++) |
102 { |
205 { |
103 float ptX = localHistory[i][(int)JointType.HandRight].Position.X; |
206 float ptX = localHistory[i][(int)JointType.HandRight].Position.X; |
104 float ptY = localHistory[i][(int)JointType.HandRight].Position.Y; |
207 float ptY = localHistory[i][(int)JointType.HandRight].Position.Y; |
105 averageDistToRightBarycenter += (float)Distance2D(ptX, rightBarycenter.X, ptY, rightBarycenter.Y); |
208 averageDistToRightBarycenter += (float)Distance2D(ptX, rightBarycenter.X, ptY, rightBarycenter.Y); |
106 } |
209 } |
107 averageDistToRightBarycenter /= indexesToCheck; |
210 averageDistToRightBarycenter /= indexesToCheck; |
108 |
211 |
109 //De la position p1 à pn, on suit l'algorithme. |
212 //Pour les points, on suit l'algorithme. |
110 for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++) |
213 |
111 { |
214 //Si la distance moyenne de chaque point de la main droite au barycentre droit est trop faible |
112 //Si la position Y de la main est plus haute que la tête |
215 //Alors la main droite n'a pas décrit de cercle. |
113 //OU si la position Y de la main est plus basse que la hanche |
216 if (averageDistToRightBarycenter < refDistance / 2) |
114 //OU si la nouvelle position X de la main est à droite de la précédente |
217 rightHandDoCircle = false; |
115 //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y |
218 |
116 //Alors on retourne faux. |
219 float globalPercent = 0; |
117 if (localHistory[i][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.Head].Position.Y || |
220 |
118 localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HipCenter].Position.Y || |
221 if (rightHandDoCircle) |
119 localHistory[i][(int)JointType.HandRight].Position.X > localHistory[i - 1][(int)JointType.HandRight].Position.X || |
222 for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++) |
120 Math.Abs(localHistory[i][(int)JointType.HandRight].Position.Y - startPoint.Y) > refDistance / 2) |
223 { |
121 return false; |
224 //Si la distance moyenne de chaque point de la main droite au barycentre droit est trop faible |
122 } |
225 //OU si la distance d'un point de la main droite excède à la distance moyenne au barycentre droit avec une erreur N |
123 |
226 //OU si le point de départ de la main gauche est plus éloigné du point d'arrivée de la main gauche de N. |
124 //Si la distance horizontale du geste a été plus courte que la distance N |
227 //Alors la main droite n'a pas décrit de cercle. |
125 //Alors on retourne faux. |
228 |
126 if (Math.Abs(localHistory[0][(int)JointType.HandRight].Position.X - localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position.X) < refDistance / 2) |
229 float X = localHistory[i][(int)JointType.HandRight].Position.X; |
127 return false; |
230 float Y = localHistory[i][(int)JointType.HandRight].Position.Y; |
128 |
231 float R = averageDistToRightBarycenter, r = (float)Math.Abs((double)Distance2D(X, Y, rightBarycenter.X, rightBarycenter.Y)); |
129 //Si la dernière position de la main droite est sur le côté droit du corps |
232 float percent = 0; |
130 //OU si la première position calculée de la main droite est sur le côté gauche du corps |
233 |
131 //Alors on retourne faux. |
234 if (r < R) |
132 if (localHistory[localHistory.Count - 1][(int)JointType.HandRight].Position.X > localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X || |
235 percent = 100 * r / R; |
133 localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position.X < localHistory[localHistory.Count - 1][(int)JointType.HipCenter].Position.X) |
236 else |
134 return false; |
237 percent = 100 * R / r; |
|
238 |
|
239 globalPercent += percent; |
|
240 |
|
241 /*if (Math.Abs((double)Distance2D(X, Y, rightBarycenter.X, rightBarycenter.Y) - averageDistToRightBarycenter) > refDistance / 5) |
|
242 { |
|
243 //Console.Out.WriteLine("FAIL"); |
|
244 return false; |
|
245 }*/ |
|
246 } |
|
247 |
|
248 float res = ((float)globalPercent / indexesToCheck); |
|
249 |
|
250 Console.Out.WriteLine("p:" + ((float)globalPercent / indexesToCheck)); |
|
251 |
|
252 if (res >= 50) |
|
253 Console.In.Read(); |
135 |
254 |
136 //On supprime l'historique local. |
255 //On supprime l'historique local. |
137 localHistory.Clear(); |
256 localHistory.Clear(); |
138 //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe left ont été remplies. |
257 //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe left ont été remplies. |
139 return true; |
258 return true; |