Jump to content

User:Cyp/Java

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Cyp (talk | contribs) at 15:45, 31 July 2003 (Slightly modern version, that actually works). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Polyhedra.java


import java.awt.*;
import java.applet.*;

public class Polyhedra extends Applet{
  double g=1.6180339887498948482045868343656381177203; //(1+Math.sqrt(5))/2;
  double d=0.6180339887498948482045868343656381177203; //1/g;
  double s=1.4142135623730950488016887242096980785696; //Math.sqrt(2);
  double q=2.6180339887498948482045868343656381177203; //(1+Math.sqrt(5))/2+1;
  double j=3.2360679774997896964091736687312762354406; //(1+Math.sqrt(5));
  double w=(Math.pow(Math.sqrt(297)+17, 1/3.)-Math.pow(Math.sqrt(297)-17, 1/3.)-1)/3;
  double tetrav[]={
-1,-s,0, -1,s,0, 1,0,-s, 1,0,s};
  int tetrat[]={
0,1,3, 3,1,2, 1,0,2, 3,2,0};
  double hexav[]={
-1,-1,-1, -1,-1,1, -1,1,-1, -1,1,1, 1,-1,-1, 1,-1,1, 1,1,-1, 1,1,1};
  int hexat[]={
0,2,3,1, 2,6,7,3, 0,4,6,2, 3,7,5,1, 0,1,5,4, 6,4,5,7};
  double octav[]={
-1,0,0, 1,0,0, 0,-1,0, 0,1,0, 0,0,-1, 0,0,1};
  int octat[]={
0,4,3, 3,4,1, 1,4,2, 2,4,0, 3,5,0, 0,5,2, 2,5,1, 1,5,3};
  double dodecav[]={
0,-d,-g, 0,-d,g, 0,d,-g, 0,d,g, -d,-g,0, -d,g,0, d,-g,0, d,g,0, -g,0,-d, g,0,-d, -g,0,d, g,0,d, -1,-1,-1, -1,-1,1, -1,1,-1, -1,1,1, 1,-1,-1, 1,-1,1, 1,1,-1, 1,1,1};
  int dodecat[]={
0,2,14,8,12, 0,16,9,18,2, 4,6,16,0,12, 2,18,7,5,14, 13,4,12,8,10, 6,17,11,9,16, 15,10,8,14,5, 18,9,11,19,7, 1,17,6,4,13, 5,7,19,3,15, 13,10,15,3,1, 19,11,17,1,3};
  double icosav[]={
0,-1,-g, 0,-1,g, 0,1,-g, 0,1,g, -1,-g,0, -1,g,0, 1,-g,0, 1,g,0, -g,0,-1, g,0,-1, -g,0,1, g,0,1};
  int icosat[]={
0,2,8, 2,0,9, 4,0,8, 4,6,0, 6,9,0, 5,8,2, 5,2,7, 7,2,9, 10,4,8, 10,8,5, 6,11,9, 9,11,7, 10,5,3, 10,1,4, 1,11,6, 3,7,11, 1,6,4, 3,5,7, 3,11,1, 1,10,3};
  double icosidodecav[]={
-j,0,0, j,0,0, 0,-j,0, 0,j,0, 0,0,-j, 0,0,j,
-1,-g,-q, -1,-g,q, -1,g,-q, -1,g,q, 1,-g,-q, 1,-g,q, 1,g,-q, 1,g,q,
-g,-q,-1, -g,q,-1, g,-q,-1, g,q,-1, -g,-q,1, -g,q,1, g,-q,1, g,q,1,
-q,-1,-g, q,-1,-g, -q,-1,g, q,-1,g, -q,1,-g, q,1,-g, -q,1,g, q,1,g
};
  int icosidodecat[]={
3,17,21,3, 3,27,23,1, 3,1,25,29, 3,21,29,13, 3,12,27,17, 3,10,16,23, 3,20,11,25, 3,9,13,5, 3,19,9,28, 3,26,8,15,
3,15,3,19, 3,7,5,11, 3,18,24,7, 3,2,14,18, 3,2,20,16, 3,4,6,10, 3,6,22,14, 3,8,4,12, 3,0,22,26, 3,0,28,24,
5,17,27,1,29,21, 5,1,23,16,20,25, 5,4,10,23,27,12, 5,5,13,29,25,11, 5,3,21,13,9,19, 5,8,12,17,3,15,
5,0,26,15,19,28, 5,24,28,9,5,7, 5,0,24,18,14,22, 5,2,18,7,11,20, 5,10,6,14,2,16, 5,8,26,22,6,4
};
  double cuboctav[]={
-1,-1,0, -1,1,0, 1,-1,0, 1,1,0,
0,-1,-1, 0,-1,1, 0,1,-1, 0,1,1,
-1,0,-1, 1,0,-1, -1,0,1, 1,0,1
};
  int cuboctat[]={
3,3,11,7, 3,9,3,6, 3,11,2,5, 3,4,2,9, 3,7,10,1, 3,1,8,6, 3,0,10,5, 3,4,8,0,
4,3,9,2,11, 4,11,5,10,7, 4,7,1,6,3, 4,10,0,8,1, 4,6,8,4,9, 4,4,0,5,2
};
  double truncicosav[]={
0,-1,-3*g, 0,-1,3*g, 0,1,-3*g, 0,1,3*g,
-3*g,0,-1, 3*g,0,-1, -3*g,0,1, 3*g,0,1,
-1,-3*g,0, -1,3*g,0, 1,-3*g,0, 1,3*g,0,

-2,-(g+q),-g, -2,-(g+q),g, -2,(g+q),-g, -2,(g+q),g, 2,-(g+q),-g, 2,-(g+q),g, 2,(g+q),-g, 2,(g+q),g,
-g,-2,-(g+q), g,-2,-(g+q), -g,-2,(g+q), g,-2,(g+q), -g,2,-(g+q), g,2,-(g+q), -g,2,(g+q), g,2,(g+q),
-(g+q),-g,-2, -(g+q),g,-2, (g+q),-g,-2, (g+q),g,-2, -(g+q),-g,2, -(g+q),g,2, (g+q),-g,2, (g+q),g,2,

-1,-(2+g),-2*g, -1,-(2+g),2*g, -1,(2+g),-2*g, -1,(2+g),2*g, 1,-(2+g),-2*g, 1,-(2+g),2*g, 1,(2+g),-2*g, 1,(2+g),2*g,
-2*g,-1,-(2+g), 2*g,-1,-(2+g), -2*g,-1,(2+g), 2*g,-1,(2+g), -2*g,1,-(2+g), 2*g,1,-(2+g), -2*g,1,(2+g), 2*g,1,(2+g),
-(2+g),-2*g,-1, -(2+g),2*g,-1, (2+g),-2*g,-1, (2+g),2*g,-1, -(2+g),-2*g,1, -(2+g),2*g,1, (2+g),-2*g,1, (2+g),2*g,1
};
  int truncicosat[]={
6,9,11,19,43,39,15, 6,55,31,5,7,35,59, 6,27,43,19,59,35,51, 6,11,9,14,38,42,18, 6,20,44,28,52,12,36,
6,0,2,24,48,44,20, 6,48,24,38,14,53,29, 6,0,21,45,49,25,2, 6,12,8,10,16,40,36, 6,18,42,25,49,31,55,
6,23,47,34,58,17,41, 6,1,3,27,51,47,23, 6,21,40,16,54,30,45, 6,7,5,30,54,58,34, 6,39,26,50,33,57,15,
6,3,1,22,46,50,26, 6,57,33,6,4,29,53, 6,6,32,56,52,28,4, 6,22,37,13,56,32,46, 6,37,41,17,10,8,13,
5,59,19,11,18,55, 5,35,7,34,47,51, 5,3,26,39,43,27, 5,44,48,29,4,28, 5,20,36,40,21,0, 5,38,24,2,25,42,
5,14,9,15,57,53, 5,10,17,58,54,16, 5,22,1,23,41,37, 5,49,45,30,5,31, 5,50,46,32,6,33, 5,13,8,12,52,56
};
  double trunctetrav[]={
3,1,1, 1,3,1, 1,1,3,  3,-1,-1, -1,3,-1, -1,-1,3,  -3,-1,1, 1,-3,-1, -1,1,-3,  -3,1,-1, -1,-3,1, 1,-1,-3
};
  int trunctetrat[]={
6,11,3,0,1,4,8, 6,3,7,10,5,2,0, 6,6,10,7,11,8,9, 6,9,4,1,2,5,6,
3,0,2,1, 3,8,4,9, 3,6,5,10, 3,7,3,11
};
  double trunchexav[]={
-(s-1),-1,-1, -(s-1),-1,1, -(s-1),1,-1, -(s-1),1,1, (s-1),-1,-1, (s-1),-1,1, (s-1),1,-1, (s-1),1,1,
-1,-(s-1),-1, 1,-(s-1),-1, -1,-(s-1),1, 1,-(s-1),1, -1,(s-1),-1, 1,(s-1),-1, -1,(s-1),1, 1,(s-1),1,
-1,-1,-(s-1), -1,1,-(s-1), 1,-1,-(s-1), 1,1,-(s-1), -1,-1,(s-1), -1,1,(s-1), 1,-1,(s-1), 1,1,(s-1)
};
  int trunchexat[]={
8,5,22,18,4,0,16,20,1, 8,21,14,10,20,16,8,12,17, 8,14,3,7,15,11,5,1,10, 8,6,19,23,7,3,21,17,2, 8,0,4,9,13,6,2,12,8, 8,13,9,18,22,11,15,23,19,
3,11,22,5, 3,18,9,4, 3,3,14,21, 3,2,17,12, 3,10,1,20, 3,7,23,15, 3,13,19,6, 3,0,8,16
};
  double truncoctav[]={
-2,-1,0, -2,1,0, 2,-1,0, 2,1,0,
0,-2,-1, 0,-2,1, 0,2,-1, 0,2,1,
-1,0,-2, 1,0,-2, -1,0,2, 1,0,2,
-1,-2,0, -1,2,0, 1,-2,0, 1,2,0,
0,-1,-2, 0,-1,2, 0,1,-2, 0,1,2,
-2,0,-1, 2,0,-1, -2,0,1, 2,0,1
};
  int truncoctat[]={
6,17,11,23,2,14,5, 6,14,2,21,9,16,4, 6,7,15,3,23,11,19, 6,0,12,4,16,8,20, 6,19,10,22,1,13,7, 6,17,5,12,0,22,10, 6,1,20,8,18,6,13, 6,6,18,9,21,3,15,
4,12,5,14,4, 4,2,23,3,21, 4,13,6,15,7, 4,8,16,9,18, 4,0,20,1,22, 4,11,17,10,19
};
  double truncdodecav[]={
(0),-(3-g),-(5*g), (0),-(3-g),(5*g), (0),(3-g),-(5*g), (0),(3-g),(5*g),
-(5*g),(0),-(3-g), (5*g),(0),-(3-g), -(5*g),(0),(3-g), (5*g),(0),(3-g),
-(3-g),-(5*g),(0), -(3-g),(5*g),(0), (3-g),-(5*g),(0), (3-g),(5*g),(0),

-(3-g),-(2+g),-(4+2*g), -(3-g),-(2+g),(4+2*g), -(3-g),(2+g),-(4+2*g), -(3-g),(2+g),(4+2*g), (3-g),-(2+g),-(4+2*g), (3-g),-(2+g),(4+2*g), (3-g),(2+g),-(4+2*g), (3-g),(2+g),(4+2*g),
-(4+2*g),-(3-g),-(2+g), (4+2*g),-(3-g),-(2+g), -(4+2*g),-(3-g),(2+g), (4+2*g),-(3-g),(2+g), -(4+2*g),(3-g),-(2+g), (4+2*g),(3-g),-(2+g), -(4+2*g),(3-g),(2+g), (4+2*g),(3-g),(2+g),
-(2+g),-(4+2*g),-(3-g), -(2+g),(4+2*g),-(3-g), (2+g),-(4+2*g),-(3-g), (2+g),(4+2*g),-(3-g), -(2+g),-(4+2*g),(3-g), -(2+g),(4+2*g),(3-g), (2+g),-(4+2*g),(3-g), (2+g),(4+2*g),(3-g),

-(2+g),-(-2+4*g),-(1+3*g), -(2+g),-(-2+4*g),(1+3*g), -(2+g),(-2+4*g),-(1+3*g), -(2+g),(-2+4*g),(1+3*g), (2+g),-(-2+4*g),-(1+3*g), (2+g),-(-2+4*g),(1+3*g), (2+g),(-2+4*g),-(1+3*g), (2+g),(-2+4*g),(1+3*g),
-(1+3*g),-(2+g),-(-2+4*g), (1+3*g),-(2+g),-(-2+4*g), -(1+3*g),-(2+g),(-2+4*g), (1+3*g),-(2+g),(-2+4*g), -(1+3*g),(2+g),-(-2+4*g), (1+3*g),(2+g),-(-2+4*g), -(1+3*g),(2+g),(-2+4*g), (1+3*g),(2+g),(-2+4*g),
-(-2+4*g),-(1+3*g),-(2+g), -(-2+4*g),(1+3*g),-(2+g), (-2+4*g),-(1+3*g),-(2+g), (-2+4*g),(1+3*g),-(2+g), -(-2+4*g),-(1+3*g),(2+g), -(-2+4*g),(1+3*g),(2+g), (-2+4*g),-(1+3*g),(2+g), (-2+4*g),(1+3*g),(2+g)
};
  int truncdodecat[]={
10,24,48,53,29,33,57,50,26,6,4, 10,53,38,14,18,42,55,31,11,9,29, 10,39,57,33,9,11,35,59,43,19,15, 10,40,45,21,25,49,42,18,2,0,16,
10,28,52,44,20,4,6,22,46,56,32, 10,5,7,27,51,59,35,31,55,49,25, 10,8,32,56,37,13,17,41,58,34,10, 10,17,1,3,19,43,51,27,23,47,41,
10,47,23,7,5,21,45,54,30,34,58, 10,37,46,22,26,50,39,15,3,1,13, 10,24,20,44,36,12,0,2,14,38,48, 10,36,52,28,8,10,30,54,40,16,12,
3,33,29,9, 3,50,57,39, 3,53,48,38, 3,11,31,35, 3,25,21,5, 3,42,49,55, 3,7,23,27, 3,40,54,45, 3,52,36,44, 3,8,28,32,
3,22,6,26, 3,20,24,4, 3,51,43,59, 3,56,46,37, 3,13,1,17, 3,41,47,58, 3,3,15,19, 3,14,2,18, 3,12,16,0, 3,10,34,30
};
  double rhombicuboctav[]={
-(1+s),-1,-1, -(1+s),-1,1, -(1+s),1,-1, -(1+s),1,1, (1+s),-1,-1, (1+s),-1,1, (1+s),1,-1, (1+s),1,1,
-1,-(1+s),-1, 1,-(1+s),-1, -1,-(1+s),1, 1,-(1+s),1, -1,(1+s),-1, 1,(1+s),-1, -1,(1+s),1, 1,(1+s),1,
-1,-1,-(1+s), -1,1,-(1+s), 1,-1,-(1+s), 1,1,-(1+s), -1,-1,(1+s), -1,1,(1+s), 1,-1,(1+s), 1,1,(1+s)
};
  int rhombicuboctat[]={
4,5,7,6,4, 4,5,22,23,7, 4,6,7,15,13, 4,4,6,19,18, 4,9,11,5,4, 4,21,20,1,3, 4,3,1,0,2, 4,2,12,14,3, 4,17,2,0,16,
4,0,1,10,8, 4,10,11,9,8, 4,8,9,18,16, 4,16,18,19,17, 4,11,10,20,22, 4,22,20,21,23, 4,23,21,14,15, 4,12,17,19,13, 4,13,15,14,12,
3,11,22,5, 3,7,23,15, 3,6,13,19, 3,9,4,18, 3,14,21,3, 3,16,0,8, 3,17,12,2, 3,1,20,10
};
  double snubhexa1v[]={
-1,-w,1/w, -1,w,-1/w, 1,-w,-1/w, 1,w,1/w,
1/w,-1,-w, -1/w,-1,w, -1/w,1,-w, 1/w,1,w,
-w,1/w,-1, w,-1/w,-1, -w,-1/w,1, w,1/w,1,

-1,-1/w,-w, -1,1/w,w, 1,-1/w,w, 1,1/w,-w,
-w,-1,-1/w, w,-1,1/w, w,1,-1/w, -w,1,1/w,
-1/w,-w,-1, 1/w,w,-1, -1/w,w,1, 1/w,-w,1
};
  int snubhexa1t[]={
4,9,12,10,14, 4,16,2,18,1, 4,3,17,0,19, 4,15,11,13,8, 4,22,5,20,6, 4,23,7,21,4,
3,12,5,10, 3,12,20,5, 3,5,0,10, 3,10,0,17, 3,22,0,5, 3,11,15,7, 3,19,11,3, 3,11,7,3,
3,9,14,4, 3,14,23,4, 3,10,17,14, 3,14,17,23, 3,15,21,7, 3,7,23,3, 3,20,12,16, 3,1,18,8,
3,23,17,3, 3,6,20,1, 3,12,9,16, 3,20,16,1, 3,9,2,16, 3,9,4,2, 3,4,21,2, 3,18,21,15,
3,18,15,8, 3,8,6,1, 3,6,8,13, 3,22,6,13, 3,11,19,13, 3,13,19,22, 3,22,19,0, 3,21,18,2
};
  double snubhexa2v[]={
1,-w,1/w, 1,w,-1/w, -1,-w,-1/w, -1,w,1/w,
-1/w,-1,-w, 1/w,-1,w, 1/w,1,-w, -1/w,1,w,
w,1/w,-1, -w,-1/w,-1, w,-1/w,1, -w,1/w,1,

1,-1/w,-w, 1,1/w,w, -1,-1/w,w, -1,1/w,-w,
w,-1,-1/w, -w,-1,1/w, -w,1,-1/w, w,1,1/w,
1/w,-w,-1, -1/w,w,-1, 1/w,w,1, -1/w,-w,1
};
  int snubhexa2t[]={
4,9,14,10,12, 4,18,2,16,1, 4,3,19,0,17, 4,15,8,13,11, 4,22,6,20,5, 4,23,4,21,7,
3,12,10,5, 3,12,5,20, 3,5,10,0, 3,10,17,0, 3,22,5,0, 3,11,7,15, 3,19,3,11, 3,11,3,7,
3,9,4,14, 3,14,4,23, 3,10,14,17, 3,14,23,17, 3,15,7,21, 3,7,3,23, 3,20,16,12, 3,1,8,18,
3,23,3,17, 3,6,1,20, 3,12,16,9, 3,20,1,16, 3,9,16,2, 3,9,2,4, 3,4,2,21, 3,18,15,21,
3,18,8,15, 3,8,1,6, 3,6,13,8, 3,22,13,6, 3,11,13,19, 3,13,22,19, 3,22,0,19, 3,21,2,18
};

boolean DEBUG=/*/true;/*/false;/**/

