home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / enzykbad / solid.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  12.0 KB  |  394 lines

  1. /*----------------------------------------------------------------------*/
  2. /* Solid -- represents a convex solid object with polygonal faces
  3.        - holds an orientation matrix(orient), screen coords (cenx,ceny),
  4.            width and height (W,H), polygons, points,  normal vectors
  5.            to faces, shading colours.
  6.        - methods:
  7.            getSolidData - reads in the solids information (in a very
  8.                specific way
  9.            setColours - sets up the shading colours
  10.            getColour - decides the shading of a particular face
  11.            CalcScrPts - calculates the screen points from the 3D points 
  12.            faceUp - decides whether to draw the face or not
  13.            Draw - draws the solid
  14.            DropFace - prints only the top face (flat with no tilt)
  15.            DrawPoly - draws a particular polygon of the solid
  16.            DropBlank - draws blank faces...this is equivalent to 
  17.                DropFace except no pattern is drawn 
  18.            ExplodePrep - prepares for Explode
  19.            Explode - a little demo of the before a DropFace the non-
  20.                essential face fly away
  21.            StampPrep - prepares for Stamp
  22.            Stamp - a little demo of the before a DropFace the solid 
  23.                rotates around 
  24.                                                                         */
  25. /*----------------------------------------------------------------------*/
  26. /*         Jim Morey -- morey@math.ubc.ca -- January 24, 1996           */
  27. /*----------------------------------------------------------------------*/
  28.  
  29. import java.io.*;
  30. import java.awt.*;
  31. import java.lang.*;
  32. import java.awt.Color;
  33. import java.net.*;
  34. import Omatrix;
  35.  
  36. public class Solid extends Object{
  37.   private final double FLOOR=-1.05;
  38.  
  39.   public Omatrix orient;
  40.   public int cenx,ceny,W,H;
  41.   public double Scale;
  42.   public int[][] polygons;
  43.  
  44.   private Omatrix demoMid,demoInitial;
  45.   private double demoAngle;
  46.   private int demoFace;
  47.   private double[][] points,explode;
  48.   private double[][] rotPts;
  49.   private int[][] scrPts;
  50.   private int[][] faces;
  51.   private Color colours[][];
  52.   private int npoint,npoly,nface,ncolour;
  53.   private int p,i,j,k,min,f,face,colour;
  54.   private double lightvec[],Zeye;
  55.   private int x[],y[];
  56.  
  57.   Solid(InputStream is, int wid, int heig, int ncolour_) 
  58.     throws IOException{
  59.     getSolidData(is);
  60.     rotPts = new double[npoint][3];
  61.     scrPts = new int[npoint][2];
  62.  
  63.     /* .. regular setup .. */
  64.  
  65.     double len = Math.sqrt(lightvec[0]*lightvec[0] + 
  66.       lightvec[1]*lightvec[1] + lightvec[2]*lightvec[2]);
  67.     lightvec[0] = lightvec[0]/len;
  68.     lightvec[1] = lightvec[1]/len;
  69.     lightvec[2] = lightvec[2]/len;
  70.     
  71.     x = new int[20];
  72.     y = new int[20];
  73.     W = wid / 2;
  74.     H = heig / 2;
  75.     ncolour = ncolour_;
  76.     colours = new Color[ncolour][2];
  77.     setColours();
  78.  
  79.     orient = new Omatrix();
  80.     demoInitial = new Omatrix();
  81.     demoMid = new Omatrix();
  82.  
  83.     double max=0;
  84.     for (i=0;i<npoint;i++){
  85.       len = Math.sqrt(points[i][0]*points[i][0] + 
  86.         points[i][1]*points[i][1] + points[i][2]*points[i][2]);
  87.       if (len >max) max = len;
  88.     }
  89.    
  90.     if (W>H) Scale= (double)H/max/1.2;
  91.     else Scale= (double)W/max/1.2;
  92.  
  93.     for (i=0;i<nface;i++){
  94.       len = Math.sqrt(points[i][0]*points[i][0] + 
  95.         points[i][1]*points[i][1] + points[i][2]*points[i][2]);
  96.       points[i][0] = points[i][0]/len;
  97.       points[i][1] = points[i][1]/len;
  98.       points[i][2] = points[i][2]/len;
  99.     }
  100.  
  101.     CalcScrPts((double)W,(double)H,0);
  102.   }
  103.  
  104.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  105.   void getSolidData(InputStream is) throws IOException{
  106.     String              str, name, thing;
  107.     int                 count;
  108.  
  109.     StreamTokenizer token = new StreamTokenizer(is);
  110.     token.eolIsSignificant(false);
  111.     token.commentChar('#');
  112.  
  113.     token.nextToken();
  114.     Zeye = token.nval;
  115.     /* .. get the points .. */
  116.     token.nextToken();
  117.     npoint = (int)token.nval;
  118.     points = new double[npoint][3];
  119.     for (i=0;i<npoint;i++){ 
  120.       for (j=0;j<3;j++){ 
  121.         token.nextToken();
  122.         points[i][j] = token.nval;
  123.       }
  124.     }
  125.  
  126.     /* .. get the polygons .. */
  127.     token.nextToken();
  128.     npoly = (int)token.nval;
  129.     polygons = new int[npoly][];
  130.     for (i=0;i<npoly;i++){ 
  131.       token.nextToken();
  132.       count = (int)token.nval;
  133.       polygons[i] = new int[count+2];
  134.       polygons[i][0] = count;
  135.       for (j=1;j<count+2;j++){ 
  136.         token.nextToken();
  137.         polygons[i][j] = (int)token.nval;
  138.       }
  139.     }
  140.  
  141.     /* .. get the faces .. */
  142.     token.nextToken();
  143.     nface = (int)token.nval;
  144.     faces = new int[nface][];
  145.     explode = new double[nface][5];
  146.     for (i=0;i<nface;i++){ 
  147.       token.nextToken();
  148.       count = (int)token.nval;
  149.       faces[i] = new int[count+1];
  150.       faces[i][0] = count;
  151.       for (j=1;j<count+1;j++){ 
  152.         token.nextToken();
  153.         faces[i][j] = (int)token.nval;
  154.       }
  155.     }
  156.  
  157.     lightvec = new double[3];
  158.     for (j=0;j<3;j++){ 
  159.       token.nextToken();
  160.       lightvec[j] = token.nval;
  161.     }
  162.   }
  163.  
  164.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  165.   public void setColours(){
  166.     for (i=0;i<ncolour;i++){
  167.       colours[i][0]= new Color(255 -(ncolour-1-i)*100/ncolour,
  168.         255 -(ncolour-1-i)*100/ncolour,255 -(ncolour-1-i)*100/ncolour);
  169.       colours[i][1]= new Color(255 -(ncolour-1-i)*100/ncolour,0,0);
  170.     }
  171.   }
  172.     
  173.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  174.   public Color getColour(int f,int index){
  175.     int colour = (int)((rotPts[f][0]*lightvec[0]+ 
  176.       rotPts[f][1]*lightvec[1] + 
  177.       rotPts[f][2]*lightvec[2])*ncolour); 
  178.  
  179.     if (colour<0) colour = 0;
  180.     if (colour>ncolour-1) colour = ncolour-1;
  181.  
  182.     return colours[colour][polygons[faces[f][index]][1]];
  183.   }
  184.       
  185.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  186.   public void CalcScrPts(double x,double y,double z){
  187.     double persp;
  188.  
  189.     for (p=0;p<npoint;p++){
  190.       rotPts[p][2] = points[p][0]*orient.M[2][0] + 
  191.                            points[p][1]*orient.M[2][1] +
  192.                            points[p][2]*orient.M[2][2];
  193.       rotPts[p][0] = points[p][0]*orient.M[0][0] + 
  194.                            points[p][1]*orient.M[0][1] +
  195.                            points[p][2]*orient.M[0][2];
  196.       rotPts[p][1] = -points[p][0]*orient.M[1][0] - 
  197.                            points[p][1]*orient.M[1][1] -
  198.                            points[p][2]*orient.M[1][2];
  199.     }
  200.     for (p=nface;p<npoint;p++){
  201.       rotPts[p][2] += z;
  202.       persp = (Zeye - rotPts[p][2])/(Scale*Zeye);
  203.       if (persp != 0);
  204.       scrPts[p][0] = (int)(rotPts[p][0]/persp+x);
  205.       scrPts[p][1] = (int)(rotPts[p][1]/persp+y);
  206.     }
  207.   }
  208.  
  209.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  210.   public boolean faceUp(int f){
  211.     return (rotPts[f][0]*rotPts[nface+f][0] + 
  212.             rotPts[f][1]*rotPts[nface+f][1] + 
  213.             rotPts[f][2]*(rotPts[nface+f][2]-Zeye) < 0);
  214.   }
  215.     
  216.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  217.   public void Draw(Graphics offscreen,int x0,int y0,double z){
  218.     CalcScrPts((double)x0,(double)y0,z);
  219.     /* .. for non-convex solids (not used).. 
  220.     i=0;
  221.     for (f=0;f<nface;f++)
  222.       if (faceUp(f)) {
  223.         topface[i] = f; 
  224.         i++;
  225.       }
  226.     for (j=0;j<i-1;j++){
  227.       min = j;
  228.       for (k=j+1;k<i;k++)
  229.         if (rotPts[topface[k]][2]<rotPts[topface[min]][2]) min =k;
  230.       if (min !=j) {
  231.         f = topface[j];
  232.         topface[j] = topface[min];
  233.         topface[min] = f;
  234.       }
  235.     }
  236.     */
  237.      
  238.     for (f=0;f<nface;f++){
  239.       if (faceUp(f)) 
  240.         for (j=1;j<faces[f][0]+1;j++)
  241.           DrawPoly(offscreen,faces[f][j],getColour(f,j));
  242.     } 
  243.   } 
  244.  
  245.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  246.   public void StampPrep(Omatrix tilt){
  247.     Omatrix tmp = new Omatrix();
  248.     demoInitial.Equal(orient);
  249.     CalcScrPts(0,0,0);
  250.     demoFace=0;
  251.     for (j=1;j<nface;j++){
  252.       if (rotPts[j][2]>rotPts[demoFace][2]) demoFace = j;
  253.     }
  254.   }
  255.  
  256.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  257.   public void Stamp(Graphics offscreen,int x0,int y0,double t){
  258.     Omatrix tmp = new Omatrix();
  259.     tmp.Rotation(0,2,Math.PI*t);
  260.     orient=tmp.Times(demoInitial);
  261.     Draw(offscreen,(int)(x0+30*Math.sin(Math.PI*t)), y0,
  262.       FLOOR*t+(1-t)*2*Math.sin(Math.PI*t));
  263.   }
  264.  
  265.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  266.   public void ExplodePrep(Omatrix tilt){
  267.     /* .. random parameters for faces .. */
  268.     for (j=0;j<nface;j++){
  269.       for (i=0;i<4;i++)
  270.         explode[j][i] = Math.random()*2 - 1;
  271.       explode[j][4] = Math.random();
  272.     }
  273.  
  274.     demoInitial.Equal(orient);
  275.     orient = tilt.Transpose().Times(orient);
  276.     CalcScrPts(0,0,0);
  277.     demoFace=0;
  278.     for (j=1;j<nface;j++) 
  279.       if (rotPts[j][2]>rotPts[demoFace][2]) demoFace = j; 
  280.  
  281.     demoAngle = demoMid.FindTran(demoInitial,orient);
  282.   }
  283.  
  284.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  285.   public void Explode(Graphics offscreen,int x0,int y0,double t){
  286.     /* .. there will be some problems with depth! .. */ 
  287.     Omatrix tmp = new Omatrix();
  288.     Omatrix tmp2 = new Omatrix();
  289.  
  290.     for (j=0;j<nface;j++){
  291.       if (j == demoFace){
  292.         tmp.Rotation(1,2,demoAngle*t);
  293.         orient=demoMid.Times(tmp.Times(demoMid.Transpose().Times(demoInitial)));
  294.         CalcScrPts((double)x0,(double)y0,
  295.           FLOOR*t+(1-t)*Math.sin(Math.PI*t));
  296.       } else {
  297.         tmp.Rotation(1,2,10*explode[j][0]*t);
  298.         tmp2.Rotation(0,2,10*explode[j][1]*t);
  299.         orient = tmp.Times(tmp2.Times(demoInitial));
  300.         CalcScrPts((double)x0+t*200*explode[j][2],
  301.           (double)y0+t*200*explode[j][3],
  302.           0+t*explode[j][4]);
  303.       }
  304.       for (i=1;i<faces[j][0]+1;i++)
  305.         DrawPoly(offscreen,faces[j][i],getColour(j,i));
  306.     }
  307.   }
  308.  
  309.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  310.   public void DropFace(Graphics offscreen,Omatrix tilt, int x0,int y0,boolean level){
  311.     orient = tilt.Transpose().Times(orient);
  312.     int max=0;
  313.     if (level){
  314.       CalcScrPts((double)x0,(double)y0,FLOOR-1);
  315.       for (j=1;j<nface;j++) if (rotPts[j][2]>rotPts[max][2]) max = j;
  316.     } else {
  317.       Omatrix tmp = new Omatrix();
  318.       tmp.Rotation(0,2,Math.PI);
  319.       orient = tmp.Times(orient);
  320.       CalcScrPts((double)x0,(double)y0,1+FLOOR);
  321.       for (j=1;j<nface;j++) if (rotPts[j][2]<rotPts[max][2]) max = j;
  322.       orient = tmp.Times(orient);
  323.     } 
  324.  
  325.     for (j=1;j<faces[max][0]+1;j++)
  326.       DrawPoly(offscreen,faces[max][j],colours[ncolour-1][polygons[faces[max][j]][1]]);
  327.  
  328.     orient = tilt.Times(orient);
  329.   } 
  330.  
  331.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  332.   private void DrawPoly(Graphics offscreen,int poly,Color colour){
  333.     for (p=2;p<polygons[poly][0]+2;p++){
  334.       x[p-2] = scrPts[polygons[poly][p]][0];
  335.       y[p-2] = scrPts[polygons[poly][p]][1];
  336.     }
  337.     offscreen.setColor(colour); 
  338.     offscreen.fillPolygon(x,y,polygons[poly][0]);
  339.     offscreen.setColor(Color.black); 
  340.     offscreen.drawPolygon(x,y,polygons[poly][0]);
  341.   }
  342.  
  343.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  344.   public void DropBlank(Graphics offscreen,int poly,Omatrix tilt,int x0,int y0,boolean level){
  345.     orient = tilt.Transpose().Times(orient);
  346.     if (level){
  347.       CalcScrPts((double)x0,(double)y0,FLOOR-1);
  348.     } else {
  349.       Omatrix tmp = new Omatrix();
  350.       tmp.Rotation(0,2,Math.PI);
  351.       orient = tmp.Times(orient);
  352.       CalcScrPts((double)x0,(double)y0,(1+FLOOR));
  353.       orient = tmp.Times(orient);
  354.     } 
  355.  
  356.     DrawPoly(offscreen,poly,Color.lightGray);
  357.  
  358.     orient = tilt.Times(orient);
  359.   } 
  360.  
  361.   /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  362.   public String toString() {
  363.     String              str;
  364.  
  365.     str ="Zeye "+Zeye+"\npoints "+npoint+"\n ";
  366.     for (i=0;i<npoint;i++){ 
  367.       str = str.concat("   "+i+
  368.         " ("+points[i][0]+" "+points[i][1]+" "+points[i][2]+")\n");
  369.     }
  370.  
  371.     str = str.concat("polys "+npoly+" \n");
  372.     for (i=0;i<npoly;i++){ 
  373.       str = str.concat("   "+i+">>(");
  374.       for (j=1;j<polygons[i][0]+2;j++){ 
  375.         str = str.concat(" "+polygons[i][j]);
  376.       }
  377.       str = str.concat(")\n");
  378.     }
  379.  
  380.     str = str.concat("faces "+nface+" \n");
  381.     for (i=0;i<nface;i++){ 
  382.       str = str.concat("   "+i+">>(");
  383.       for (j=1;j<faces[i][0]+1;j++){ 
  384.         str = str.concat(" "+faces[i][j]);
  385.       }
  386.       str = str.concat(")\n");
  387.     }
  388.  
  389.     str = str.concat("light ("+lightvec[0]+" "+lightvec[1]+" "+lightvec[2]+")");
  390.   
  391.     return str;
  392.   }
  393.