Rotator3D.java
Upload User: cdlibang
Upload Date: 2016-07-17
Package Size: 774k
Code Size: 15k
Category:

2D Graphic

Development Platform:

Java

  1. /*
  2.  * @(#)Rotator3D.java 1.7 99/04/23
  3.  *
  4.  * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
  7.  * modify and redistribute this software in source and binary code form,
  8.  * provided that i) this copyright notice and license appear on all copies of
  9.  * the software; and ii) Licensee does not utilize the software in a manner
  10.  * which is disparaging to Sun.
  11.  * 
  12.  * This software is provided "AS IS," without a warranty of any kind. ALL
  13.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  14.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  15.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  16.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  17.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  18.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  19.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  20.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  21.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  22.  * POSSIBILITY OF SUCH DAMAGES.
  23.  * 
  24.  * This software is not designed or intended for use in on-line control of
  25.  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
  26.  * the design, construction, operation or maintenance of any nuclear
  27.  * facility. Licensee represents and warrants that it will not use or
  28.  * redistribute the Software for such purposes.
  29.  */
  30. /*
  31.  * @(#)Rotator3D.java 1.7 99/04/23
  32.  * 
  33.  * Copyright 1993-1998 Sun Microsystems, Inc. 901 San Antonio Road, 
  34.  * Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
  35.  * 
  36.  * This software is the confidential and proprietary information of Sun
  37.  * Microsystems, Inc. ("Confidential Information").  You shall not
  38.  * disclose such Confidential Information and shall use it only in
  39.  * accordance with the terms of the license agreement you entered into
  40.  * with Sun.
  41.  * 
  42.  * CopyrightVersion 1.2
  43.  * 
  44.  */
  45. package demos.Colors;
  46. import java.awt.*;
  47. import java.awt.event.*;
  48. import AnimatingContext;
  49. import DemoSurface;
  50. import DemoPanel;
  51. /**
  52.  * 3D objects with color & lighting translated, rotated and scaled.
  53.  */
  54. public class Rotator3D extends DemoSurface implements AnimatingContext {
  55.     private Objects3D objs[] = new Objects3D[3];
  56.     private static final int[][][] polygons = 
  57.              { 
  58.         // Solid cube   
  59.               {{5, 1, 15, 13, 21, 23, 15}, 
  60.                {5, 2, 21, 13, 19, 27, 21},
  61.                {5, 3, 23, 15, 17, 25, 23}, 
  62.                {5, 4, 19, 13, 15, 17, 19},
  63.                {5, 5, 27, 21, 23, 25, 27},
  64.                {5, 6, 27, 19, 17, 25, 27}},
  65.         // Polygonal faces cube
  66.               {{5, 1, 21, 13, 19, 27, 21},
  67.                {5, 5, 23, 15, 17, 25, 23}, 
  68.                {4,0,15,14,16,15}, {7,6,16,14,13,12,18,17,16}, {4,0,12,19,18,12},
  69.                {4,2,22,21,20,22}, {7,0,24,23,22,20,27,26,24}, {4,2,24,26,25,24},
  70.                {4, 3, 15, 13, 23, 15}, {4, 0, 23, 13, 21, 23}, 
  71.                {5, 0, 27, 26, 18, 19, 27}, {5, 4, 25, 17, 18, 26, 25}}, 
  72.         // Octahedron
  73.               {{4, 3, 18, 21, 16, 18}, {4, 1, 20, 16, 18, 20}, 
  74.                {4, 1, 18, 21, 16, 18}, {4, 3, 20, 17, 19, 20}, 
  75.                {4, 2, 20, 26, 27, 20}, {5, 3, 26, 18, 16, 27, 26}, 
  76.                {5, 0, 17, 24, 25, 19, 17}, {4, 3, 21, 25, 24, 21}, 
  77.                {4, 4, 18, 21, 22, 18}, {4, 2, 22, 21, 17, 22}, 
  78.                {4, 5, 20, 23, 16, 20}, {4, 1, 20, 23, 19, 20}, 
  79.                {4, 6, 21, 23, 16, 21}, {4, 4, 21, 23, 19, 21}, 
  80.                {4, 5, 20, 18, 22, 20}, {4, 6, 20, 22, 17, 20}}
  81.              };
  82.     private static final double[][][] points = 
  83.            { 
  84.         // Points for solid cube & polygonal faces cube
  85.             {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, 
  86.              {0, 0, -1}, {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, 
  87.              {0, 0, 1}, {0, 0, -1}, {1, 1, 0}, {1, 1, 1}, {0, 1, 1}, 
  88.              {-1, 1, 1}, {-1, 1, 0}, {-1, 1, -1}, {0, 1, -1}, {1, 1, -1}, 
  89.              {1, -1, 0}, {1, -1, 1}, {0, -1, 1}, {-1, -1, 1}, {-1, -1, 0}, 
  90.              {-1, -1, -1}, {0, -1, -1}, {1, -1, -1}},
  91.         // Points for octahedron
  92.             {{0, 0, 1}, {0, 0, -1}, {-0.8165, 0.4714, 0.33333},
  93.              {0.8165, -0.4714, -0.33333}, {0.8165, 0.4714, 0.33333},
  94.              {-0.8165, -0.4714, -0.33333}, {0, -0.9428, 0.3333},
  95.              {0, 0.9428, -0.33333}, {0, 0, 1}, {0, 0, -1},
  96.              {-0.8165, 0.4714, 0.33333}, {0.8165, -0.4714, -0.33333}, 
  97.              {0.8165, 0.4714, 0.33333}, {-0.8165, -0.4714, -0.33333},  
  98.              {0, -0.9428, 0.33333}, {0, 0.9428, -0.33333},  
  99.              {-1.2247, -0.7071, 1}, {1.2247, 0.7071, -1}, 
  100.              {0, 1.4142, 1}, {0, -1.4142, -1}, {-1.2247, 0.7071, -1}, 
  101.              {1.2247, -0.7071, 1}, {0.61237, 1.06066, 0}, 
  102.              {-0.61237, -1.06066, 0}, {1.2247, 0, 0}, 
  103.              {0.61237, -1.06066, 0}, {-0.61237, 1.06066, 0}, {-1.2247, 0, 0}}
  104.            }; 
  105.     private static final int[][][] faces = 
  106.            { 
  107.          // Solid cube
  108.              {{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 0}, {1, 5}},
  109.          // Polygonal faces cube
  110.              {{1, 0}, {1, 1}, {3, 2, 3, 4}, {3, 5, 6, 7}, {2,8,9}, {2,10,11}},
  111.          // Octahedron
  112.              {{1, 2}, {1, 3}, {2, 4, 5}, {2, 6, 7}, {2, 8, 9}, 
  113.               {2, 10, 11}, {2, 12, 13}, {2, 14, 15}},
  114.            };
  115.     public Rotator3D() {
  116.         setBackground(Color.white);
  117.     }
  118.     public void reset(int w, int h) {
  119.         objs[0] = new Objects3D(polygons[0], points[0], faces[0], w, h);
  120.         objs[1] = new Objects3D(polygons[1], points[0], faces[1], w, h);
  121.         objs[2] = new Objects3D(polygons[2], points[1], faces[2], w, h);
  122.     }
  123.     public void step(int w, int h) {
  124.         for (int i = objs.length; i-- > 0; ) {
  125.             if (objs[i] != null) {
  126.                 objs[i].step(w, h);
  127.             }
  128.         }
  129.     }
  130.     public void drawDemo(int w, int h, Graphics2D g2) {
  131.         for (int i = objs.length; i-- > 0; ) {
  132.             if (objs[i] != null) {
  133.                 objs[i].Draw(g2);
  134.             }
  135.         }
  136.     }
  137.     public static void main(String argv[]) {
  138.         final DemoPanel dp = new DemoPanel(new Rotator3D());
  139.         Frame f = new Frame("Java2D Demo - Rotator3D");
  140.         f.addWindowListener(new WindowAdapter() {
  141.             public void windowClosing(WindowEvent e) {System.exit(0);}
  142.             public void windowDeiconified(WindowEvent e) { 
  143.                 dp.surface.start(); 
  144.             }
  145.             public void windowIconified(WindowEvent e) { 
  146.                 dp.surface.stop(); 
  147.             }
  148.         });
  149.         f.add("Center", dp);
  150.         f.pack();
  151.         f.setSize(new Dimension(400,300));
  152.         f.show();
  153.         dp.surface.start();
  154.     }
  155. /**
  156.  * 3D Objects : Solid Cube, Cube & Octahedron with polygonal faces.
  157.  */
  158. public class Objects3D {
  159.     private final int UP = 0;
  160.     private final int DOWN = 1;
  161.     private int[][] polygons;
  162.     private int npoly;
  163.     private double[][] points;
  164.     private int npoint;
  165.     private int[][] faces;
  166.     private int nface;
  167.     private int ncolour = 10;
  168.     private Color[][] colours = new Color[ncolour][7];
  169.     private double[] lightvec = {0, 1, 1}; 
  170.     private double Zeye = 10;
  171.     private double angle;
  172.     private Matrix3D orient, tmp, tmp2, tmp3;
  173.     private int scaleDirection;
  174.     private double scale, scaleAmt;
  175.     private double ix = 3.0, iy = 3.0;
  176.     private double[][] rotPts;
  177.     private int[][] scrPts;
  178.     private int xx[] = new int[20];
  179.     private int yy[] = new int[20];
  180.     private double x, y;
  181.     private int p, j;
  182.     private int colour;
  183.     private double bounce, persp;
  184.  
  185.     public Objects3D(int[][] polygons, 
  186.                      double[][] points, 
  187.                      int[][] faces, 
  188.                      int w, 
  189.                      int h) {
  190.         this.polygons = polygons;
  191.         this.points = points;
  192.         this.faces = faces;
  193.         npoly = polygons.length;
  194.         npoint = points.length;
  195.         nface = faces.length;
  196.         x = w * Math.random();
  197.         y = h * Math.random();
  198.         ix = Math.random() > 0.5 ? ix : -ix;
  199.         iy = Math.random() > 0.5 ? iy : -iy;
  200.         rotPts = new double[npoint][3];
  201.         scrPts = new int[npoint][2];
  202.                     
  203.         for (int i = 0; i < ncolour; i++) {
  204.             // white
  205.             colours[i][0]= new Color(255 -(ncolour-1-i)*100/ncolour,
  206.                 255 -(ncolour-1-i)*100/ncolour,255 -(ncolour-1-i)*100/ncolour);
  207.             // red
  208.             colours[i][1]= new Color(255 -(ncolour-1-i)*100/ncolour,0,0);
  209.             // green
  210.             colours[i][2]= new Color(0,255 -(ncolour-1-i)*100/ncolour,0);
  211.             // blue
  212.             colours[i][3]= new Color(0,0,255 -(ncolour-1-i)*100/ncolour);
  213.             // yellow
  214.             colours[i][4]= new Color(255 -(ncolour-1-i)*100/ncolour,
  215.                 255 -(ncolour-1-i)*100/ncolour,0);
  216.             // cyan
  217.             colours[i][5]= new Color(0, 255 -(ncolour-1-i)*100/ncolour,
  218.                 255 -(ncolour-1-i)*100/ncolour);
  219.             // magenta
  220.             colours[i][6]= new Color(255 -(ncolour-1-i)*100/ncolour, 0,
  221.                 255 -(ncolour-1-i)*100/ncolour);
  222.         }
  223.         double len = Math.sqrt(lightvec[0]*lightvec[0] + 
  224.                                lightvec[1]*lightvec[1] + 
  225.                                lightvec[2]*lightvec[2]);
  226.         lightvec[0] = lightvec[0]/len;
  227.         lightvec[1] = lightvec[1]/len;
  228.         lightvec[2] = lightvec[2]/len;
  229.         double max = 0;
  230.         for (int i = 0; i < npoint; i++) {
  231.             len = Math.sqrt(points[i][0]*points[i][0] + 
  232.                     points[i][1]*points[i][1] + points[i][2]*points[i][2]);
  233.             if (len >max) {
  234.                 max = len;
  235.             }
  236.         }
  237.    
  238.         for (int i = 0; i < nface; i++) {
  239.             len = Math.sqrt(points[i][0]*points[i][0] + 
  240.                     points[i][1]*points[i][1] + points[i][2]*points[i][2]);
  241.             points[i][0] = points[i][0]/len;
  242.             points[i][1] = points[i][1]/len;
  243.             points[i][2] = points[i][2]/len;
  244.         }
  245.         orient = new Matrix3D();
  246.         tmp = new Matrix3D();
  247.         tmp2 = new Matrix3D();
  248.         tmp3 = new Matrix3D();
  249.         tmp.Rotation(2,0,Math.PI/50);
  250.         CalcScrPts((double) w/3,(double) h/3, 0);
  251.         scale = Math.min(w/3/max/1.2, h/3/max/1.2);
  252.         scaleAmt = scale;
  253.         scale *= Math.random() * 1.5;
  254.         scaleDirection = scaleAmt < scale ? DOWN : UP;
  255.     }
  256.  
  257.     private Color getColour(int f,int index) {
  258.         colour = (int)((rotPts[f][0]*lightvec[0]+ rotPts[f][1]*lightvec[1] 
  259.                     + rotPts[f][2]*lightvec[2])*ncolour); 
  260.         if (colour < 0) {
  261.             colour = 0;
  262.         }
  263.         if (colour > ncolour-1) {
  264.             colour = ncolour-1;
  265.         }
  266.         return colours[colour][polygons[faces[f][index]][1]];
  267.     }
  268.       
  269.     private void CalcScrPts(double x, double y, double z) {
  270.         for (p = 0; p < npoint; p++) {
  271.             rotPts[p][2] = points[p][0]*orient.M[2][0] + 
  272.                            points[p][1]*orient.M[2][1] +
  273.                            points[p][2]*orient.M[2][2];
  274.             rotPts[p][0] = points[p][0]*orient.M[0][0] + 
  275.                            points[p][1]*orient.M[0][1] +
  276.                            points[p][2]*orient.M[0][2];
  277.             rotPts[p][1] = -points[p][0]*orient.M[1][0] - 
  278.                            points[p][1]*orient.M[1][1] -
  279.                            points[p][2]*orient.M[1][2];
  280.         }
  281.         for (p = nface; p < npoint; p++) {
  282.             rotPts[p][2] += z;
  283.             persp = (Zeye - rotPts[p][2])/(scale*Zeye);
  284.             scrPts[p][0] = (int)(rotPts[p][0]/persp+x);
  285.             scrPts[p][1] = (int)(rotPts[p][1]/persp+y);
  286.         }
  287.     }
  288.     private boolean faceUp(int f) {
  289.         return (rotPts[f][0]*rotPts[nface+f][0] + 
  290.                 rotPts[f][1]*rotPts[nface+f][1] + 
  291.                 rotPts[f][2]*(rotPts[nface+f][2]-Zeye) < 0);
  292.     }
  293.     
  294.     public void step(int w, int h) {
  295.         x += ix;
  296.         y += iy;
  297.         if (x > w-scale) {
  298.             x = w-scale-1;
  299.             ix = -w/100 - 1;
  300.         }
  301.         if (x-scale < 0) {
  302.             x = 2+scale;
  303.             ix = w/100 + Math.random()*3;
  304.         }
  305.         if (y > h-scale) {
  306.             y = h-scale-2;
  307.             iy = -h/100 - 1;
  308.         }
  309.         if (y-scale < 0) {
  310.             y = 2+scale;
  311.             iy = h/100 + Math.random()*3;
  312.         }
  313.         angle += Math.random() * 0.15;
  314.         tmp3.Rotation(1, 2, angle);
  315.         tmp2.Rotation(1, 0, angle*Math.sqrt(2)/2);
  316.         tmp.Rotation(0, 2, angle*Math.PI/4);
  317.         orient.M = tmp3.Times(tmp2.Times(tmp.M));
  318.         bounce = Math.abs(Math.cos(0.5*(angle)))*2-1;
  319.         if (scale > scaleAmt*1.4) {
  320.             scaleDirection = DOWN;
  321.         }
  322.         if (scale < scaleAmt*0.4) {
  323.             scaleDirection = UP;
  324.         }
  325.         if (scaleDirection == UP) {
  326.             scale += Math.random();
  327.         }
  328.         if (scaleDirection == DOWN) {
  329.             scale -= Math.random();
  330.         }
  331.         CalcScrPts(x, y, bounce);
  332.     }
  333.     public void Draw(Graphics2D g2) {
  334.      
  335.         for (int f = 0;f < nface; f++) {
  336.             if (faceUp(f)) {
  337.                 for (j = 1;j < faces[f][0]+1; j++) {
  338.                     DrawPoly(g2, faces[f][j], getColour(f,j));
  339.                 }
  340.             }
  341.         } 
  342.     } 
  343.     private void DrawPoly(Graphics2D g2, int poly, Color colour) {
  344.         for (int p = 2; p < polygons[poly][0]+2; p++) {
  345.             xx[p-2] = scrPts[polygons[poly][p]][0];
  346.             yy[p-2] = scrPts[polygons[poly][p]][1];
  347.         }
  348.         g2.setColor(colour); 
  349.         g2.fillPolygon(xx,yy,polygons[poly][0]);
  350.         g2.setColor(Color.black); 
  351.         g2.drawPolygon(xx,yy,polygons[poly][0]);
  352.     }
  353. /** 
  354.  * A 3D matrix object.
  355.  */
  356. public class Matrix3D {
  357.     public double[][] M = { { 1, 0, 0 },
  358.                             { 0, 1, 0 },
  359.                             { 0, 0, 1 } };
  360.     private double[][] tmp = new double[3][3];
  361.     private int row, col, k;
  362.  
  363.     public void Rotation(int i, int j, double angle) {
  364.         for (row = 0; row < 3; row++) {
  365.             for (col = 0; col <3; col++) {
  366.                 if (row != col) { 
  367.                     M[row][col] = 0.0; 
  368.                 } else { 
  369.                     M[row][col] = 1.0; 
  370.                 }
  371.             }
  372.         }
  373.         M[i][i] = Math.cos(angle);
  374.         M[j][j] = Math.cos(angle);
  375.         M[i][j] = Math.sin(angle);
  376.         M[j][i] = -Math.sin(angle);
  377.     }
  378.     public double[][] Times(double[][] N) {
  379.         for (row = 0; row < 3; row++) {
  380.             for (col = 0; col < 3; col++) {
  381.                 tmp[row][col] = 0.0;
  382.                 for (k = 0; k < 3; k++) {
  383.                     tmp[row][col] += M[row][k] * N[k][col];
  384.                 }
  385.             }
  386.         }
  387.         return tmp;
  388.     }
  389. } // End Matrix3D
  390. } // End Objects3D
  391. } // End Rotator3D