public class Shape2 { int NVERTICES,NFACES,NSIDES; Matrix3D transfo = new Matrix3D(); double vertices[][]; material m=new material(); double tVertices[][];//transformed vertices static double epsilon; static double foc ; static int nlights; static light[] lights; int faces[][]; int px[]; int py[]; double pz[]; double rgb[][]; int ord[]; static double zBuffer[][]; static double FrameBuffer[][][]; static void setEps(double e){ epsilon=e; } static void setFoc(double f){ foc=f; } static void setLights(int nb, double dirs[][], double rgbs[][]){ lights=new light[nb]; nlights=nb; for (int i=0;i0) rgb[i][j]+=lights[k].rgb[j]*m.diffuse[j]*vald;// diffuse tmp[0]=tVertices[i][0]; tmp[1]=tVertices[i][1]; tmp[2]=tVertices[i][2]; double[] normPos=normalize(tmp); double vals=normPos[0]*(lights[k].dir[0]-2*vald*normNorm[0])+normPos[1]*(lights[k].dir[1]-2*vald*normNorm[1])+normPos[2]*(lights[k].dir[2]-2*vald*normNorm[2]); if (vals>0) rgb[i][j]+=lights[k].rgb[j]*m.specular[j]*pow(vals,m.p); } } } } } double pow(double f1, int f2){ double res=1; for (int i=0;i0) ind+=pow2[i]; } switch (ind){ case (0): res = new Shape2[1]; res[0]=this; return res; case(1): return get2tr(this,0,1,2); case(2): return get2tr(this,1,0,2); case(3): res = new Shape2[1]; res[0]=get1tr(this,1,0,2); return res; case(4): return get2tr(this,2,0,1); case(5): res = new Shape2[1]; res[0]=get1tr(this,0,2,1); return res; case(6): res = new Shape2[1]; res[0]=get1tr(this,1,2,0); return res; case(7): return null; } return null; } Shape2[] get2tr(Shape2 src, int gone, int s1, int s2){ double[] zs=new double[3]; for (int i=0; i<3; ++i) zs[i]=src.tVertices[i][2]+epsilon-foc; Shape2[] res=new Shape2[2]; res[0]=new Shape2(); res[0].copy(src); double tCross0 = getTcross(zs[gone],zs[s1]); double[] rgbz=interpolRgbz(getRgbz(s1),getRgbz(gone),tCross0); double[] xyz=interpolXyz(getTxyz(s1),getTxyz(gone),tCross0); res[0].setRgbz(rgbz,gone); res[0].setTxyz(xyz,gone); res[1]=new Shape2(); res[1].copy(src); tCross0 = getTcross(zs[gone],zs[s2]); rgbz=interpolRgbz(getRgbz(s2),getRgbz(gone),tCross0); xyz=interpolXyz(getTxyz(s2),getTxyz(gone),tCross0); res[1].setRgbz(rgbz,gone); res[1].setTxyz(xyz,gone); return res; } Shape2 get1tr(Shape2 src, int gone1, int gone2, int s2){ double[] zs=new double[3]; for (int i=0; i<3; ++i) zs[i]=src.tVertices[i][2]+epsilon-foc; Shape2 res=new Shape2(); res.copy(src); double tCross0 = getTcross(zs[gone1],zs[s2]); double[] rgbz=interpolRgbz(getRgbz(s2),getRgbz(gone1),tCross0); double[] xyz=interpolXyz(getTxyz(s2),getTxyz(gone1),tCross0); res.setRgbz(rgbz,gone1); res.setTxyz(xyz,gone1); tCross0 = getTcross(zs[gone2],zs[s2]); rgbz=interpolRgbz(getRgbz(s2),getRgbz(gone2),tCross0); xyz=interpolXyz(getTxyz(s2),getTxyz(gone2),tCross0); res.setRgbz(rgbz,gone2); res.setTxyz(xyz,gone2); return res; } double getTcross(double z1, double z2){ //assumes z1>-epsilon+foc>z2 return -z2/(z1-z2); } void persp(){ for (int j=0; jmax){ max=py[j]; ord[2]=j; } } for (int j=0;j<3;j++) if (j!=ord[0] & j!=ord[2]) ord[1]=j; if (py[ord[0]]==py[ord[1]]){ trapeze res = new trapeze(); res.trapeze(this,0); trapeze retres[]=new trapeze[1]; retres[0]=res; return retres; } if (py[ord[1]]==py[ord[2]]){ trapeze res = new trapeze(); res.trapeze(this,1); trapeze retres[]=new trapeze[1]; retres[0]=res; return retres; } trapeze retres[]=new trapeze[2]; double tY= (py[ord[1]]-py[ord[0]]+0.0)/(py[ord[2]]-py[ord[0]]); int tmpPx=(int)(px[ord[0]]+tY*(px[ord[2]]-px[ord[0]])); double tmpRgbz[]=interpolRgbz(getRgbz(ord[0]),getRgbz(ord[2]),tY); retres[0]=new trapeze(); Shape2 topTriangle=new Shape2(); topTriangle.triangle(this); int tmpVert=ord[0]; topTriangle.py[tmpVert]=py[ord[1]]; topTriangle.px[tmpVert]=tmpPx; topTriangle.pz[tmpVert]=tmpRgbz[3]; for (int i=0;i<3;i++) topTriangle.rgb[tmpVert][i]=tmpRgbz[i]; retres[0].trapeze(topTriangle,0); retres[1]=new trapeze(); Shape2 bottomTriangle=new Shape2(); bottomTriangle.triangle(this); tmpVert=ord[2]; bottomTriangle.py[tmpVert]=py[ord[1]]; bottomTriangle.px[tmpVert]=tmpPx; bottomTriangle.pz[tmpVert]=tmpRgbz[3]; for (int i=0;i<3;i++) bottomTriangle.rgb[tmpVert][i]=tmpRgbz[i]; retres[1].trapeze(bottomTriangle,1); return retres; } double[] interpolRgbz(double[] inp1, double[] inp2, double t){ double res[]=new double[4]; for (int i=0;i<4;i++) res[i]=inp1[i]+t*(inp2[i]-inp1[i]); return res; } double[] interpolXyz(double[] inp1, double[] inp2, double t){ double res[]=new double[3]; for (int i=0;i<3;i++) res[i]=inp1[i]+t*(inp2[i]-inp1[i]); return res; } void sphere(int M, int N){ transfo.identity(); double theta, phi; double xyz[]= new double[3]; int index, index1; NVERTICES = M*(N+1); NFACES = M*N; NSIDES = 4; vertices = new double[NVERTICES][6]; tVertices = new double[NVERTICES][6]; px=new int[NVERTICES]; py=new int[NVERTICES]; pz=new double[NVERTICES]; faces = new int[NFACES][NSIDES]; for (int n=0; n<=N ; n++) for (int m=0;m0){ index1=(n-1)*M+m; faces[index1][0]=(n-1)*M+m; faces[index1][1]=(n-1)*M+((m+1)%M); faces[index1][2]=n*M+((m+1)%M); faces[index1][3]=n*M+m; } } } void triangle(){ ord=new int[3]; NVERTICES=3; NFACES=1; NSIDES=3; transfo.identity(); vertices=new double[3][6]; tVertices=new double[3][6]; rgb=new double[NVERTICES][3]; px=new int[NVERTICES]; py=new int[NVERTICES]; pz=new double[NVERTICES]; faces= new int[1][3]; vertices[0][0]=0; vertices[0][1]=0; vertices[0][2]=-1; vertices[1][0]=1; vertices[1][1]=0; vertices[1][2]=-1; vertices[2][0]=0; vertices[2][1]=1; vertices[2][2]=-1; for (int i=0;i<3;++i){ vertices[i][3]=0; vertices[i][4]=0; vertices[i][5]=1; } } void triangle(Shape2 srcTriangle){ this.triangle(); NVERTICES=srcTriangle.NVERTICES; NFACES=srcTriangle.NFACES; NSIDES=srcTriangle.NSIDES; transfo.copy(srcTriangle.transfo); m.copy(srcTriangle.m); //zBuffer=srcTriangle.zBuffer; //FrameBuffer=srcTriangle.FrameBuffer; for (int i=0;i<3;i++) ord[i]=srcTriangle.ord[i]; for (int i=0;i0){ index1=(n-1)*M+m; faces[index1][0]=(n-1)*M+m; faces[index1][1]=(n-1)*M+((m+1)%M); faces[index1][2]=n*M+((m+1)%M); faces[index1][3]=n*M+m; } } } void cube(){ transfo.identity(); int index, index1; NVERTICES = 24; NFACES = 6; NSIDES = 4; vertices = new double[NVERTICES][6]; tVertices = new double[NVERTICES][6]; px=new int[NVERTICES]; py=new int[NVERTICES]; pz=new double[NVERTICES]; faces = new int[NFACES][NSIDES]; for (int xyz=0;xyz<3;xyz++) for (int j=0;j<=1;j++){ index1 = 2*xyz+j; index = 2*NSIDES*xyz + NSIDES*j ; for (int k=0;k0){ double tmppt[]={0,0,z,0,0,1}; vertices[N]=tmppt; } else{ double tmppt[]={0,0,z,0,0,-1}; vertices[N]=tmppt; } for (int n=0; n0){ vertices[n][5]=1; faces[n][0]=n; faces[n][1]=(n+1)%N; } else{ vertices[n][5]=-1; faces[n][1]=n; faces[n][0]=(n+1)%N; } faces[n][2]=N; } } void cap2(int N, double z){ transfo.identity(); double theta; double xyz[]= new double[3]; NVERTICES = N + 1; NFACES = N; NSIDES = 4; vertices = new double[NVERTICES][6]; px=new int[NVERTICES]; py=new int[NVERTICES]; faces = new int[NFACES][NSIDES]; if (z>0){ double tmppt[]={0,0,z,0,0,1}; vertices[N]=tmppt; } else{ double tmppt[]={0,0,z,0,0,-1}; vertices[N]=tmppt; } for (int n=0; n0){ vertices[n][5]=1; faces[n][0]=n; faces[n][1]=(n+1)%N; } else{ vertices[n][5]=-1; faces[n][1]=n; faces[n][0]=(n+1)%N; } faces[n][2]=N; faces[n][3]=N; } } void cylinder(int N){ transfo.identity(); NVERTICES = 4*N+2; NFACES = 3*N; NSIDES = 4; vertices = new double[NVERTICES][6]; px=new int[NVERTICES]; py=new int[NVERTICES]; faces = new int[NFACES][NSIDES]; Shape2 tmptube = new Shape2(); Shape2 cap1 = new Shape2(); Shape2 cap2 = new Shape2(); tmptube.tube(N); cap1.cap(N,1); cap2.cap(N,-1); for (int i=0;i