import java.applet.Applet; import java.awt.*; public class raytracer1 extends Applet{ int NSPHERE=5; /* 表示する球の個数 */ int SIZE=150; /* 表示する画像の大きさ */ int DEPTH=4; /* 光線追跡の深さ */ Button button1; TextField tf1[],tf2[],tf3[],tf4[]; TextField tf6,tf7,tf8,tf9,tf10,tf11,tf0; Choice paramchoice,paramchoice2; Label depthLabel,noLabel,paramLabel,viewLabel,ambLabel; Panel choicePanel,inputPanel,depthPanel,noPanel,butnPanel,canvasPanel, matelPanel,paramPanel0,viewPanel,ambPanel,dispPanel,allPanel; Panel paramPanel[]; Phong phongCanvas; DispCanvas disp; double r_view=10.,the_view=0.0,pi_view=0.0, amb1=0.1,amb2=0.1,amb3=0.8; /* 視点、環境光の初期値 */ double ks[]={0.99,0.1,0.6,0.6,0.6};double kt[]={0.0,0.9,0.0,0.0,0.0}; double ir[]={1.0,3.0,1.0,1.0,1.0};double deg[]={60.,60.,60.,60.,60.}; /* 球の属性の初期値 */ public void init(){ int nn=1; String A="0.0"; System.out.println("test"); phongCanvas = new Phong(SIZE); disp = new DispCanvas(); phongCanvas.setNSPHERE(NSPHERE); //phongCanvas.setSIZE(SIZE); phongCanvas.setDEPTH(SIZE); phongCanvas.setparam(ks,kt,ir,deg); System.out.println("test2"); phongCanvas.setView(r_view,the_view,pi_view); phongCanvas.setAmb(amb1,amb2,amb3); disp.setNSPHERE(NSPHERE); disp.setparam(ks,kt,ir,deg); choicePanel = new Panel();allPanel= new Panel(); noPanel = new Panel();inputPanel = new Panel();matelPanel = new Panel(); paramPanel0 = new Panel();viewPanel = new Panel();ambPanel = new Panel(); butnPanel = new Panel();canvasPanel = new Panel(); dispPanel = new Panel();depthPanel = new Panel(); button1 = new Button("trace"); paramchoice = new Choice();paramchoice2 = new Choice(); tf0 = new TextField(A.valueOf(DEPTH),1); tf1 = new TextField[NSPHERE];tf2 = new TextField[NSPHERE]; tf3 = new TextField[NSPHERE];tf4 = new TextField[NSPHERE]; for(int i=0;i0){ phongCanvas.setDEPTH(DEPTH); }else{ phongCanvas.setDEPTH(4); } phongCanvas.setparam(ks,kt,ir,deg); disp.setparam(ks,kt,ir,deg); A = new Double(0.);B = new Double(0.); C = new Double(0.); Vr = new Double(0.);Vt = new Double(0.);Vp = new Double(0.); Vr = A.valueOf(tf6.getText());Vt = B.valueOf(tf7.getText()); Vp = C.valueOf(tf8.getText()); phongCanvas.setView(Vr.doubleValue(),Vt.doubleValue(),Vp.doubleValue()); A = new Double(0.);B = new Double(0.); C = new Double(0.); Ambr = new Double(0.);Ambg = new Double(0.);Ambb = new Double(0.); Ambr = A.valueOf(tf9.getText());Ambg = B.valueOf(tf10.getText()); Ambb = C.valueOf(tf11.getText()); phongCanvas.setAmb(Ambr.doubleValue(),Ambg.doubleValue(), Ambb.doubleValue()); disp.repaint(); phongCanvas.start(); } return true; } } class DispCanvas extends Canvas { /* アプレットの右上にパラメータの情報を表示 */ double ks[] = new double[10];double kt[] = new double[10]; double ir[] = new double[10];double deg[] = new double[10]; int NSPHERE; public void setNSPHERE(int i){ /* 球の個数を代入 */ NSPHERE=i; } public void setparam(double a[],double bb[],double c[],double d[]){ /* 球の属性を表わす変数の代入 */ for(int i =0;i255) COL.x=255.; if(COL.y<0) COL.y=0.;if(COL.y>255) COL.y=255.; if(COL.z<0) COL.z=0.;if(COL.z>255) COL.z=255.; myGC.setColor(new Color((int)COL.x,(int)COL.y,(int)COL.z)); myGC.drawLine(x,y,x,y); repaint(); } for(x=(int)(xmax+1);x sph[i].rad) { s1 = 0.; }else { s1 = 1.; num++; r2 = sph[i].rad*sph[i].rad; d1 = sph[i].cen.z*sph[i].cen.z - r2; dd = sph[i].cen.x*sph[i].cen.x+ d1; xz = sph[i].cen.x*sph[i].cen.z; d2 = r2-day*day; zz = sph[i].cen.z + day*za; zd = zz*zz - d2; dd = Math.sqrt((sph[i].cen.x*sph[i].cen.x + zd)*d2); x1 = (xz - dd)/zd*r_view; x2 = (xz + dd)/zd*r_view; s1 = (x1 + txw)*scale - 1.; s2 = (x2 + txw)*scale - 1.; //System.out.println("d1="+d1+" "+dd+" "+xz+" "+d2); //System.out.println("x1="+x1+" "+x2+" "+s1+" "+s2); if(s1 < xmin) xmin = s1; if(s2 > xmax) xmax = s2; /* ysでのスキャンライン上には、xminからxmaxまでの間に球が存在している */ } } return num; } void transfrm(){ /* 視線がz軸上になるように座標変換する */ double fef,tef,xy,px,py,pz; int s; fef=3.1415/180.*pi_view;tef=3.1415/180.*the_view; ct=Math.cos(tef);st=Math.sin(tef); cf=Math.cos(fef);sf=Math.sin(fef); System.out.println("fef="+fef+" "+tef+" "+ct+" "+st); for(s=0;s0 ? Math.sqrt(u) : 1e31; u = b-u>TOL ? b-u : b+u; if((u>=TOL)&&(u0.){ diffuse = cos_alfa*sph[s].kd + ambient; Hx=lightx+Dx;Hy=lighty+Dy;Hz=lightz+Dz; gamma = (Hx*Nx + Hy*Ny + Hz*Nz)/Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); if(gamma>0.) specular = sph[s].ks*Math.pow(gamma,(int)sph[s].deg); }else{ diffuse=ambient; } fd=Dx*Nx+Dy*Ny+Dz*Nz; fd=(double)Math.abs(fd); cx=Dx/fd;cy=Dy/fd;cz=Dy/fd; Rx=-(cx+2*Nx);Ry=-(cy+2*Ny);Rz=-(cz+2*Nz); R=new Vec(Rx,Ry,Rz);R.vunit(R); P=new Vec(Px,Py,Pz); color2=new Vec(); color2=trace(level,P,R); color3=new Vec(); color3=black; if(sph[s].kt>0.0){ flug = 1; Px = cx*cx+cy*cy+cz*cz; Py = (cx+Nx)*(cx+Nx)+(cy+Ny)*(cy+Ny)+(cz+Nz)*(cz+Nz); Pz =sph[s].ir*sph[s].ir*Px-Py; if(Pz > 0.0){ Rx=1./Math.sqrt(Pz)*fd*(Nx+cx)-Nx;Ry=fd*(Ny+cy)-Ny;Rz=fd*(Nz+cz)-Nz; R=new Vec(Rx,Ry,Rz);R.vunit(R); }else{ R=new Vec();R=D; } color3=trace(level,P,R); } cx=sph[s].color.x*diffuse + specular + sph[s].ks*color2.x + sph[s].kt*color3.x; cy=sph[s].color.y*diffuse + specular + sph[s].ks*color2.y + sph[s].kt*color3.y; cz=sph[s].color.z*diffuse + specular + sph[s].ks*color2.z + sph[s].kt*color3.z; return (new Vec(cx,cy,cz)); } } class Vec{ /* ベクトルクラス */ public double x,y,z; Vec(){ } Vec(double nwx,double nwy,double nwz){ x=nwx; y=nwy; z=nwz; } void setval(double nwx,double nwy,double nwz){ /* ベクトルの値を代入 */ x=nwx; y=nwy; z=nwz; } void vcomb(double a,Vec A,Vec B){ /* ベクトルAとベクトルBとの1次結合関数 */ x=B.x + a*A.x; y=B.y + a*A.y; z=B.z + a*A.z; } void vunit(Vec A){ /* ベクトルAの正規化 */ double a,v; v=A.x*A.x+A.y*A.y+A.z*A.z; a=1/Math.sqrt(v); x=a*A.x; y=a*A.y; z=a*A.z; } } class Sphere{ /* 球のクラス */ public Vec cen,color; public double x,y,z,r,g,b,rad,kd,ks,kt,kl,ir,deg; Sphere(){ } Sphere(double ocenx,double oceny,double ocenz,double ocolr, double ocolg,double ocolb,double orad,double okd, double oks,double okt,double okl,double oir,double odeg){ cen = new Vec(ocenx,oceny,ocenz); color = new Vec(ocolr,ocolg,ocolb); rad=orad;kd=okd;ks=oks;kt=okt;kl=okl;ir=oir;deg=odeg; } void setval(double ocenx,double oceny,double ocenz,double ocolr, double ocolg,double ocolb,double orad,double okd, double oks,double okt,double okl,double oir,double odeg){ /* 球の変数を代入 */ cen = new Vec(ocenx,oceny,ocenz); color = new Vec(ocolr,ocolg,ocolb); rad=orad;kd=okd;ks=oks;kt=okt;kl=okl;ir=oir;deg=odeg; } }