KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java2d > demos > Colors > Rotator3D


1 /*
2  * @(#)Rotator3D.java 1.18 06/08/24
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 /*
38  * @(#)Rotator3D.java 1.18 06/08/24
39  */

40
41 package java2d.demos.Colors;
42
43 import java.awt.*;
44 import java2d.AnimatingSurface;
45
46 import static java.lang.Math JavaDoc.*;
47
48
49 /**
50  * 3D objects with color & lighting translated, rotated and scaled.
51  */

52 public class Rotator3D extends AnimatingSurface {
53
54     private Objects3D objs[] = new Objects3D[3];
55     private static final int[][][] polygons =
56              {
57         // Solid cube
58
{{5, 1, 15, 13, 21, 23, 15},
59                {5, 2, 21, 13, 19, 27, 21},
60                {5, 3, 23, 15, 17, 25, 23},
61                {5, 4, 19, 13, 15, 17, 19},
62                {5, 5, 27, 21, 23, 25, 27},
63                {5, 6, 27, 19, 17, 25, 27}},
64         // Polygonal faces cube
65
{{5, 1, 21, 13, 19, 27, 21},
66                {5, 5, 23, 15, 17, 25, 23},
67                {4,0,15,14,16,15}, {7,6,16,14,13,12,18,17,16}, {4,0,12,19,18,12},
68                {4,2,22,21,20,22}, {7,0,24,23,22,20,27,26,24}, {4,2,24,26,25,24},
69                {4, 3, 15, 13, 23, 15}, {4, 0, 23, 13, 21, 23},
70                {5, 0, 27, 26, 18, 19, 27}, {5, 4, 25, 17, 18, 26, 25}},
71         // Octahedron
72
{{4, 3, 18, 21, 16, 18}, {4, 1, 20, 16, 18, 20},
73                {4, 1, 18, 21, 16, 18}, {4, 3, 20, 17, 19, 20},
74                {4, 2, 20, 26, 27, 20}, {5, 3, 26, 18, 16, 27, 26},
75                {5, 0, 17, 24, 25, 19, 17}, {4, 3, 21, 25, 24, 21},
76                {4, 4, 18, 21, 22, 18}, {4, 2, 22, 21, 17, 22},
77                {4, 5, 20, 23, 16, 20}, {4, 1, 20, 23, 19, 20},
78                {4, 6, 21, 23, 16, 21}, {4, 4, 21, 23, 19, 21},
79                {4, 5, 20, 18, 22, 20}, {4, 6, 20, 22, 17, 20}}
80              };
81     private static final double[][][] points =
82            {
83         // Points for solid cube & polygonal faces cube
84
{{ 1, 0, 0}, {-1, 0, 0}, { 0, 1, 0}, { 0, -1, 0}, { 0, 0, 1},
85              { 0, 0, -1}, { 1, 0, 0}, {-1, 0, 0}, { 0, 1, 0}, { 0, -1, 0},
86              { 0, 0, 1}, { 0, 0, -1}, { 1, 1, 0}, { 1, 1, 1}, { 0, 1, 1},
87              {-1, 1, 1}, {-1, 1, 0}, {-1, 1, -1}, { 0, 1, -1}, { 1, 1, -1},
88              { 1, -1, 0}, { 1, -1, 1}, { 0, -1, 1}, {-1, -1, 1}, {-1, -1, 0},
89              {-1, -1, -1}, { 0, -1, -1}, { 1, -1, -1}},
90         // Points for octahedron
91
{{0, 0, 1}, {0, 0, -1}, {-0.8165, 0.4714, 0.33333},
92              {0.8165, -0.4714, -0.33333}, {0.8165, 0.4714, 0.33333},
93              {-0.8165, -0.4714, -0.33333}, {0, -0.9428, 0.3333},
94              {0, 0.9428, -0.33333}, {0, 0, 1}, {0, 0, -1},
95              {-0.8165, 0.4714, 0.33333}, {0.8165, -0.4714, -0.33333},
96              {0.8165, 0.4714, 0.33333}, {-0.8165, -0.4714, -0.33333},
97              {0, -0.9428, 0.33333}, {0, 0.9428, -0.33333},
98              {-1.2247, -0.7071, 1}, {1.2247, 0.7071, -1},
99              {0, 1.4142, 1}, {0, -1.4142, -1}, {-1.2247, 0.7071, -1},
100              {1.2247, -0.7071, 1}, {0.61237, 1.06066, 0},
101              {-0.61237, -1.06066, 0}, {1.2247, 0, 0},
102              {0.61237, -1.06066, 0}, {-0.61237, 1.06066, 0}, {-1.2247, 0, 0}}
103            };
104     private static final int[][][] faces =
105            {
106          // Solid cube
107
{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 0}, {1, 5}},
108          // Polygonal faces cube
109
{{1, 0}, {1, 1}, {3, 2, 3, 4}, {3, 5, 6, 7}, {2,8,9}, {2,10,11}},
110          // Octahedron
111
{{1, 2}, {1, 3}, {2, 4, 5}, {2, 6, 7}, {2, 8, 9},
112               {2, 10, 11}, {2, 12, 13}, {2, 14, 15}},
113            };
114
115
116     public Rotator3D() {
117         setBackground(Color.white);
118     }
119
120
121     public void reset(int w, int h) {
122         objs[0] = new Objects3D(polygons[0], points[0], faces[0], w, h);
123         objs[1] = new Objects3D(polygons[1], points[0], faces[1], w, h);
124         objs[2] = new Objects3D(polygons[2], points[1], faces[2], w, h);
125     }
126
127
128     public void step(int w, int h) {
129         for (Objects3D obj : objs) {
130             if (obj != null) {
131                 obj.step(w, h);
132             }
133         }
134     }
135
136
137     public void render(int w, int h, Graphics2D g2) {
138         for (Objects3D obj : objs) {
139             if (obj != null) {
140                 obj.render(g2);
141             }
142         }
143     }
144
145
146     public static void main(String JavaDoc argv[]) {
147         createDemoFrame(new Rotator3D());
148     }
149
150
151 /**
152  * 3D Objects : Solid Cube, Cube & Octahedron with polygonal faces.
153  */

