source: Dev/branches/rest-dojo-ui/client/dojox/gfx3d/matrix.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 15.3 KB
Line 
1define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
2       
3        // candidates for dojox.math:
4        gfx3d.matrix = {
5                _degToRad : function(degree){ return Math.PI * degree / 180; },
6                _radToDeg : function(radian){ return radian / Math.PI * 180; }
7        };
8       
9        gfx3d.matrix.Matrix3D = function(arg){
10                // summary: a 3D matrix object
11                // description: Normalizes a 3D matrix-like object. If arrays is passed,
12                //              all objects of the array are normalized and multiplied sequentially.
13                // arg: Object
14                //              a 3D matrix-like object, a number, or an array of such objects
15                if(arg){
16                        if(typeof arg == "number"){
17                                this.xx = this.yy = this.zz = arg;
18                        }else if(arg instanceof Array){
19                                if(arg.length > 0){
20                                        var m = gfx3d.matrix.normalize(arg[0]);
21                                        // combine matrices
22                                        for(var i = 1; i < arg.length; ++i){
23                                                var l = m;
24                                                var r = gfx3d.matrix.normalize(arg[i]);
25                                                m = new gfx3d.matrix.Matrix3D();
26                                                m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
27                                                m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
28                                                m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
29                                                m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
30                                                m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
31                                                m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
32                                                m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
33                                                m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
34                                                m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
35                                                m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
36                                                m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
37                                                m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
38                                        }
39                                        lang.mixin(this, m);
40                                }
41                        }else{
42                                lang.mixin(this, arg);
43                        }
44                }
45        };
46       
47        // the default (identity) matrix, which is used to fill in missing values
48        lang.extend(gfx3d.matrix.Matrix3D, {xx: 1, xy: 0, xz: 0, yx: 0, yy: 1, yz: 0, zx: 0, zy: 0, zz: 1, dx: 0, dy: 0, dz: 0});
49       
50        lang.mixin(gfx3d.matrix, {
51                // summary: class constants, and methods of dojox.gfx3d.matrix
52               
53                // matrix constants
54               
55                // identity: dojox.gfx3d.matrix.Matrix3D
56                //              an identity matrix constant: identity * (x, y, z) == (x, y, z)
57                identity: new gfx3d.matrix.Matrix3D(),
58               
59                // matrix creators
60               
61                translate: function(a, b, c){
62                        // summary: forms a translation matrix
63                        // description: The resulting matrix is used to translate (move) points by specified offsets.
64                        // a: Number: an x coordinate value
65                        // b: Number: a y coordinate value
66                        // c: Number: a z coordinate value
67                        if(arguments.length > 1){
68                                return new gfx3d.matrix.Matrix3D({dx: a, dy: b, dz: c}); // dojox.gfx3d.matrix.Matrix3D
69                        }
70                        // branch
71                        // a: Object: a point-like object, which specifies offsets for 3 dimensions
72                        // b: null
73                        return new gfx3d.matrix.Matrix3D({dx: a.x, dy: a.y, dz: a.z}); // dojox.gfx3d.matrix.Matrix3D
74                },
75                scale: function(a, b, c){
76                        // summary: forms a scaling matrix
77                        // description: The resulting matrix is used to scale (magnify) points by specified offsets.
78                        // a: Number: a scaling factor used for the x coordinate
79                        // b: Number: a scaling factor used for the y coordinate
80                        // c: Number: a scaling factor used for the z coordinate
81                        if(arguments.length > 1){
82                                return new gfx3d.matrix.Matrix3D({xx: a, yy: b, zz: c}); // dojox.gfx3d.matrix.Matrix3D
83                        }
84                        if(typeof a == "number"){
85                                // branch
86                                // a: Number: a uniform scaling factor used for the all coordinates
87                                // b: null
88                                return new gfx3d.matrix.Matrix3D({xx: a, yy: a, zz: a}); // dojox.gfx3d.matrix.Matrix3D
89                        }
90                        // branch
91                        // a: Object: a point-like object, which specifies scale factors for 3 dimensions
92                        // b: null
93                        return new gfx3d.matrix.Matrix3D({xx: a.x, yy: a.y, zz: a.z}); // dojox.gfx3d.matrix.Matrix3D
94                },
95                rotateX: function(angle){
96                        // summary: forms a rotating matrix (about the x axis)
97                        // description: The resulting matrix is used to rotate points
98                        //              around the origin of coordinates (0, 0) by specified angle.
99                        // angle: Number: an angle of rotation in radians (>0 for CW)
100                        var c = Math.cos(angle);
101                        var s = Math.sin(angle);
102                        return new gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
103                },
104                rotateXg: function(degree){
105                        // summary: forms a rotating matrix (about the x axis)
106                        // description: The resulting matrix is used to rotate points
107                        //              around the origin of coordinates (0, 0) by specified degree.
108                        //              See dojox.gfx3d.matrix.rotateX() for comparison.
109                        // degree: Number: an angle of rotation in degrees (>0 for CW)
110                        return gfx3d.matrix.rotateX(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
111                },
112                rotateY: function(angle){
113                        // summary: forms a rotating matrix (about the y axis)
114                        // description: The resulting matrix is used to rotate points
115                        //              around the origin of coordinates (0, 0) by specified angle.
116                        // angle: Number: an angle of rotation in radians (>0 for CW)
117                        var c = Math.cos(angle);
118                        var s = Math.sin(angle);
119                        return new gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
120                },
121                rotateYg: function(degree){
122                        // summary: forms a rotating matrix (about the y axis)
123                        // description: The resulting matrix is used to rotate points
124                        //              around the origin of coordinates (0, 0) by specified degree.
125                        //              See dojox.gfx3d.matrix.rotateY() for comparison.
126                        // degree: Number: an angle of rotation in degrees (>0 for CW)
127                        return gfx3d.matrix.rotateY(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
128                },
129                rotateZ: function(angle){
130                        // summary: forms a rotating matrix (about the z axis)
131                        // description: The resulting matrix is used to rotate points
132                        //              around the origin of coordinates (0, 0) by specified angle.
133                        // angle: Number: an angle of rotation in radians (>0 for CW)
134                        var c = Math.cos(angle);
135                        var s = Math.sin(angle);
136                        return new gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
137                },
138                rotateZg: function(degree){
139                        // summary: forms a rotating matrix (about the z axis)
140                        // description: The resulting matrix is used to rotate points
141                        //              around the origin of coordinates (0, 0) by specified degree.
142                        //              See dojox.gfx3d.matrix.rotateZ() for comparison.
143                        // degree: Number: an angle of rotation in degrees (>0 for CW)
144                        return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
145                },
146       
147                // camera transformation
148                cameraTranslate: function(a, b, c){
149                        // summary: forms a translation matrix
150                        // description: The resulting matrix is used to translate (move) points by specified offsets.
151                        // a: Number: an x coordinate value
152                        // b: Number: a y coordinate value
153                        // c: Number: a z coordinate value
154                        if(arguments.length > 1){
155                                return new gfx3d.matrix.Matrix3D({dx: -a, dy: -b, dz: -c}); // dojox.gfx3d.matrix.Matrix3D
156                        }
157                        // branch
158                        // a: Object: a point-like object, which specifies offsets for 3 dimensions
159                        // b: null
160                        return new gfx3d.matrix.Matrix3D({dx: -a.x, dy: -a.y, dz: -a.z}); // dojox.gfx3d.matrix.Matrix3D
161                },
162                cameraRotateX: function(angle){
163                        // summary: forms a rotating matrix (about the x axis) in cameraTransform manner
164                        // description: The resulting matrix is used to rotate points
165                        //              around the origin of coordinates (0, 0) by specified angle.
166                        // angle: Number: an angle of rotation in radians (>0 for CW)
167                        var c = Math.cos(-angle);
168                        var s = Math.sin(-angle);
169                        return new gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
170                },
171                cameraRotateXg: function(degree){
172                        // summary: forms a rotating matrix (about the x axis)in cameraTransform manner
173                        // description: The resulting matrix is used to rotate points
174                        //              around the origin of coordinates (0, 0) by specified degree.
175                        //              See dojox.gfx3d.matrix.rotateX() for comparison.
176                        // degree: Number: an angle of rotation in degrees (>0 for CW)
177                        return gfx3d.matrix.rotateX(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
178                },
179                cameraRotateY: function(angle){
180                        // summary: forms a rotating matrix (about the y axis) in cameraTransform manner
181                        // description: The resulting matrix is used to rotate points
182                        //              around the origin of coordinates (0, 0) by specified angle.
183                        // angle: Number: an angle of rotation in radians (>0 for CW)
184                        var c = Math.cos(-angle);
185                        var s = Math.sin(-angle);
186                        return new gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
187                },
188                cameraRotateYg: function(degree){
189                        // summary: forms a rotating matrix (about the y axis) in cameraTransform manner
190                        // description: The resulting matrix is used to rotate points
191                        //              around the origin of coordinates (0, 0) by specified degree.
192                        //              See dojox.gfx3d.matrix.rotateY() for comparison.
193                        // degree: Number: an angle of rotation in degrees (>0 for CW)
194                        return gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
195                },
196                cameraRotateZ: function(angle){
197                        // summary: forms a rotating matrix (about the z axis) in cameraTransform manner
198                        // description: The resulting matrix is used to rotate points
199                        //              around the origin of coordinates (0, 0) by specified angle.
200                        // angle: Number: an angle of rotation in radians (>0 for CW)
201                        var c = Math.cos(-angle);
202                        var s = Math.sin(-angle);
203                        return new gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
204                },
205                cameraRotateZg: function(degree){
206                        // summary: forms a rotating matrix (about the z axis) in cameraTransform manner
207                        // description: The resulting matrix is used to rotate points
208                        //              around the origin of coordinates (0, 0) by specified degree.
209                        //              See dojox.gfx3d.matrix.rotateZ() for comparison.
210                        // degree: Number: an angle of rotation in degrees (>0 for CW)
211                        return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
212                },
213       
214                // ensure matrix 3D conformance
215                normalize: function(matrix){
216                        // summary: converts an object to a matrix, if necessary
217                        // description: Converts any 3D matrix-like object or an array of
218                        //              such objects to a valid dojox.gfx3d.matrix.Matrix3D object.
219                        // matrix: Object: an object, which is converted to a matrix, if necessary
220                        return (matrix instanceof gfx3d.matrix.Matrix3D) ? matrix : new gfx3d.matrix.Matrix3D(matrix); // dojox.gfx3d.matrix.Matrix3D
221                },
222               
223                // common operations
224               
225                clone: function(matrix){
226                        // summary: creates a copy of a 3D matrix
227                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix-like object to be cloned
228                        var obj = new gfx3d.matrix.Matrix3D();
229                        for(var i in matrix){
230                                if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
231                        }
232                        return obj; // dojox.gfx3d.matrix.Matrix3D
233                },
234                invert: function(matrix){
235                        // summary: inverts a 2D matrix
236                        // matrix: dojox.gfx.matrix.Matrix3D: a 2D matrix-like object to be inverted
237                        var m = gfx3d.matrix.normalize(matrix);
238                        var D = m.xx * m.yy * m.zz + m.xy * m.yz * m.zx + m.xz * m.yx * m.zy - m.xx * m.yz * m.zy - m.xy * m.yx * m.zz - m.xz * m.yy * m.zx;
239                        var M = new gfx3d.matrix.Matrix3D({
240                                xx: (m.yy * m.zz - m.yz * m.zy) / D,
241                                xy: (m.xz * m.zy - m.xy * m.zz) / D,
242                                xz: (m.xy * m.yz - m.xz * m.yy) / D,
243                                yx: (m.yz * m.zx - m.yx * m.zz) / D,
244                                yy: (m.xx * m.zz - m.xz * m.zx) / D,
245                                yz: (m.xz * m.yx - m.xx * m.yz) / D,
246                                zx: (m.yx * m.zy - m.yy * m.zx) / D,
247                                zy: (m.xy * m.zx - m.xx * m.zy) / D,
248                                zz: (m.xx * m.yy - m.xy * m.yx) / D,
249                                dx: -1 * (m.xy * m.yz * m.dz + m.xz * m.dy * m.zy + m.dx * m.yy * m.zz - m.xy * m.dy * m.zz - m.xz * m.yy * m.dz - m.dx * m.yz * m.zy) / D,
250                                dy: (m.xx * m.yz * m.dz + m.xz * m.dy * m.zx + m.dx * m.yx * m.zz - m.xx * m.dy * m.zz - m.xz * m.yx * m.dz - m.dx * m.yz * m.zx) / D,
251                                dz: -1 * (m.xx * m.yy * m.dz + m.xy * m.dy * m.zx + m.dx * m.yx * m.zy - m.xx * m.dy * m.zy - m.xy * m.yx * m.dz - m.dx * m.yy * m.zx) / D
252                        });
253                        return M; // dojox.gfx3d.matrix.Matrix3D
254                },
255                _multiplyPoint: function(m, x, y, z){
256                        // summary: applies a matrix to a point
257                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
258                        // x: Number: an x coordinate of a point
259                        // y: Number: a y coordinate of a point
260                        // z: Number: a z coordinate of a point
261                        return {x: m.xx * x + m.xy * y + m.xz * z + m.dx, y: m.yx * x + m.yy * y + m.yz * z + m.dy, z: m.zx * x + m.zy * y + m.zz * z + m.dz}; // Object
262                },
263                multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
264                        // summary: applies a matrix to a point
265                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
266                        // a: Number: an x coordinate of a point
267                        // b: Number: a y coordinate of a point
268                        // c: Number: a z coordinate of a point
269                        var m = gfx3d.matrix.normalize(matrix);
270                        if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
271                                return gfx3d.matrix._multiplyPoint(m, a, b, c); // Object
272                        }
273                        // branch
274                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
275                        // a: Object: a point
276                        // b: null
277                        // c: null
278                        return gfx3d.matrix._multiplyPoint(m, a.x, a.y, a.z); // Object
279                },
280                multiply: function(matrix){
281                        // summary: combines matrices by multiplying them sequentially in the given order
282                        // matrix: dojox.gfx3d.matrix.Matrix3D...: a 3D matrix-like object,
283                        //              all subsequent arguments are matrix-like objects too
284                        var m = gfx3d.matrix.normalize(matrix);
285                        // combine matrices
286                        for(var i = 1; i < arguments.length; ++i){
287                                var l = m;
288                                var r = gfx3d.matrix.normalize(arguments[i]);
289                                m = new gfx3d.matrix.Matrix3D();
290                                m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
291                                m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
292                                m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
293                                m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
294                                m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
295                                m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
296                                m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
297                                m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
298                                m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
299                                m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
300                                m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
301                                m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
302                        }
303                        return m; // dojox.gfx3d.matrix.Matrix3D
304                },
305       
306                _project: function(m, x, y, z){
307                        // summary: applies a matrix to a point
308                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
309                        // x: Number: an x coordinate of a point
310                        // y: Number: a y coordinate of a point
311                        // z: Number: a z coordinate of a point
312                        return {        // Object
313                                x: m.xx * x + m.xy * y + m.xz * z + m.dx,
314                                y: m.yx * x + m.yy * y + m.yz * z + m.dy,
315                                z: m.zx * x + m.zy * y + m.zz * z + m.dz};
316                },
317                project: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
318                        // summary: applies a matrix to a point
319                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
320                        // a: Number: an x coordinate of a point
321                        // b: Number: a y coordinate of a point
322                        // c: Number: a z coordinate of a point
323                        var m = gfx3d.matrix.normalize(matrix);
324                        if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
325                                return gfx3d.matrix._project(m, a, b, c); // Object
326                        }
327                        // branch
328                        // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
329                        // a: Object: a point
330                        // b: null
331                        // c: null
332                        return gfx3d.matrix._project(m, a.x, a.y, a.z); // Object
333                }
334        });
335       
336        // propagate matrix up
337        gfx3d.Matrix3D = gfx3d.matrix.Matrix3D;
338       
339        return gfx3d.matrix;
340});
Note: See TracBrowser for help on using the repository browser.