Bonjour,

Je suis en train de réaliser un menu de site internet sous forme d'un cube 3D en Flash. J'ai récupéré des fichiers d'un certain Ericlin que j'ai pu adapter sans problème.

Cependant, il me reste une seule chose sur laquelle je bute depuis vendredi : un petit problème de perspective. En effet, la face arrière paraît plus grande que la face avant...

Voici un apperçu :
http://atomikedesign.e3b.org/arrobe/cube_arrobe.html

Je pense que ce problème peut être corrigé dans le fichier math3d.as donc voici le contenu :
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
class Math3d {
    //by ericlin
    // (oui, c'est un fichier trouvé sur le net car ce sont des fonctions mathématiques bien au dessus de mon niveau)
    static function vector(proxPoint, distPoint) {
        var x = distPoint.x-proxPoint.x;
        var y = distPoint.y-proxPoint.y;
        var z = distPoint.z-proxPoint.z;
        return {x:x, y:y, z:z};
    }
    static function getLength(vector1) {
        var a1 = vector1.x;
        var b1 = vector1.y;
        var c1 = vector1.z;
        return Math.sqrt(a1*a1+b1*b1+c1*c1);
    }
    static function isZero(floatNumber) {
        //to serve as "==" for floatNumber; ->Flash has inaccuracy
        if (Math.abs(floatNumber)<0.00001) {
            return true;
        }
        return false;
    }
    static function getMidPoint(point1, point2) {
        var a1 = point1.x;
        var b1 = point1.y;
        var c1 = point1.z;
        var a2 = point2.x;
        var b2 = point2.y;
        var c2 = point2.z;
        return {x:(a1+a2)/2, y:(b1+b2)/2, z:(c1+c2)/2};
    }
 