  public void paint(Graphics g) {
    g.setColor(new Color(0xffffff));
    g.fillRect(0, 0, 200, 200);
    double n=Math.random();
 /*   if(n<.2) drawfig(g, tetrav, tetrat, 3);
    else if(n<.4) drawfig(g, hexav, hexat, 4);
    else if(n<.6) drawfig(g, octav, octat, 3);
    else if(n<.8) drawfig(g, dodecav, dodecat, 5);
    else drawfig(g, icosav, icosat, 3);
    */
    //drawfig(g, tetrav, tetrat, 3);
    //drawfig(g, hexav, hexat, 4);
    //drawfig(g, octav, octat, 3);
    //drawfig(g, dodecav, dodecat, 5);
    //drawfig(g, icosav, icosat, 3);
    //drawfig(g, icosidodecav, icosidodecat, -1);
    //drawfig(g, cuboctav, cuboctat, -1);
    //drawfig(g, truncicosav, truncicosat, -1);
    //drawfig(g, trunctetrav, trunctetrat, -1);
    //drawfig(g, trunchexav, trunchexat, -1);
    //drawfig(g, truncoctav, truncoctat, -1);
    //drawfig(g, truncdodecav, truncdodecat, -1);
    //drawfig(g, rhombicuboctav, rhombicuboctat, -1);
    //drawfig(g, snubhexa1v, snubhexa1t, -1);
    drawfig(g, snubhexa2v, snubhexa2t, -1);
  }
  void drawfig(Graphics g, double vs[], int ts[], int m) {
    int z=m, y=m; if(m==-1) m=1;
    double tr[]=randmat();
    for(int back=(DEBUG?1:-1);back<=1;back+=2) for(int t=0;t*m<ts.length;++t) {
      if(z==-1) { y=(int)ts[t]; ++t; }
      double f, td[];
      double a1=vs[ts[t*m  ]*3], a2=vs[ts[t*m  ]*3+1], a3=vs[ts[t*m  ]*3+2];
      f=1/Math.sqrt(a1*a1+a2*a2+a3*a3); a1*=f; a2*=f; a3*=f; td=trans(a1, a2, a3, tr); a1=td[0]; a2=td[1]; a3=td[2];
      double b1=vs[ts[t*m+1]*3], b2=vs[ts[t*m+1]*3+1], b3=vs[ts[t*m+1]*3+2];
      f=1/Math.sqrt(b1*b1+b2*b2+b3*b3); b1*=f; b2*=f; b3*=f; td=trans(b1, b2, b3, tr); b1=td[0]; b2=td[1]; b3=td[2];
      double c1=vs[ts[t*m+2]*3], c2=vs[ts[t*m+2]*3+1], c3=vs[ts[t*m+2]*3+2];
      f=1/Math.sqrt(c1*c1+c2*c2+c3*c3); c1*=f; c2*=f; c3*=f; td=trans(c1, c2, c3, tr); c1=td[0]; c2=td[1]; c3=td[2];
      double d1=b1-a1, d2=b2-a2, d3=b3-a3;
      double e1=c1-a1, e2=c2-a2, e3=c3-a3;
      double f1=e2*d3-d2*e3, f2=e3*d1-d3*e1, f3=e1*d2-d1*e2;
      double da1=a1/(4+a3), da2=a2/(4+a3),
             db1=b1/(4+b3)-da1, db2=b2/(4+b3)-da2,
             dc1=c1/(4+c3)-da1, dc2=c2/(4+c3)-da2;
      if(back*(db1*dc2-dc1*db2)/*f3*/>0) {
        g.setColor(new Color((float)Math.random(), (float)Math.random(), (float)Math.random(), (float)(/*.85+.15*/ .75+.25*Math.random())/*(float)(back<0?.90:0.90)*/));
        int xa[]=new int[y], ya[]=new int[y];
        xa[0]=(int)(a1*3/(4+a3)*100+100); xa[1]=(int)(b1*3/(4+b3)*100+100); xa[2]=(int)(c1*3/(4+c3)*100+100);
        ya[0]=(int)(a2*3/(4+a3)*100+100); ya[1]=(int)(b2*3/(4+b3)*100+100); ya[2]=(int)(c2*3/(4+c3)*100+100);
        for(int w=0/*3*/;w<y;++w) {
          a1=vs[ts[t*m+w]*3]; a2=vs[ts[t*m+w]*3+1]; a3=vs[ts[t*m+w]*3+2];
          f=1/Math.sqrt(a1*a1+a2*a2+a3*a3); a1*=f; a2*=f; a3*=f; td=trans(a1, a2, a3, tr); a1=td[0]; a2=td[1]; a3=td[2];
          xa[w]=(int)(a1*3/(4+a3)*100+100); ya[w]=(int)(a2*3/(4+a3)*100+100);
        }
        g.fillPolygon(xa, ya, y);
        
      }if(z==-1) t+=y-1;
    }if(!DEBUG)return;
    g.setColor(new Color(0, 0, 0)); //g.drawString("Hello", 10, 10);
    for(int num=0;num<vs.length/3;++num) {
      double a1=vs[num*3], a2=vs[num*3+1], a3=vs[num*3+2];
      double f, td[];
      f=1/Math.sqrt(a1*a1+a2*a2+a3*a3); a1*=f; a2*=f; a3*=f; td=trans(a1, a2, a3, tr); a1=td[0]; a2=td[1]; a3=td[2];
      //double da1=a1/(4+a3), da2=a2/(4+a3);
      if(a3<0){//1* db1*dc2-dc1*db2 /*f3*/<0) {
        /*a3=0;*/ g.drawString(""+num, (int)(a1*3/(4+a3)*100+100), (int)(a2*3/(4+a3)*100+100));
        g.fillRect((int)(a1*3/(4+a3)*100+100)-1, (int)(a2*3/(4+a3)*100+100)-1, 3, 3);
      }
    }
  }
  double[] randmat() {
    double[] r=new double[9];
    double s, x, y, z;
    int i, j;
    for(i=0;i<3;++i) {
      x=Math.random()*2-1;
      y=Math.random()*2-1;
      z=Math.random()*2-1;
      s=x*x+y*y+z*z;
      if(s>1) { --i; continue; }
      for(j=0;j<i;++j) {
        s=x*r[j*3  ]
         +y*r[j*3+1]
         +z*r[j*3+2];
        x-=s*r[j*3  ];
        y-=s*r[j*3+1];
        z-=s*r[j*3+2];
      }
      s=x*x+y*y+z*z;
      if(s==0) { --i; continue; }
      s=Math.sqrt(s);
      x/=s; y/=s; z/=s;
      r[i*3  ]=x;
      r[i*3+1]=y;
      r[i*3+2]=z;
    }
    if(r[0]*r[4]*r[8]+r[1]*r[5]*r[6]+r[2]*r[3]*r[7]-r[0]*r[5]*r[7]-r[1]*r[3]*r[8]-r[2]*r[4]*r[6]<0) {
      r[0]=-r[0];
      r[1]=-r[1];
      r[2]=-r[2];
    }
    return(r);
  }
  double[] trans(double x, double y, double z, double[] t) {
    return(new double[]{x*t[0]+y*t[1]+z*t[2],
                        x*t[3]+y*t[4]+z*t[5],
                        x*t[6]+y*t[7]+z*t[8]});
  }
}