Merci, je regarde ça... Avec le boulot, ce n'était pas facile aujourd'hui
Merci, je regarde ça... Avec le boulot, ce n'était pas facile aujourd'hui
En fait pour faire la transformation globale, il faut faire le produit des matrices
Mx*My*Mz*Mt
et pour la calculer, il faut tout reprendre à l'envers :
Et si je fais ça, c'est encore raté
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
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 //matrice de rotation suivant x Mx[0, 0] := 1; Mx[0, 1] := 0; Mx[0, 2] := 0; Mx[0, 3] := 0; Mx[1, 0] := 0; Mx[1, 1] := cos(ax); Mx[1, 2] := sin(ax); Mx[1, 3] := 0; Mx[2, 0] := 0; Mx[2, 1] := -sin(ax); Mx[2, 2] := cos(ax); Mx[2, 3] := 0; Mx[3, 0] := 0; Mx[3, 1] := 0; Mx[3, 2] := 0; Mx[3, 3] := 1; //matrice de rotation suivant y My[0, 0] := cos(ay); My[0, 1] := 0; My[0, 2] := -sin(ay); My[0, 3] := 0; My[1, 0] := 0; My[1, 1] := 1; My[1, 2] := 0; My[1, 3] := 0; My[2, 0] := sin(ay); My[2, 1] := 0; My[2, 2] := cos(ay); My[2, 3] := 0; My[3, 0] := 0; My[3, 1] := 0; My[3, 2] := 0; My[3, 3] := 1; //matrice de rotation suivant z Mz[0, 0] := cos(az); Mz[0, 1] := sin(az); Mz[0, 2] := 0; Mz[0, 3] := 0; Mz[1, 0] := -sin(az); Mz[1, 1] := cos(az); Mz[1, 2] := 0; Mz[1, 3] := 0; Mz[2, 0] := 0; Mz[2, 1] := 0; Mz[2, 2] := 1; Mz[2, 3] := 0; Mz[3, 0] := 0; Mz[3, 1] := 0; Mz[3, 2] := 0; Mz[3, 3] := 1; //matrice de translation Mt[0, 0] := 1; Mt[0, 1] := 0; Mt[0, 2] := 0; Mt[0, 3] := trax; Mt[1, 0] := 0; Mt[1, 1] := 1; Mt[1, 2] := 0; Mt[1, 3] := tray; Mt[2, 0] := 0; Mt[2, 1] := 0; Mt[2, 2] := 1; Mt[2, 3] := traz; Mt[3, 0] := 0; Mt[3, 1] := 0; Mt[3, 2] := 0; Mt[3, 3] := 1; //matrice Mzt for i := 0 to 3 do for j := 0 to 3 do begin x := 0; for k := 0 to 3 do x := x + Mt[i, k] * Mz[k, j]; Mzt[i, j] := x; end; //matrice Myzt for i := 0 to 3 do for j := 0 to 3 do begin x := 0; for k := 0 to 3 do x := x + Mzt[i, k] * My[k, j]; Myzt[i, j] := x; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin x := 0; for k := 0 to 3 do x := x + Myzt[i, k] * Mx[k, j]; M[i, j] := x; end;
Déjà, j'ai fait un oubli fondamental ici :
Dans matrice, la variable locale x, je l'ai renommée en p pour éviter le conflit avec x coordonnée...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 procedure TFace.Position(tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 4 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(tetx,tety,tetz,dx,dy,dz); P[i].transform2D;//<----ici j'ai oublié de faire le passage en 2D :oops: end; end;
Après, la perspective est retrouvée, mais ce n'est toujours pas ça...
Il y a un point fondamental qu'il va falloir éclaicir...
Dans ton tuto, tu considères que ton z est rentrant et ton repère ne forme pas un trièdre direct, d'ailleurs tes coordonnées matricielles sont différentes des miennes...
Mais ce sont des coordonnées mathématiques... quand as -tu la correspondance en coordonnées informatiques ? Puisque la transfo 2D ne la produit pas...
D'ailleurs, j'ai vu que pour respecter une perspective correcte il fallait que la distance D entre la caméra(les yeux) et le plan de projection soit en général 2.5 fois supérieure à la principale dimension de l'objet.
x=D*x/z
y=D*y/z
(pour info)
Ma dernière version: vu que faire une translation suivi d'une rotation n'est pas la même chose que de faire une rotation suivi d'une translation, j'ai eu l'idée de commencer par faire ma translation...
j'en approche mais ce n'est toujours pas ça.
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 program Project1; {$FRAME_WIDTH 550} {$FRAME_HEIGHT 400} {$FRAME_RATE 12} {$BACKGROUND $FFFFFF} uses Flash8; Type TMatrice = array[0..3,0..3] of Double; TPoint3D = class x,y,z,ax,ay,az,trax,tray,traz:double;//a:angle et tr: pour la translation Mx,My,Mz,Mt,Myz,Mxyz,M:TMatrice; Procedure rotate(thetax,thetay,thetaz,tx,ty,tz:double); Procedure matrice; Procedure Transform2D; Constructor Create(xv,yv,zv:double); end; TFace=class(Movieclip) p: array[1..4] of TPoint3D; procedure position(tetx,tety,tetz,dx,dy,dz:double); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); end; Tunivers=class(Movieclip) roll:double; Face:array[1..4] of TFace; constructor Create(parent:Movieclip); procedure onEnterFrame;override; end; const carre:array[1..4,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0)); Constructor TPoint3D.Create(xv,yv,zv:double); begin x:=xv; y:=yv; z:=zv; end; procedure TPoint3D.Matrice; var i,j,k:integer; p:double; begin //matrice de rotation suivant x Mx[0, 0] := 1; Mx[0, 1] := 0; Mx[0, 2] := 0; Mx[0, 3] := 0; Mx[1, 0] := 0; Mx[1, 1] := cos(ax); Mx[1, 2] := sin(ax); Mx[1, 3] := 0; Mx[2, 0] := 0; Mx[2, 1] := -sin(ax); Mx[2, 2] := cos(ax); Mx[2, 3] := 0; Mx[3, 0] := 0; Mx[3, 1] := 0; Mx[3, 2] := 0; Mx[3, 3] := 1; //matrice de rotation suivant y My[0, 0] := cos(ay); My[0, 1] := 0; My[0, 2] := -sin(ay); My[0, 3] := 0; My[1, 0] := 0; My[1, 1] := 1; My[1, 2] := 0; My[1, 3] := 0; My[2, 0] := sin(ay); My[2, 1] := 0; My[2, 2] := cos(ay); My[2, 3] := 0; My[3, 0] := 0; My[3, 1] := 0; My[3, 2] := 0; My[3, 3] := 1; //matrice de rotation suivant z Mz[0, 0] := cos(az); Mz[0, 1] := sin(az); Mz[0, 2] := 0; Mz[0, 3] := 0; Mz[1, 0] := -sin(az); Mz[1, 1] := cos(az); Mz[1, 2] := 0; Mz[1, 3] := 0; Mz[2, 0] := 0; Mz[2, 1] := 0; Mz[2, 2] := 1; Mz[2, 3] := 0; Mz[3, 0] := 0; Mz[3, 1] := 0; Mz[3, 2] := 0; Mz[3, 3] := 1; //matrice de translation Mt[0, 0] := 1; Mt[0, 1] := 0; Mt[0, 2] := 0; Mt[0, 3] := trax; Mt[1, 0] := 0; Mt[1, 1] := 1; Mt[1, 2] := 0; Mt[1, 3] := tray; Mt[2, 0] := 0; Mt[2, 1] := 0; Mt[2, 2] := 1; Mt[2, 3] := traz; Mt[3, 0] := 0; Mt[3, 1] := 0; Mt[3, 2] := 0; Mt[3, 3] := 1; //je fais Mt*Mx*My*Mz //matrice Myz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mz[i, k] * My[k, j]; Myz[i, j] := p; end; //matrice Mxyz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Myz[i, k] * Mx[k, j]; Mxyz[i, j] := p; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mxyz[i, k] * Mt[k, j]; M[i, j] := p; end; end; Procedure TPoint3D.rotate(thetax,thetay,thetaz,tx,ty,tz:double); var x1,y1,z1:double; Begin ax:=thetax; ay:=thetay; az:=thetaz; trax:=tx; tray:=ty; traz:=tz; matrice; x1:=M[0,0]*x +M[0,1]*y{+M[0,2]*z}+M[0,3]; //z=0... y1:=M[1,0]*x +M[1,1]*y{+M[1,2]*z}+M[1,3]; z1:=M[2,0]*x +M[2,1]*y{+M[2,2]*z}+M[2,3]; x:=x1; y:=y1; z:=z1; end; Procedure TPoint3D.TransForm2D; begin if z<>-128 then begin x := 128 * x / (128 + z / 4); y := 128 * y / (128 + z / 4); end else exit; //x:=500*x/z; //x=D*x/z D doit être pris en général avec une valeur 2.5 fois supérieure à la principale dimension de l'objet (200 pixels ici) //y:=500*y/z; //y=D*y/z D distance entre la caméra et le plan de projection. end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); end; procedure TFace.Position(tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 4 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(tetx,tety,tetz,dx,dy,dz); P[i].transform2D; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); begin clear; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P[1].x,P[1].y); lineto(P[2].x,P[2].y); lineto(P[3].x,P[3].y); lineto(P[4].x,P[4].y); lineto(P[1].x,P[1].y); end; constructor TUnivers.Create(parent:Movieclip); //Var i:integer; begin inherited Create(Parent, 'univers',0); Face[1]:=TFace.Create(self,1); with Face[1] do begin position(0,0,0,0,0,100); //100 pour l'épaisseur, on met la face en avant plan de la distance correspondant à la moitié de l'arête (z=100) z est sortant...J'ai modifié les coordonnées des matrices pour un trièdre direct Tracer(3,clred); end; Face[2]:=TFace.Create(self,2); with Face[2] do begin position(0,math.pi/2,0,0,0,100); Tracer(3,clblue); end; Face[3]:=TFace.Create(self,3); with Face[3] do begin position(0,math.pi,0,0,0,100); Tracer(3,clgreen); end; Face[4]:=TFace.Create(self,4); with Face[4] do begin position(0,3*math.pi/2,0,0,0,100); Tracer(3,claqua); end; Face[5]:=TFace.Create(self,5); with Face[5] do begin position(math.pi/2,0,0,0,0,100); Tracer(3,clyellow); end; Face[6]:=TFace.Create(self,6); with Face[6] do begin position(-math.pi/2,0,0,0,0,100); Tracer(3,$ff00ff); end; _x:=stage.width/2; _y:=stage.height/2; end; procedure TUnivers.onEnterFrame; var r:double; begin //exit; roll:=roll+2; r:=math.pi*roll/180; with Face[1] do begin position(0,r,0,0,0,100); Tracer(3,clred); end; with Face[2] do begin position(0,Math.pi/2+r,0,0,0,100); Tracer(3,clblue); end; with Face[3] do begin position(0,math.pi+r,0,0,0,100); Tracer(3,clgreen); end; with Face[4] do begin position(0,3*math.pi/2+r,0,0,0,100); Tracer(3,claqua); end; with Face[5] do begin position(math.pi/2,r,0,0,0,100); Tracer(3,clyellow); end; with Face[6] do begin position(-math.pi/2,r,0,0,0,100); Tracer(3,$ff00ff); end; end; begin TUnivers.Create(_Root); end.
ben si, c'est bon, il manque juste le swapDepth()
pour ce faire, j'ai ajouté un 5ième point qui est le centre de la face (0,0,0) dans ton cas.
puis je fais un swapDepths(-P[5].z), c'est à dire que les faces du cubes sont triées en profondeur en fonction du Z de leur centre.
le problème avec cette approche c'est que quand 2 faces ont la même profondeur, le swapDepth() va bien positionner la première mais va donner à la seconde l'ancienne profondeur de la première.
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 program Project1; {$FRAME_WIDTH 550} {$FRAME_HEIGHT 400} {$FRAME_RATE 12} {$BACKGROUND $FFFFFF} uses Flash8; Type TMatrice = array[0..3,0..3] of Double; TPoint3D = class x,y,z,ax,ay,az,trax,tray,traz:double;//a:angle et tr: pour la translation Mx,My,Mz,Mt,Myz,Mxyz,M:TMatrice; Procedure rotate(thetax,thetay,thetaz,tx,ty,tz:double); Procedure matrice; Procedure Transform2D; Constructor Create(xv,yv,zv:double); end; TFace=class(Movieclip) p: array[1..4] of TPoint3D; procedure position(tetx,tety,tetz,dx,dy,dz:double); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); end; Tunivers=class(Movieclip) roll:double; Face:array[1..5] of TFace; constructor Create(parent:Movieclip); procedure onEnterFrame;override; end; const carre:array[1..5,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0),(0,0,0)); Constructor TPoint3D.Create(xv,yv,zv:double); begin x:=xv; y:=yv; z:=zv; end; procedure TPoint3D.Matrice; var i,j,k:integer; p:double; begin //matrice de rotation suivant x Mx[0, 0] := 1; Mx[0, 1] := 0; Mx[0, 2] := 0; Mx[0, 3] := 0; Mx[1, 0] := 0; Mx[1, 1] := cos(ax); Mx[1, 2] := sin(ax); Mx[1, 3] := 0; Mx[2, 0] := 0; Mx[2, 1] := -sin(ax); Mx[2, 2] := cos(ax); Mx[2, 3] := 0; Mx[3, 0] := 0; Mx[3, 1] := 0; Mx[3, 2] := 0; Mx[3, 3] := 1; //matrice de rotation suivant y My[0, 0] := cos(ay); My[0, 1] := 0; My[0, 2] := -sin(ay); My[0, 3] := 0; My[1, 0] := 0; My[1, 1] := 1; My[1, 2] := 0; My[1, 3] := 0; My[2, 0] := sin(ay); My[2, 1] := 0; My[2, 2] := cos(ay); My[2, 3] := 0; My[3, 0] := 0; My[3, 1] := 0; My[3, 2] := 0; My[3, 3] := 1; //matrice de rotation suivant z Mz[0, 0] := cos(az); Mz[0, 1] := sin(az); Mz[0, 2] := 0; Mz[0, 3] := 0; Mz[1, 0] := -sin(az); Mz[1, 1] := cos(az); Mz[1, 2] := 0; Mz[1, 3] := 0; Mz[2, 0] := 0; Mz[2, 1] := 0; Mz[2, 2] := 1; Mz[2, 3] := 0; Mz[3, 0] := 0; Mz[3, 1] := 0; Mz[3, 2] := 0; Mz[3, 3] := 1; //matrice de translation Mt[0, 0] := 1; Mt[0, 1] := 0; Mt[0, 2] := 0; Mt[0, 3] := trax; Mt[1, 0] := 0; Mt[1, 1] := 1; Mt[1, 2] := 0; Mt[1, 3] := tray; Mt[2, 0] := 0; Mt[2, 1] := 0; Mt[2, 2] := 1; Mt[2, 3] := traz; Mt[3, 0] := 0; Mt[3, 1] := 0; Mt[3, 2] := 0; Mt[3, 3] := 1; //je fais Mt*Mx*My*Mz //matrice Myz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mz[i, k] * My[k, j]; Myz[i, j] := p; end; //matrice Mxyz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Myz[i, k] * Mx[k, j]; Mxyz[i, j] := p; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mxyz[i, k] * Mt[k, j]; M[i, j] := p; end; end; Procedure TPoint3D.rotate(thetax,thetay,thetaz,tx,ty,tz:double); var x1,y1,z1:double; Begin ax:=thetax; ay:=thetay; az:=thetaz; trax:=tx; tray:=ty; traz:=tz; matrice; x1:=M[0,0]*x +M[0,1]*y{+M[0,2]*z}+M[0,3]; //z=0... y1:=M[1,0]*x +M[1,1]*y{+M[1,2]*z}+M[1,3]; z1:=M[2,0]*x +M[2,1]*y{+M[2,2]*z}+M[2,3]; x:=x1; y:=y1; z:=z1; end; Procedure TPoint3D.TransForm2D; begin if z<>-128 then begin x := 128 * x / (128 + z / 4); y := 128 * y / (128 + z / 4); end else exit; //x:=500*x/z; //x=D*x/z D doit être pris en général avec une valeur 2.5 fois supérieure à la principale dimension de l'objet (200 pixels ici) //y:=500*y/z; //y=D*y/z D distance entre la caméra et le plan de projection. end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); end; procedure TFace.Position(tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 5 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(tetx,tety,tetz,dx,dy,dz); P[i].transform2D; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); begin clear; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P[1].x,P[1].y); lineto(P[2].x,P[2].y); lineto(P[3].x,P[3].y); lineto(P[4].x,P[4].y); lineto(P[1].x,P[1].y); swapDepths(-P[5].z); end; constructor TUnivers.Create(parent:Movieclip); //Var i:integer; begin inherited Create(Parent, 'univers',0); Face[1]:=TFace.Create(self,1); with Face[1] do begin position(0,0,0,0,0,100); //100 pour l'épaisseur, on met la face en avant plan de la distance correspondant à la moitié de l'arête (z=100) z est sortant...J'ai modifié les coordonnées des matrices pour un trièdre direct Tracer(3,clred); end; Face[2]:=TFace.Create(self,2); with Face[2] do begin position(0,math.pi/2,0,0,0,100); Tracer(3,clblue); end; Face[3]:=TFace.Create(self,3); with Face[3] do begin position(0,math.pi,0,0,0,100); Tracer(3,clgreen); end; Face[4]:=TFace.Create(self,4); with Face[4] do begin position(0,3*math.pi/2,0,0,0,100); Tracer(3,claqua); end; Face[5]:=TFace.Create(self,5); with Face[5] do begin position(math.pi/2,0,0,0,0,100); Tracer(3,clyellow); end; Face[6]:=TFace.Create(self,6); with Face[6] do begin position(-math.pi/2,0,0,0,0,100); Tracer(3,$ff00ff); end; _x:=stage.width/2; _y:=stage.height/2; end; procedure TUnivers.onEnterFrame; var r:double; begin //exit; roll:=roll+2; r:=math.pi*roll/180; with Face[1] do begin position(0,r,0,0,0,100); Tracer(3,clred); end; with Face[2] do begin position(0,Math.pi/2+r,0,0,0,100); Tracer(3,clblue); end; with Face[3] do begin position(0,math.pi+r,0,0,0,100); Tracer(3,clgreen); end; with Face[4] do begin position(0,3*math.pi/2+r,0,0,0,100); Tracer(3,claqua); end; with Face[5] do begin position(math.pi/2,r,0,0,0,100); Tracer(3,clyellow); end; with Face[6] do begin position(-math.pi/2,r,0,0,0,100); Tracer(3,$ff00ff); end; end; begin TUnivers.Create(_Root); end.
exemple, la face 2 est en Z=5, si je place la face 3 qui est en Z= 12 en Z=5, c'est la face 2 qui récupère le Z = 12 (d'où le terme "swap" dans la méthode).
pour éviter ça, dans CubeMan je garde un index unique pour chaque face et le nombre total de faces. Puis j'applique la formule : swapDepths(ZOrder - Trunc(Z) * FaceCount), où ZOrder est le numéro de la face.
Comme ça, pour un Z = 5, face 2 sera en 2 + 5 * 6 = 32 et la face 3 en 3 + 5 * 6 = 33, comme ça je suis certain que je ne modifie pas la profondeur d'une autre face quand j'en positionne une.
Sur ce coup là, tu es optimiste... ajoute une rotation autour de x et tu verras...
Merci pour les faces, j'avais commencé à le faire mais comme je savais qu'en rotation en x, c'était faux, j'ai arrêté...Merci pour ton astuce aussi de cube man pour cette gestion des faces
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 program Project1; {$FRAME_WIDTH 550} {$FRAME_HEIGHT 400} {$FRAME_RATE 12} {$BACKGROUND $FFFFFF} uses Flash8; Type TMatrice = array[0..3,0..3] of Double; TPoint3D = class x,y,z,ax,ay,az,trax,tray,traz:double;//a:angle et tr: pour la translation Mx,My,Mz,Mt,Myz,Mxyz,M:TMatrice; Procedure rotate(thetax,thetay,thetaz,tx,ty,tz:double); Procedure matrice; Procedure Transform2D; Constructor Create(xv,yv,zv:double); end; TFace=class(Movieclip) p: array[1..4] of TPoint3D; procedure position(tetx,tety,tetz,dx,dy,dz:double); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); end; Tunivers=class(Movieclip) roll:double; Face:array[1..5] of TFace; constructor Create(parent:Movieclip); procedure onEnterFrame;override; end; const carre:array[1..5,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0),(0,0,0)); Constructor TPoint3D.Create(xv,yv,zv:double); begin x:=xv; y:=yv; z:=zv; end; procedure TPoint3D.Matrice; var i,j,k:integer; p:double; begin //matrice de rotation suivant x Mx[0, 0] := 1; Mx[0, 1] := 0; Mx[0, 2] := 0; Mx[0, 3] := 0; Mx[1, 0] := 0; Mx[1, 1] := cos(ax); Mx[1, 2] := sin(ax); Mx[1, 3] := 0; Mx[2, 0] := 0; Mx[2, 1] := -sin(ax); Mx[2, 2] := cos(ax); Mx[2, 3] := 0; Mx[3, 0] := 0; Mx[3, 1] := 0; Mx[3, 2] := 0; Mx[3, 3] := 1; //matrice de rotation suivant y My[0, 0] := cos(ay); My[0, 1] := 0; My[0, 2] := -sin(ay); My[0, 3] := 0; My[1, 0] := 0; My[1, 1] := 1; My[1, 2] := 0; My[1, 3] := 0; My[2, 0] := sin(ay); My[2, 1] := 0; My[2, 2] := cos(ay); My[2, 3] := 0; My[3, 0] := 0; My[3, 1] := 0; My[3, 2] := 0; My[3, 3] := 1; //matrice de rotation suivant z Mz[0, 0] := cos(az); Mz[0, 1] := sin(az); Mz[0, 2] := 0; Mz[0, 3] := 0; Mz[1, 0] := -sin(az); Mz[1, 1] := cos(az); Mz[1, 2] := 0; Mz[1, 3] := 0; Mz[2, 0] := 0; Mz[2, 1] := 0; Mz[2, 2] := 1; Mz[2, 3] := 0; Mz[3, 0] := 0; Mz[3, 1] := 0; Mz[3, 2] := 0; Mz[3, 3] := 1; //matrice de translation Mt[0, 0] := 1; Mt[0, 1] := 0; Mt[0, 2] := 0; Mt[0, 3] := trax; Mt[1, 0] := 0; Mt[1, 1] := 1; Mt[1, 2] := 0; Mt[1, 3] := tray; Mt[2, 0] := 0; Mt[2, 1] := 0; Mt[2, 2] := 1; Mt[2, 3] := traz; Mt[3, 0] := 0; Mt[3, 1] := 0; Mt[3, 2] := 0; Mt[3, 3] := 1; //je fais Mt*Mx*My*Mz //matrice Myz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mz[i, k] * My[k, j]; Myz[i, j] := p; end; //matrice Mxyz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Myz[i, k] * Mx[k, j]; Mxyz[i, j] := p; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mxyz[i, k] * Mt[k, j]; M[i, j] := p; end; end; Procedure TPoint3D.rotate(thetax,thetay,thetaz,tx,ty,tz:double); var x1,y1,z1:double; Begin ax:=thetax; ay:=thetay; az:=thetaz; trax:=tx; tray:=ty; traz:=tz; matrice; x1:=M[0,0]*x +M[0,1]*y{+M[0,2]*z}+M[0,3]; //z=0... y1:=M[1,0]*x +M[1,1]*y{+M[1,2]*z}+M[1,3]; z1:=M[2,0]*x +M[2,1]*y{+M[2,2]*z}+M[2,3]; x:=x1; y:=y1; z:=z1; end; Procedure TPoint3D.TransForm2D; begin if z<>-128 then begin x := 128 * x / (128 + z / 4); y := 128 * y / (128 + z / 4); end else exit; //x:=500*x/z; //x=D*x/z D doit être pris en général avec une valeur 2.5 fois supérieure à la principale dimension de l'objet (200 pixels ici) //y:=500*y/z; //y=D*y/z D distance entre la caméra et le plan de projection. end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); end; procedure TFace.Position(tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 5 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(tetx,tety,tetz,dx,dy,dz); P[i].transform2D; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); begin clear; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P[1].x,P[1].y); lineto(P[2].x,P[2].y); lineto(P[3].x,P[3].y); lineto(P[4].x,P[4].y); lineto(P[1].x,P[1].y); swapDepths(-P[5].z); end; constructor TUnivers.Create(parent:Movieclip); //Var i:integer; begin inherited Create(Parent, 'univers',0); Face[1]:=TFace.Create(self,1); with Face[1] do begin position(0,0,0,0,0,100); //100 pour l'épaisseur, on met la face en avant plan de la distance correspondant à la moitié de l'arête (z=100) z est sortant...J'ai modifié les coordonnées des matrices pour un trièdre direct Tracer(3,clred); end; Face[2]:=TFace.Create(self,2); with Face[2] do begin position(0,math.pi/2,0,0,0,100); Tracer(3,clblue); end; Face[3]:=TFace.Create(self,3); with Face[3] do begin position(0,math.pi,0,0,0,100); Tracer(3,clgreen); end; Face[4]:=TFace.Create(self,4); with Face[4] do begin position(0,3*math.pi/2,0,0,0,100); Tracer(3,claqua); end; Face[5]:=TFace.Create(self,5); with Face[5] do begin position(math.pi/2,0,0,0,0,100); Tracer(3,clyellow); end; Face[6]:=TFace.Create(self,6); with Face[6] do begin position(-math.pi/2,0,0,0,0,100); Tracer(3,$ff00ff); end; _x:=stage.width/2; _y:=stage.height/2; end; procedure TUnivers.onEnterFrame; var r:double; begin //exit; roll:=roll+2; r:=math.pi*roll/180; with Face[1] do begin position(r,r,0,0,0,100); Tracer(3,clred); end; with Face[2] do begin position(r,Math.pi/2+r,0,0,0,100); Tracer(3,clblue); end; with Face[3] do begin position(r,math.pi+r,0,0,0,100); Tracer(3,clgreen); end; with Face[4] do begin position(r,3*math.pi/2+r,0,0,0,100); Tracer(3,claqua); end; with Face[5] do begin position(math.pi/2+r,r,0,0,0,100); Tracer(3,clyellow); end; with Face[6] do begin position(-math.pi/2+r,r,0,0,0,100); Tracer(3,$ff00ff); end; end; begin TUnivers.Create(_Root); end.
J'ai vu sur un site Web en anglais que pour faire une transfo globale, il fallait toujours procédé par Mz*My*Mx et non le contraire...
je regarde cette piste.
merci pour ton aide
En exploitant cette piste: il y a deux faces qui ne collent pas sinon c'était bon...
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 //je fais Mt*Mz*My*Mx //matrice Myx for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mx[i, k] * My[k, j]; Myx[i, j] := p; end; //matrice Mzyx for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Myx[i, k] * Mz[k, j]; Mzyx[i, j] := p; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mzyx[i, k] * Mt[k, j]; M[i, j] := p; end;
il n'y a pas d'ordre établi, tout dépend de ce que tu veux faire
tu pourrais très bien définir statiquement les points de tes faces en 3D sans utiliser de rotation.
F1 (-1 -1 -1) (-1 +1 -1) (+1 +1 -1) (+1 -1 -1)
F2 (-1 -1 +1) (-1 +1 +1) (+1 +1 +1) (+1 -1 +1)
etc...
ou faire F1, rotation de 90° selon Y pour F2 à droite, une nouvelle rotation de 90° selon Y (180° au total) pour F3 derrière, encore 90° Y pour F4 à gauche, puis 90° suivant Z pour F5 au dessus et 180° suivant Z pour F6 en dessous
donc la matrice de F6 c'est M90y * M90y * M90y * M90z * M180z
mais tu peux aussi définir F6 comme une rotation M90x de F1
Je ne sais pas si on s'est compris...
En fait, je suis parti d'un carré dans le plan horizontal sans profondeur, ma constante tableau...
Je cherche à trouver une procedure unique qui gére toutes les rotations en même temps autour des axes ainsi que les translations...
J'ai un souci pour l'obtenir ; ma combinaison de matrices ne permet pas de garder les faces solidaires durant une quelconque rotation sur tous les axes.
Ma premiière face F1 est obtenue et définie dans le create de Tunivers.
Pour définir celle-ci à t=0, j'affecte mon carré initial à ma procedure en faisant uniquement une translation vers l'avant de 100 pixels (demi-arête).
F2 est défini toujours à partir de mon carré initial (constante tableau) en mettant encore en avant de 100 pixels et en faisant une rotation de pi/2 vers la droite suivant y.
F3 même chose avec une rotation de pi pour qu'elle se trouve en arrière.
F4,F5,F6... tout ça dans le create de TUnivers.
Enfin, dans le onEnterFrame, je voulais vérifier qu'en incrémentant un angle, je pouvais faire tourner mes faces formant un cube dans toutes les directions en faisant évolué mon angle incrémenté à chaque frame.
J'ai donc repris la configuration initiale de mes faces à t=0 (dans constructorTunivers.create) et j'ai ajouté en plus dans les trois directions, l'angle qui s'incrémente pour voir si ma procedure globale de rotation affectait de la même manière mes rotations suivant x,y et z.
Et bien certaines faces ne tournent pas dans le sens prévu donc ma composition de matrices est fausse et c'est là que je galère depuis un moment...
si je comprend bien :
tu construis ton cube à base de transformation de la face, OK ce n'est pas un problème.
maintenant tu veux faire tourner tout le cube en gardant les faces solidaires.
pour cela, il faut insérer la transformation du cube AVANT la transformation de la face.
voici un exemple ou j'utilise une matrice au niveau de l'univers qui est combinée avec la matrice de transformation de chaque point.
Pour avoir plusieurs rotations sur le cube, il faut là encore combiner des matrices de rotations comme on le fait avec TPoint3D
mais je trouve tout de même plus simple d'utiliser un objet Matrice 3D, ça évite de déclarer des tas de tableaux à multiplier les uns avec les autres.
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367 program Project1; {$FRAME_WIDTH 550} {$FRAME_HEIGHT 400} {$FRAME_RATE 12} {$BACKGROUND $FFFFFF} uses Flash8; Type TMatrice = array[0..3,0..3] of Double; TPoint3D = class x,y,z,ax,ay,az,trax,tray,traz:double;//a:angle et tr: pour la translation Mx,My,Mz,Mt,Myz,Mxyz,M:TMatrice; Procedure rotate(M0: TMatrice; thetax,thetay,thetaz,tx,ty,tz:double); Procedure matrice; Procedure Transform2D; Constructor Create(xv,yv,zv:double); end; TFace=class(Movieclip) p: array[1..4] of TPoint3D; procedure position(M: TMatrice; tetx,tety,tetz,dx,dy,dz:double); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); end; Tunivers=class(Movieclip) roll:double; M: TMatrice; Face:array[1..5] of TFace; constructor Create(parent:Movieclip); procedure onEnterFrame;override; end; const carre:array[1..5,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0),(0,0,0)); Constructor TPoint3D.Create(xv,yv,zv:double); begin x:=xv; y:=yv; z:=zv; end; procedure TPoint3D.Matrice; var i,j,k:integer; p:double; begin //matrice de rotation suivant x Mx[0, 0] := 1; Mx[0, 1] := 0; Mx[0, 2] := 0; Mx[0, 3] := 0; Mx[1, 0] := 0; Mx[1, 1] := cos(ax); Mx[1, 2] := sin(ax); Mx[1, 3] := 0; Mx[2, 0] := 0; Mx[2, 1] := -sin(ax); Mx[2, 2] := cos(ax); Mx[2, 3] := 0; Mx[3, 0] := 0; Mx[3, 1] := 0; Mx[3, 2] := 0; Mx[3, 3] := 1; //matrice de rotation suivant y My[0, 0] := cos(ay); My[0, 1] := 0; My[0, 2] := -sin(ay); My[0, 3] := 0; My[1, 0] := 0; My[1, 1] := 1; My[1, 2] := 0; My[1, 3] := 0; My[2, 0] := sin(ay); My[2, 1] := 0; My[2, 2] := cos(ay); My[2, 3] := 0; My[3, 0] := 0; My[3, 1] := 0; My[3, 2] := 0; My[3, 3] := 1; //matrice de rotation suivant z Mz[0, 0] := cos(az); Mz[0, 1] := sin(az); Mz[0, 2] := 0; Mz[0, 3] := 0; Mz[1, 0] := -sin(az); Mz[1, 1] := cos(az); Mz[1, 2] := 0; Mz[1, 3] := 0; Mz[2, 0] := 0; Mz[2, 1] := 0; Mz[2, 2] := 1; Mz[2, 3] := 0; Mz[3, 0] := 0; Mz[3, 1] := 0; Mz[3, 2] := 0; Mz[3, 3] := 1; //matrice de translation Mt[0, 0] := 1; Mt[0, 1] := 0; Mt[0, 2] := 0; Mt[0, 3] := trax; Mt[1, 0] := 0; Mt[1, 1] := 1; Mt[1, 2] := 0; Mt[1, 3] := tray; Mt[2, 0] := 0; Mt[2, 1] := 0; Mt[2, 2] := 1; Mt[2, 3] := traz; Mt[3, 0] := 0; Mt[3, 1] := 0; Mt[3, 2] := 0; Mt[3, 3] := 1; //je fais Mt*Mx*My*Mz //matrice Myz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mz[i, k] * My[k, j]; Myz[i, j] := p; end; //matrice Mxyz for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Myz[i, k] * Mx[k, j]; Mxyz[i, j] := p; end; // matrice totale avec translation for i := 0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mxyz[i, k] * Mt[k, j]; M[i, j] := p; end; end; Procedure TPoint3D.rotate(M0: TMatrice; thetax,thetay,thetaz,tx,ty,tz:double); var x1,y1,z1:double; MFinale: TMatrice; i,j:Integer; Begin ax:=thetax; ay:=thetay; az:=thetaz; trax:=tx; tray:=ty; traz:=tz; matrice; for i := 0 to 3 do for j := 0 to 3 do MFinale[i, j] := M0[i, 0] * M[0, j] + M0[i, 1] * M[1, j] + M0[i, 2] * M[2, j] + M0[i, 3] * M[3, j]; x1:=MFinale[0,0]*x +MFinale[0,1]*y{+M[0,2]*z}+MFinale[0,3]; //z=0... y1:=MFinale[1,0]*x +MFinale[1,1]*y{+M[1,2]*z}+MFinale[1,3]; z1:=MFinale[2,0]*x +MFinale[2,1]*y{+M[2,2]*z}+MFinale[2,3]; x:=x1; y:=y1; z:=z1; end; Procedure TPoint3D.TransForm2D; begin if z<>-128 then begin x := 128 * x / (128 + z / 4); y := 128 * y / (128 + z / 4); end else exit; //x:=500*x/z; //x=D*x/z D doit être pris en général avec une valeur 2.5 fois supérieure à la principale dimension de l'objet (200 pixels ici) //y:=500*y/z; //y=D*y/z D distance entre la caméra et le plan de projection. end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); end; procedure TFace.Position(M: TMatrice; tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 5 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(M, tetx,tety,tetz,dx,dy,dz); P[i].transform2D; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); begin clear; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P[1].x,P[1].y); lineto(P[2].x,P[2].y); lineto(P[3].x,P[3].y); lineto(P[4].x,P[4].y); lineto(P[1].x,P[1].y); swapDepths(-P[5].z); end; constructor TUnivers.Create(parent:Movieclip); //Var i:integer; begin inherited Create(Parent, 'univers',0); M[0,0] := 1; M[0,1] := 0; M[0,2] := 0; M[0,3] := 0; M[1,0] := 0; M[1,1] := 1; M[1,2] := 0; M[1,3] := 0; M[2,0] := 0; M[2,1] := 0; M[2,2] := 1; M[2,3] := 0; M[3,0] := 0; M[3,1] := 0; M[3,2] := 0; M[3,3] := 1; Face[1]:=TFace.Create(self,1); with Face[1] do begin position(M, 0,0,0,0,0,100); //100 pour l'épaisseur, on met la face en avant plan de la distance correspondant à la moitié de l'arête (z=100) z est sortant...J'ai modifié les coordonnées des matrices pour un trièdre direct Tracer(3,clred); end; Face[2]:=TFace.Create(self,2); with Face[2] do begin position(M, 0,math.pi/2,0,0,0,100); Tracer(3,clblue); end; Face[3]:=TFace.Create(self,3); with Face[3] do begin position(M, 0,math.pi,0,0,0,100); Tracer(3,clgreen); end; Face[4]:=TFace.Create(self,4); with Face[4] do begin position(M, 0,3*math.pi/2,0,0,0,100); Tracer(3,claqua); end; Face[5]:=TFace.Create(self,5); with Face[5] do begin position(M, math.pi/2,0,0,0,0,100); Tracer(3,clyellow); end; Face[6]:=TFace.Create(self,6); with Face[6] do begin position(M, -math.pi/2,0,0,0,0,100); Tracer(3,$ff00ff); end; _x:=stage.width/2; _y:=stage.height/2; end; procedure TUnivers.onEnterFrame; var r:double; begin //exit; roll:=roll+2; r:=math.pi*roll/180; M[0, 0] := cos(r); M[0, 1] := sin(r); M[1, 0] := -sin(r); M[1, 1] := cos(r); with Face[1] do begin position(M, 0,r,0,0,0,100); Tracer(3,clred); end; with Face[2] do begin position(M, 0,Math.pi/2+r,0,0,0,100); Tracer(3,clblue); end; with Face[3] do begin position(M, 0,math.pi+r,0,0,0,100); Tracer(3,clgreen); end; with Face[4] do begin position(M, 0,3*math.pi/2+r,0,0,0,100); Tracer(3,claqua); end; with Face[5] do begin position(M, math.pi/2,r,0,0,0,100); Tracer(3,clyellow); end; with Face[6] do begin position(M, -math.pi/2,r,0,0,0,100); Tracer(3,$ff00ff); end; end; begin TUnivers.Create(_Root); end.
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 program Project1; {$FRAME_WIDTH 550} {$FRAME_HEIGHT 400} {$FRAME_RATE 12} {$BACKGROUND $FFFFFF} uses Flash8; type TMatrixData = array[0..15] of Double; TMatrix3d = class Values: TMatrixData; M : TMatrixData; V : TMatrixData; x,y,z : Double; x2d : Double; y2d : Double; constructor Create; procedure Reset; procedure Mult(); procedure Translate(tx, ty, tz: Double); procedure RotateX(A: Double); procedure RotateY(A: Double); procedure RotateZ(A: Double); procedure Transform(ax, ay, az: Double); procedure Assign(AMatrix: TMatrix3d); end; constructor TMatrix3d.Create; var i: Integer; begin for i := 0 to 15 do M[i] := 0; M[ 0] := 1; M[ 5] := 1; M[10] := 1; M[15] := 1; Reset; end; procedure TMatrix3d.Reset; var i: Integer; begin for i := 0 to 15 do Values[i] := M[i]; end; procedure TMatrix3d.Mult(); var i, j: Integer; begin for i := 0 to 3 do for j := 0 to 3 do V[4 * i + j] := M[4 * i ] * Values[ j] + M[4 * i + 1] * Values[ 4 + j] + M[4 * i + 2] * Values[ 8 + j] + M[4 * i + 3] * Values[12 + j]; for i := 0 to 15 do Values[i] := V[i]; end; procedure TMatrix3d.Translate(tx, ty, tz: Double); begin M[12] := tx; M[13] := ty; M[14] := tz; Mult(); M[12] := 0; M[13] := 0; M[14] := 0; end; procedure TMatrix3d.RotateX(A: Double); begin if A <> 0 then begin M[ 5] := cos(a); M[ 6] :=-sin(a); M[ 9] :=-M[6]; M[10] := M[5]; Mult(); M[ 5] := 1; M[ 6] := 0; M[ 9] := 0; M[10] := 1; end; end; procedure TMatrix3d.RotateY(A: Double); begin if A <> 0 then begin M[ 0] := cos(a); M[ 2] := sin(a); M[ 8] :=-M[2]; M[10] := M[0]; Mult(); M[ 0] := 1; M[ 2] := 0; M[ 8] := 0; M[10] := 1; end; end; procedure TMatrix3d.RotateZ(A: Double); begin if A <> 0 then begin M[ 0] := cos(a); M[ 1] :=-sin(a); M[ 4] :=-M[1]; M[ 5] := M[0]; Mult(); M[ 0] := 1; M[ 1] := 0; M[ 4] := 0; M[ 5] := 1; end; end; procedure TMatrix3d.Transform(ax, ay, az: Double); begin x := ax * Values[0] + ay * Values[4] + az * Values[ 8] + Values[12]; y := ax * Values[1] + ay * Values[5] + az * Values[ 9] + Values[13]; z := ax * Values[2] + ay * Values[6] + az * Values[10] + Values[14]; x2d := 128 * x / (128 + z / 4); y2d := 128 * y / (128 + z / 4); end; procedure TMatrix3d.Assign(AMatrix: TMatrix3d); var i: Integer; begin for i := 0 to 15 do Values[i] := AMatrix.Values[i]; end; type TPoint3D = class x,y,z:double; M:TMatrix3d; Procedure rotate(M0: TMatrix3d; thetax,thetay,thetaz,tx,ty,tz:double); Procedure matrice; Procedure Transform2D; Constructor Create(xv,yv,zv:double); end; TFace=class(Movieclip) p: array[1..4] of TPoint3D; procedure position(M: TMatrix3d; tetx,tety,tetz,dx,dy,dz:double); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); end; Tunivers=class(Movieclip) roll:double; M: TMatrix3d; Face:array[1..5] of TFace; constructor Create(parent:Movieclip); procedure onEnterFrame;override; end; const carre:array[1..5,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0),(0,0,0)); Constructor TPoint3D.Create(xv,yv,zv:double); begin x:=xv; y:=yv; z:=zv; M := TMatrix3D.Create; end; procedure TPoint3D.Matrice; var i,j,k:integer; p:double; begin end; Procedure TPoint3D.rotate(M0: TMatrix3d; thetax,thetay,thetaz,tx,ty,tz:double); var x1,y1,z1:double; i,j:Integer; Begin // Transformations du cube M.Assign(M0); //matrice de rotation suivant z M.RotateZ(thetaz); //matrice de rotation suivant y M.RotateY(thetay); //matrice de rotation suivant x M.RotateX(thetax); //matrice de translation M.Translate(tx, ty, tz); // Transformer le point 3D suivant la matrice résultante M M.Transform(x, y, z); x := M.x; y := M.y; z := M.z; end; Procedure TPoint3D.TransForm2D; begin if z<>-128 then begin x := 128 * x / (128 + z / 4); y := 128 * y / (128 + z / 4); end else exit; //x:=500*x/z; //x=D*x/z D doit être pris en général avec une valeur 2.5 fois supérieure à la principale dimension de l'objet (200 pixels ici) //y:=500*y/z; //y=D*y/z D distance entre la caméra et le plan de projection. end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); end; procedure TFace.Position(M: TMatrix3d; tetx,tety,tetz,dx,dy,dz:double); var i:integer; begin for i:=1 to 5 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].rotate(M, tetx,tety,tetz,dx,dy,dz); P[i].transform2D; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); begin clear; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P[1].x,P[1].y); lineto(P[2].x,P[2].y); lineto(P[3].x,P[3].y); lineto(P[4].x,P[4].y); lineto(P[1].x,P[1].y); swapDepths(-P[5].z); end; constructor TUnivers.Create(parent:Movieclip); //Var i:integer; begin inherited Create(Parent, 'univers',0); M := TMatrix3D.Create; Face[1]:=TFace.Create(self,1); with Face[1] do begin position(M, 0,0,0,0,0,100); //100 pour l'épaisseur, on met la face en avant plan de la distance correspondant à la moitié de l'arête (z=100) z est sortant...J'ai modifié les coordonnées des matrices pour un trièdre direct Tracer(3,clred); end; Face[2]:=TFace.Create(self,2); with Face[2] do begin position(M, 0,math.pi/2,0,0,0,100); Tracer(3,clblue); end; Face[3]:=TFace.Create(self,3); with Face[3] do begin position(M, 0,math.pi,0,0,0,100); Tracer(3,clgreen); end; Face[4]:=TFace.Create(self,4); with Face[4] do begin position(M, 0,3*math.pi/2,0,0,0,100); Tracer(3,claqua); end; Face[5]:=TFace.Create(self,5); with Face[5] do begin position(M, math.pi/2,0,0,0,0,100); Tracer(3,clyellow); end; Face[6]:=TFace.Create(self,6); with Face[6] do begin position(M, -math.pi/2,0,0,0,0,100); Tracer(3,$ff00ff); end; _x:=stage.width/2; _y:=stage.height/2; end; procedure TUnivers.onEnterFrame; var r:double; begin //exit; roll:=roll+2; r:=math.pi*roll/180; M.Reset(); M.RotateZ(r); with Face[1] do begin position(M, 0,r,0,0,0,100); Tracer(3,clred); end; with Face[2] do begin position(M, 0,Math.pi/2+r,0,0,0,100); Tracer(3,clblue); end; with Face[3] do begin position(M, 0,math.pi+r,0,0,0,100); Tracer(3,clgreen); end; with Face[4] do begin position(M, 0,3*math.pi/2+r,0,0,0,100); Tracer(3,claqua); end; with Face[5] do begin position(M, math.pi/2,r,0,0,0,100); Tracer(3,clyellow); end; with Face[6] do begin position(M, -math.pi/2,r,0,0,0,100); Tracer(3,$ff00ff); end; end; begin TUnivers.Create(_Root); end.
Merci pour ta réponse et tes solutions...
Je regarde ça...
Petite remarque: il faut mettre -100 en z, en effet z est bien rentrant dans cette configuration. Pour preuve, on doit commencer par une face rouge...
Il y a déjà cet exemple dans le forum mais apparemment la technique utilisée n'est pas la même.
Pour la rotation du cube de pi/4 en x,y et z, tu peux toujours faire ça :
Pour le tracé de la fonction trigo, je n'ai pas regardé de mais ça a l'air simple...
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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290 program Project1; {$FRAME_WIDTH 500} {$FRAME_HEIGHT 500} {$FRAME_RATE 40} {$BACKGROUND $E0E0E0} uses Flash8; Type TMatrice = class procedure Produitmatriciel; procedure Translate(tx, ty, tz: number); procedure RotateX(ax: number); procedure RotateY(ay: number); procedure RotateZ(az: number); Constructor Create; end; TPoint3D = class x,y,z:number; Function Transform2d:Point; procedure Transform; Constructor Create(xv,yv,zv:number); end; TFace=class(Movieclip) zorder:integer; size:number; p: array[1..5] of TPoint3D; procedure build(tx,ty,tz,Rx,Ry,Rz:number); procedure Tracer(penw:integer;ColorFill:integer); constructor Create (parent:Movieclip;Depth:integer); procedure position; end; TCube=class(Movieclip) posi:integer; Face:array[1..5] of TFace; procedure Reset; constructor Create(parent:Movieclip;Depth:integer); procedure onEnterFrame;override; end; const carre:array[1..5,1..3]of double=((-100,-100,0),(100,-100,0),(100,100,0),(-100,100,0),(0,0,0)); pi=3.141592654; var matrice:TMatrice; Values,Mi,V,id: array[0..3,0..3] of number; Constructor TPoint3D.Create(xv,yv,zv:number); begin x:=xv; y:=yv; z:=zv; end; procedure TPoint3D.Transform; var x1,y1,z1:number; begin x1 := x * Values[0,0] + y * Values[0,1] +z * Values[ 0,2] + Values[0,3]; y1 := x * Values[1,0] + y * Values[1,1] +z * Values[ 1,2] + Values[1,3]; z1 := x * Values[2,0] + y * Values[2,1] +z * Values[2,2] + Values[2,3]; x:=x1; y:=y1; z:=z1; end; Function TPoint3D.Transform2d:Point; begin result:=Point.Create(128 * x / (128 + z / 4),128 * y / (128 + z / 4)); end; Constructor TMatrice.Create; var i,j: Integer; begin id[0, 0] := 1; id[1, 0] := 0; id[2, 0] := 0; id[3, 0] := 0; //matrice identité id[0, 1] := 0; id[1, 1] := 1; id[2, 1] := 0; id[3, 1] := 0; id[0, 2] := 0; id[1, 2] := 0; id[2, 2] := 1; id[3, 2] := 0; id[0, 3] := 0; id[1, 3] := 0; id[2, 3] := 0; id[3, 3] := 1; for i := 0 to 3 do //initialisation des matrices à identité for j:=0 to 3 do begin Values[i,j] :=id[i,j]; Mi[i,j]:=id[i,j]; end; end; Procedure TMatrice.Produitmatriciel; var i,j,k: Integer; p:number; begin for i:=0 to 3 do for j := 0 to 3 do begin p := 0; for k := 0 to 3 do p := p + Mi[i, k] * values[k, j]; V[i,j] := p; end; for i := 0 to 3 do for j := 0 to 3 do Values[i,j] := V[i,j]; end; procedure TMatrice.Translate(tx, ty, tz: number); begin Mi[0, 0] := 1; Mi[1, 0] := 0; Mi[2, 0] := 0; Mi[3, 0] := 0; Mi[0, 1] := 0; Mi[1, 1] := 1; Mi[2, 1] := 0; Mi[3, 1] := 0; Mi[0, 2] := 0; Mi[1, 2] := 0; Mi[2, 2] := 1; Mi[3, 2] := 0; Mi[0, 3] := tx; Mi[1, 3] := ty; Mi[2, 3] := tz; Mi[3, 3] := 1; Produitmatriciel; //réinitialisation de Mi à matrice identité Mi[0, 3] := 0; Mi[1, 3] := 0; Mi[2, 3] := 0; end; Procedure TMatrice.RotateX(ax: number); var cax,sax:number; begin if ax<>0 then begin cax:=cos(ax); sax:=sin(ax); Mi[0, 0] := 1; Mi[1, 0] := 0; Mi[2, 0] := 0; Mi[3, 0] := 0; Mi[0, 1] := 0; Mi[1, 1] := cax; Mi[2, 1] := -sax; Mi[3, 1] := 0; Mi[0, 2] := 0; Mi[1, 2] := sax; Mi[2, 2] := cax; Mi[3, 2] := 0; Mi[0, 3] := 0; Mi[1, 3] := 0; Mi[2, 3] := 0; Mi[3, 3] := 1; Produitmatriciel; //réinitialisation de Mi à matrice identité Mi[1, 1] := 1; Mi[1, 2] := 0; Mi[2, 1] := 0; Mi[2, 2] := 1; end; end; Procedure TMatrice.RotateY(ay: number); var cay,say:number; begin if ay<>0 then begin cay:=cos(ay); say:=sin(ay); Mi[0, 0] := cay; Mi[1, 0] := 0; Mi[2, 0] := -say; Mi[3, 0] := 0; Mi[0, 1] := 0; Mi[1, 1] := 1; Mi[2, 1] := 0; Mi[3, 1] := 0; Mi[0, 2] := say; Mi[1, 2] := 0; Mi[2, 2] := cay; Mi[3, 2] := 0; Mi[0, 3] := 0; Mi[1, 3] := 0; Mi[2, 3] := 0; Mi[3, 3] := 1; Produitmatriciel; //réinitialisation de Mi à matrice identité Mi[0, 0] := 1; Mi[0, 2] := 0; Mi[2, 0] := 0; Mi[2, 2] := 1; end; end; Procedure TMatrice.RotateZ(az: number); var caz,saz:number; begin if az<> 0 then begin caz:=cos(az); saz:=sin(az); Mi[0, 0] := caz; Mi[1, 0] := -saz; Mi[2, 0] := 0; Mi[3, 0] := 0; Mi[0, 1] := saz; Mi[1, 1] := caz; Mi[2, 1] := 0; Mi[3, 1] := 0; Mi[0, 2] := 0; Mi[1, 2] := 0; Mi[2, 2] := 1; Mi[3, 2] := 0; Mi[0, 3] := 0; Mi[1, 3] := 0; Mi[2, 3] := 0; Mi[3, 3] := 1; Produitmatriciel; //réinitialisation de Mi à matrice identité Mi[0, 0] := 1; Mi[0, 1] := 0; Mi[1, 0] := 0; Mi[1, 1] := 1; end; end; constructor TFace.Create (parent:Movieclip;Depth:integer); begin inherited Create(Parent, 'face' + IntToStr(Depth),Depth); Matrice:=TMatrice.Create; zorder:=Depth; end; procedure TFace.build(tx,ty,tz,Rx,Ry,Rz:number); var i:integer; begin Matrice.Translate(tx,ty,tz); Matrice.RotateX(Rx); Matrice.RotateY(Ry); Matrice.RotateZ(Rz); for i:=1 to 5 do begin P[i]:=TPoint3D.Create(carre[i,1],carre[i,2],carre[i,3]); P[i].transform; end; end; procedure TFace.Tracer(penw:integer;ColorFill:integer); var i:integer; P1:Point; begin clear; P1:=P[1].Transform2D; Linestyle(penw,clBlack); BeginFill(colorFill); moveto(P1.x,P1.y); for i:=2 to 4 do lineto(P[i].Transform2D.x,P[i].Transform2D.y); Lineto(P1.x,P1.y); swapDepths(Zorder-Trunc(P[5].z)); end; procedure TFace.position; var i:integer; begin for i:=1 to 5 do P[i].Transform; end; constructor TCube.Create(parent:Movieclip;Depth:integer); var i:integer; begin inherited Create(Parent, 'cube' + IntToStr(Depth),Depth); For i:=1 to 6 do Face[i]:=TFace.Create(self,i); Face[1].build(0,0,-100,0,0,0); Face[2].build(0,0,0,0,pi/2,0); Face[3].build(0,0,0,0,pi/2,0); Face[4].build(0,0,0,0,pi/2,0); Face[5].build(0,0,0,0,0,pi/2); Face[6].build(0,0,0,0,0,pi); _x:=stage.width/2; _y:=stage.height/2; Reset; end; procedure TCube.Reset; var i,j: Integer; begin for i := 0 to 3 do for j:=0 to 3 do Values[i,j] := id[i,j]; end; procedure TCube.onEnterFrame; var i:integer; begin inc(posi); if posi<=45 then Matrice.rotatex(pi/180); if (posi>45) and (posi<=90) then Matrice.rotatey(pi/180); if (posi>90) and (posi<=135) then Matrice.rotatez(pi/180); if posi>135 then posi:=0; For i:=1 to 6 do Face[i].position; Face[1].tracer(3,clred); Face[2].tracer(3,clblue); Face[3].tracer(3,clgreen); Face[4].tracer(3,clyellow); Face[5].tracer(3,claqua); Face[6].tracer(3,$ff00ff); reset; end; begin TCube.Create(_Root,0); end.
Merci pour ton exemple, Anthony : il est très réussi. Je vais m'y pencher.
Partager