    static function distance(pt1, pt2) {
        var dy = pt2.y-pt1.y;
        var dx = pt2.x-pt1.x;
        return Math.sqrt(dy*dy+dx*dx);
    }
    //=========================================
    static function getAngle(vector1, vector2) {
        var a1 = vector1.x;
        var b1 = vector1.y;
        var c1 = vector1.z;
        var a2 = vector2.x;
        var b2 = vector2.y;
        var c2 = vector2.z;
        var dotP = (a1*a2+b1*b2+c1*c2);
        var cos = dotP/(getLength(vector1)*getLength(vector2));
        //trace("dotP="+dotP+", len1="+getLength(vector1)+",len2="+getLength(vector2)+",cos="+cos);
        var sin2 = 1-cos*cos;
        if (sin2<0) {
            trace(" wrong "+cos);
            sin2 = 0;
        }
        //I took long time to find this bug. Who can guess that (1-cos*cos) is negative ?!
        //sqrt returns a NaN for a negative value ! 
        return Math.atan2(Math.sqrt(sin2), cos);
    }
    //=====================================
    static function getRotateAxis(vector1, vector2) {
        //get the axis that perpendicular to the plane formed by vector1 and vector2;
        //the answer is not unique. At least, the negative axis will also be an answer.
        //if two vectors are in line, then the answer would be a plane.
        //Here just get one of them out for use. No attemp to get all of them.        
        var a1 = vector1.x;
        var b1 = vector1.y;
        var c1 = vector1.z;
        var a2 = vector2.x;
        var b2 = vector2.y;
        var c2 = vector2.z;
        var x, y, z;
        //solve this two equations: since dotProduct should be 0;
        //a1*x+b1.y+c1*z=0;
        //a2*x+b2*y+c2*z=0
        if (!isZero(a1*b2-b1*a2)) {
            z = 1;
            y = (c1*a2-c2*a1)/(a1*b2-a2*b1);
            x = (c1*b2-c2*b1)/(b1*a2-b2*a1);
            return {x:x, y:y, z:z};
        }
        z = 0;
        //z=0, axis in xy plane;
        if (!isZero(a1)) {
            y = 1;
            x = -b1/a1;
            return {x:x, y:y, z:z};
        }
        // it is X axis;
        y = 0;
        x = 1;
        return {x:x, y:y, z:z};
    }
    //=========================================
    static function getRotateAngle(axis, vector1, vector2) {
        var angle = getAngle(vector1, vector2);
        var test = {x:vector1.x, y:vector1.y, z:vector1.z};
        rotate3d(test, axis, angle);
        var angle2 = getAngle(test, vector2);
        if (isZero(angle2)) {
            trace("posi angle");
            return angle;
        }
        //------------for sure, I confirm it. If you dare, you might just return -angle without recheck.
        test = {x:vector1.x, y:vector1.y, z:vector1.z};
        rotate3d(test, axis, -angle);
        angle2 = getAngle(test, vector2);
        if (isZero(angle2)) {
            trace("nega angle");
            return -angle;
        }
        trace("no match");
        return null;
    }
    //====================================================
    static function rotate2d(x, y, pAngle) {
        var sin = Math.sin(pAngle);
        var cos = Math.cos(pAngle);
        return {x:x*cos-y*sin, y:x*sin+y*cos};
    }
    static function rotate3d(point, axis, pAngle) {
        //permantantly change the point data but preserved the axis data
        //axis={x:  ,y:  ,z}
        var vAxis = {x:axis.x, y:axis.y, z:axis.z};
        //copy to preserve original one        
        //rotate around X axis:
        var xRot = Math.atan2(vAxis.y, vAxis.z);
        if (xRot != 0) {
            var pt = rotate2d(vAxis.z, vAxis.y, -xRot);
            vAxis.z=pt.x, vAxis.y=pt.y;
            var pt = rotate2d(point.z, point.y, -xRot);
            point.z=pt.x, point.y=pt.y;
        }
        //now on z, x plane;
        var yRot = Math.atan2(vAxis.z, vAxis.x);
        if (yRot != 0) {
            //var pt = rotate2d(vAxis.x, vAxis.z, -yRot);
            //vAxis.x=pt.x, vAxis.z=pt.y;
            var pt = rotate2d(point.x, point.z, -yRot);
            point.x=pt.x, point.z=pt.y;
        }
        //now on vAxis is the X axis;
        var pt = rotate2d(point.z, point.y, pAngle);
        point.z=pt.x, point.y=pt.y;
        //rotate back to original vAxis;
        if (yRot != 0) {
            var pt = rotate2d(point.x, point.z, yRot);
            point.x=pt.x, point.z=pt.y;
        }
        if (xRot != 0) {
            var pt = rotate2d(point.z, point.y, xRot);
            point.z=pt.x, point.y=pt.y;
        }
    }
    //----------------------------------
    static function rotate3dArray(points, axis, pAngle) {
        //modify so that we dont repeatedly calculate sin cos  for each point
        //it is about 3 times faster than call rotate once per point, but here only 8 point, so it short from 6msec to 2 msec only
        //axis={x:  ,y:  ,z}
        var vAxis = {x:axis.x, y:axis.y, z:axis.z};
        //rotate around X axis:
        var xRot = Math.atan2(vAxis.y, vAxis.z);
        var sinX = Math.sin(-xRot);
        var cosX = Math.cos(-xRot);
        var pt = {z:vAxis.z*cosX-vAxis.y*sinX, y:vAxis.z*sinX+vAxis.y*cosX};
        pt.x = vAxis.x;
        vAxis = pt;
        var yRot = Math.atan2(vAxis.z, vAxis.x);
        var sinY = Math.sin(-yRot);
        var cosY = Math.cos(-yRot);
        var sinA = Math.sin(pAngle);
        var cosA = Math.cos(pAngle);
        //---------------------------------
        for (var i = 0; i<points.length; i++) {
            var point = points[i];
            var pt = {x:point.z*cosX-point.y*sinX, y:point.z*sinX+point.y*cosX};
            point.z=pt.x, point.y=pt.y;
            var pt = {x:point.x*cosY-point.z*sinY, y:point.x*sinY+point.z*cosY};
            point.x=pt.x, point.z=pt.y;
            var pt = {x:point.z*cosA-point.y*sinA, y:point.z*sinA+point.y*cosA};
            point.z=pt.x, point.y=pt.y;
            var pt = {x:point.x*cosY-point.z*-sinY, y:point.x*-sinY+point.z*cosY};
            point.x=pt.x, point.z=pt.y;
            var pt = {x:point.z*cosX-point.y*-sinX, y:point.z*-sinX+point.y*cosX};
            point.z=pt.x, point.y=pt.y;
        }
    }
    //====================================================
    static function skew(parent, child, mcW, mcH, ptTL, ptBL, ptTR) {
        //child and parent registration point must at the top left
        //mcW, mcH => the dimension of the child, it is not necessarily to be the real width and height; 
        //TL: top_left, BL: bottom_left, TR: top_right
        var angleP2 = Math.atan2(ptTR.y-ptTL.y, ptTR.x-ptTL.x);
        var angleP1 = Math.atan2(ptBL.y-ptTL.y, ptBL.x-ptTL.x);
        var dAngle = (angleP1-angleP2)/2;
        var arm = 1/(Math.sqrt(2)*Math.cos(dAngle));
        parent._x = ptTL.x;
        parent._y = ptTL.y;
        parent._xscale = 100;
        parent._rotation = (180/Math.PI)*(angleP1-dAngle);
        child._rotation = -45;
        parent._yscale = 100*Math.tan(dAngle);
        child._xscale = distance(ptTR, ptTL)*100/arm/mcW;
        child._yscale = distance(ptBL, ptTL)*100/arm/mcH;
    }
}
Je ne suis pas assez calé en maths pour savoir ce que réalisent ces opérations, c'est pour cela que je me tourne vers vous.

Quelqu'un aurait-il une solution ?

Merci d'avance.

PS : Si vous avez besoin de plus de fichiers, demandez et je les met à dispo.