154 public class Objects3D {
155
156     private final int UP = 0;
157     private final int DOWN = 1;
158     private int[][] polygons;
159     private int npoly;
160     private double[][] points;
161     private int npoint;
162     private int[][] faces;
163     private int nface;
164     private int ncolour = 10;
165     private Color[][] colours = new Color[ncolour][7];
166     private double[] lightvec = {0, 1, 1};
167     private double Zeye = 10;
168     private double angle;
169     private Matrix3D orient, tmp, tmp2, tmp3;
170     private int scaleDirection;
171     private double scale, scaleAmt;
172     private double ix = 3.0, iy = 3.0;
173     private double[][] rotPts;
174     private int[][] scrPts;
175     private int xx[] = new int[20];
176     private int yy[] = new int[20];
177     private double x, y;
178     private int p, j;
179     private int colour;
180     private double bounce, persp;
181
182  
183     public Objects3D(int[][] polygons,
184                      double[][] points,
185                      int[][] faces,
186                      int w,
187                      int h) {
188
189         this.polygons = polygons;
190         this.points = points;
191         this.faces = faces;
192         npoly = polygons.length;
193         npoint = points.length;
194         nface = faces.length;
195
196         x = w * random();
197         y = h * random();
198
199         ix = random() > 0.5 ? ix : -ix;
200         iy = random() > 0.5 ? iy : -iy;
201
202         rotPts = new double[npoint][3];
203         scrPts = new int[npoint][2];
204                     
205         for (int i = 0; i < ncolour; i++) {
206             int x = 255 - (ncolour - i - 1)*100/ncolour;
207             Color[] c = {
208                 new Color(x,x,x), // white
209
new Color(x,0,0), // red
210
new Color(0,x,0), // green
211
new Color(0,0,x), // blue
212
new Color(x,x,0), // yellow
213
new Color(0,x,x), // cyan
214
new Color(x,0,x) // magenta
215
};
216             colours[i] = c;
217         }
218
219         double len = sqrt(lightvec[0]*lightvec[0] +
220                           lightvec[1]*lightvec[1] +
221                           lightvec[2]*lightvec[2]);
222         lightvec[0] = lightvec[0]/len;
223         lightvec[1] = lightvec[1]/len;
224         lightvec[2] = lightvec[2]/len;
225
226         double max = 0;
227         for (int i = 0; i < npoint; i++) {
228             len = sqrt(points[i][0]*points[i][0] +
229                        points[i][1]*points[i][1] +
230                        points[i][2]*points[i][2]);
231             if (len >max) {
232                 max = len;
233             }
234         }
235    
236         for (int i = 0; i < nface; i++) {
237             len = sqrt(points[i][0]*points[i][0] +
238                        points[i][1]*points[i][1] +
239                        points[i][2]*points[i][2]);
240             points[i][0] = points[i][0]/len;
241             points[i][1] = points[i][1]/len;
242             points[i][2] = points[i][2]/len;
243         }
244
245         orient = new Matrix3D();
246         tmp = new Matrix3D();
247         tmp2 = new Matrix3D();
248         tmp3 = new Matrix3D();
249         tmp.Rotation(2,0,PI/50);
250         CalcScrPts((double) w/3,(double) h/3, 0);
251
252         scale = min(w/3/max/1.2, h/3/max/1.2);
253         scaleAmt = scale;
254         scale *= random() * 1.5;
255         scaleDirection = scaleAmt < scale ? DOWN : UP;
256     }
257
258  
259     private Color getColour(int f,int index) {
260         colour = (int)((rotPts[f][0]*lightvec[0] +
261                         rotPts[f][1]*lightvec[1] +
262                         rotPts[f][2]*lightvec[2]) * ncolour);
263         if (colour < 0) {
264             colour = 0;
265         }
266         if (colour > ncolour-1) {
267             colour = ncolour-1;
268         }
269         return colours[colour][polygons[faces[f][index]][1]];
270     }
271       
272
273     private void CalcScrPts(double x, double y, double z) {
274         for (p = 0; p < npoint; p++) {
275
276             rotPts[p][2] = points[p][0]*orient.M[2][0]
277                            + points[p][1]*orient.M[2][1]
278                            + points[p][2]*orient.M[2][2];
279
280             rotPts[p][0] = points[p][0]*orient.M[0][0]
281                            + points[p][1]*orient.M[0][1]
282                            + points[p][2]*orient.M[0][2];
283
284             rotPts[p][1] = - points[p][0]*orient.M[1][0]
285                            - points[p][1]*orient.M[1][1]
286                            - points[p][2]*orient.M[1][2];
287         }
288         for (p = nface; p < npoint; p++) {
289             rotPts[p][2] += z;
290             persp = (Zeye - rotPts[p][2])/(scale*Zeye);
291             scrPts[p][0] = (int)(rotPts[p][0]/persp+x);
292             scrPts[p][1] = (int)(rotPts[p][1]/persp+y);
293         }
294     }
295
296
297     private boolean faceUp(int f) {
298         return (rotPts[f][0] * rotPts[nface+f][0] +
299                 rotPts[f][1] * rotPts[nface+f][1] +
300                 rotPts[f][2] *(rotPts[nface+f][2]-Zeye) < 0);
301     }
302     
303
304     public void step(int w, int h) {
305         x += ix;
306         y += iy;
307         if (x > w-scale) {
308             x = w-scale-1;
309             ix = -w/100 - 1;
310         }
311         if (x-scale < 0) {
312             x = 2+scale;
313             ix = w/100 + random()*3;
314         }
315         if (y > h-scale) {
316             y = h-scale-2;
317             iy = -h/100 - 1;
318         }
319         if (y-scale < 0) {
320             y = 2+scale;
321             iy = h/100 + random()*3;
322         }
323
324         angle += random() * 0.15;
325         tmp3.Rotation(1, 2, angle);
326         tmp2.Rotation(1, 0, angle*sqrt(2)/2);
327         tmp.Rotation(0, 2, angle*PI/4);
328         orient.M = tmp3.Times(tmp2.Times(tmp.M));
329         bounce = abs(cos(0.5*(angle)))*2-1;
330
331         if (scale > scaleAmt*1.4) {
332             scaleDirection = DOWN;
333         }
334         if (scale < scaleAmt*0.4) {
335             scaleDirection = UP;
336         }
337         if (scaleDirection == UP) {
338             scale += random();
339         }
340         if (scaleDirection == DOWN) {
341             scale -= random();
342         }
343
344         CalcScrPts(x, y, bounce);
345     }
346
347
348     public void render(Graphics2D g2) {
349         for (int f = 0;f < nface; f++) {
350             if (faceUp(f)) {
351                 for (j = 1;j < faces[f][0]+1; j++) {
352                     DrawPoly(g2, faces[f][j], getColour(f,j));
353                 }
354             }
355         }
356     }
357
358
359     private void DrawPoly(Graphics2D g2, int poly, Color colour) {
360         for (int p = 2; p < polygons[poly][0]+2; p++) {
361             xx[p-2] = scrPts[polygons[poly][p]][0];
362             yy[p-2] = scrPts[polygons[poly][p]][1];
363         }
364         g2.setColor(colour);
365         g2.fillPolygon(xx,yy,polygons[poly][0]);
366         g2.setColor(Color.black);
367         g2.drawPolygon(xx,yy,polygons[poly][0]);
368     }
369
370
371 /**
372  * A 3D matrix object.
373  */

374 public class Matrix3D {
375
376     public double[][] M = { { 1, 0, 0 },
377                             { 0, 1, 0 },
378                             { 0, 0, 1 } };
379     private double[][] tmp = new double[3][3];
380     private int row, col, k;
381  
382     public void Rotation(int i, int j, double angle) {
383         for (row = 0; row < 3; row++) {
384             for (col = 0; col <3; col++) {
385                 if (row != col) {
386                     M[row][col] = 0.0;
387                 } else {
388                     M[row][col] = 1.0;
389                 }
390             }
391         }
392         M[i][i] = cos(angle);
393         M[j][j] = cos(angle);
394         M[i][j] = sin(angle);
395         M[j][i] = -sin(angle);
396     }
397
398     public double[][] Times(double[][] N) {
399         for (row = 0; row < 3; row++) {
400             for (col = 0; col < 3; col++) {
401                 tmp[row][col] = 0.0;
402                 for (k = 0; k < 3; k++) {
403                     tmp[row][col] += M[row][k] * N[k][col];
404                 }
405             }
406         }
407         return tmp;
408     }
409
410 } // End Matrix3D
411

412 } // End Objects3D
413

414 } // End Rotator3D
415
Popular Tags