Bonjour à tous.
J'ai une cible à l'écran que je dois déplacer d'un point a un autre sur une ligne droite en suivant sont déplacement. Je connais le point de départ et le point d'arrivée.
Comment puis-je faire ?
Merci d'avance
 Déplacement d'une Cible sur une droite
 Déplacement d'une Cible sur une droite
				
				
						
						
				Bonjour à tous.
J'ai une cible à l'écran que je dois déplacer d'un point a un autre sur une ligne droite en suivant sont déplacement. Je connais le point de départ et le point d'arrivée.
Comment puis-je faire ?
Merci d'avance
 
 
				
				
						
						
				Tu veux avancer du point I (initial) à F (final). Coordonnées (Ix,Iy) resp. (Fx,Fy) en un temps donné Ttot. Bien sûr, ce temps peut être en fait un nombre de pas (Si Ttot=1000 pas, alors tu auras T1=1, T2=2, T3=3...).
Au temps T, la position (X,Y) de la cible est:
X=Ix+(Fx-Ix)/Ttot*T=Ix+Vx*T (où Vx=(Fx-Ix)/Ttot, la vitesse en X)
Y=Iy+(Fy-Iy)/Ttot*T=Iy+Vy*T (idem, Vy=(Fy-Iy)*Ttot, la vitesse en Y)
Si ton temps T est en fait des pas de 1, par exemple, alors tu peux simplement incrémenter la position de Vx et Vy à chaque pas, mais tu as le risque de cumuler une erreur à chaque pas... Le mieux reste de calculer la position à chaque fois:
Il faut faire bien attention à calculer la vitesse avec autre chose que des integer, sinon tu as une forte déviation dûe à l'approximation!
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7
8
9
10
Un exemple d'appli tout bête:
1) Tu mets ne nombre de pas dans la case "TempsTot"
2) Tu cliques sur Start
3) Tu fais un cliquer-glisser depuis le point de départ vers le point d'arrivée
Le header
Le code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TPoint
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
 
 
				
				
						
						
				J'ai réussi et je t'en remercie.
Par contre, j'ai quand même un petit souci, il semblerait que cela ne passe pas exactement sur la ligne droite car j'ai mis un point d'arrêt lorsque mon déplacement s'arrête (teste si le point courant est égal au point final du segment) et cela ne s'arrête pas.
 
 
				
				
						
						
				En fait, il y a deux choses:
1) Dans mon code, j'ai fait une erreur dans la boucle: il faut aller de 0 à n et par de 0 à (n-1) pour atteindre le point final
au lieu de
Code : Sélectionner tout - Visualiser dans une fenêtre à part for (int t=0;t<=Ttot;++t)2) Avec les arrondis, tu as toujours le risque de te retrouver un tout petit peu à côté de la valeur si tu fais la comparaison en double, mais c'est très improbable si tu compares la position Top/Left et que tu n'utilises pas les incréments: la formule Px=Ix+Vx*t est très précise pour t=Ttot (Px=Ix+(Fx-Ix)/Ttot*Tot=Fx)
Code : Sélectionner tout - Visualiser dans une fenêtre à part for (int t=0;t<Ttot;++t)
Je pense que ton problème vient de mon erreur (point 1)
 
 
				
				
						
						
				Voilà moi comment j'ai fait
Unit1.h
Unit1.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 
 
				
				
						
						
				Salut !
Il faut juste arrondir avec un peu plus de précision :
Code : Sélectionner tout - Visualiser dans une fenêtre à part #include <math.h>Je ne sais pas s'il y a plus simple !
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
A plus !
 
 
				
				
						
						
				Remarque :Un petit inconvénient de ce calcul, mais peut être que dans ton appli ça n'a pas d'importance, est que ta cible peut se déplacer par bonds (ou au contraire stagner à un endroit, ce qui fait du calcul pour rien). Elle peut sauter des positions sur la ligne droite. Dans son déplacement, il peut y avoir des emplacements sur la droite où elle ne se trouvera jamais. Si c'est grave, il faut modifier l'algo de calcul des points de la droitePoint.x = (VX * T) + Pts[NumSegment].x;
Point.y = (VY * T) + Pts[NumSegment].y;
 
 
				
				
						
						
				Le problème vient du fait que tu maîtrises mal le temps écoulé dans le soft. Celui-ci est en double et le timer n'est pas forcement d'une très grande précision. Résultat, tu tombes rarement juste dans les points calculés et finaux.
Le mieux est de calculer si tu as atteint ou dépassé la cible d'arrivée et de t'intérrompre à ce moment-là. Pour celà, tu peux soit calculer le temps total écoulé et voir si tu as dépassés ton Temps prévu, mais le plus élégant, c'est de jouer avec les vecteurs pour voir quand ton point P est passé derrière le point F (final). Je te propose de remplacer ton test
par
Code : Sélectionner tout - Visualiser dans une fenêtre à part if((Point.x == Pts[NumSegment + 1].x) && (Point.y == Pts[NumSegment + 1].y))
Le principe est qu'en géométrie vectorielle, le produit scalaire entre deux vecteurs donne la projection de l'un sur l'autre. Lorsqu'ils sont perpendiculaires le produit scalaire est nul, lorsqu'ils sont dans le même sens, il est positif, et lorsqu'ils sont opposé il est négatif.
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Si tu calcules les vecteurs I-->F et P-->F (P=point courant, I=point initial, F=point final), tu peux ainsi savoir si P a dépassé F car (I-->F)*(P-->F) devient négatif.
Demande-moi si tu veux plus d'explications... Mais le code a l'air de fonctionner!
Il me semble qu'il y a un truc bizarre avec ta vitesse qui n'est pas identique entre les 2 segments, mais je ne trouve pas de faute...
 
 
				
				
						
						
				Le produit scalaire était mal écrit dans mon commentaire. Il faut lire:
Code : Sélectionner tout - Visualiser dans une fenêtre à part // ProduitScalaire(<Ax,Ay>,<Bx,By>)=Ax*Bx+Ay*By
 
 
				
				
						
						
				Salut !
La progression de la cible se calcule aussi simplement par progression de n points
par intervalle de temps sur la droite reliant les deux points (départ et arrivée).
On a juste, au départ, à calculer une distance, un sinus et un cosinus.
Ici j'utilise :
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3TPoint *arrivee; TPoint *depart; double distance, sinus, cosinus, progression, pas;
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7
8
9
10
11
12
La position de la cible en mouvement sur la droite se calcule à l'aide de :
A plus !
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7progression = progression + pas; si progression < distance x = (cosinus * progression) + depart->x; y = (sinus * progression) + depart->y; sinon x = arrivee->x; y = arrivee->y;
Partager