public class sphere extends Surface{ double[] center; double[] originalCenter; double R; double[] toCenter; static double[] e=new double[] {0,0,1};//simplifying by assuming the eye is infinitely remote public sphere(){ center=new double[] {0,0,-5}; originalCenter=new double[] {0,0,-5}; R=0.8; m=new material(); } public sphere(double r, material ms, double x, double y, double z){ center=new double[3]; originalCenter=new double[3]; originalCenter[0]=center[0]=x; originalCenter[1]=center[1]=y; originalCenter[2]=center[2]=z; m = new material(); m.copy(ms); R=r; } public void setCenter(double[] sr){ originalCenter[0]=center[0] = sr[0]; originalCenter[1]=center[1] = sr[1]; originalCenter[2]=center[2] = sr[2]; } void setTransfo(Matrix3D tfs){//only for transformations that don't change the radius tfOrig=new Matrix3D(); tfOrig.copy(tfs); tf=new Matrix3D(); tf.copy(tfs); double[] tmp=new double[4]; tmp[0]=originalCenter[0]; tmp[1]=originalCenter[1]; tmp[2]=originalCenter[2]; tmp[3]=1; double[] tmp2=new double[4]; tf.transform(tmp, tmp2); center[0]=tmp2[0]; center[1]=tmp2[1]; center[2]=tmp2[2]; } double[] intersections(double[]v, double[] w){ double[] res=new double[2]; res[0]=res[1]=-1; double A=dotP(w,w); toCenter=diff(v,center); double B=2*dotP(toCenter,w); double C=dotP(toCenter,toCenter) - R*R; double discr=B*B-4*A*C; if (discr==0) res[0]=res[1]=-B/(2*A); if (discr>0){ res[0]= (-B-Math.sqrt(discr))/(2*A); res[1]= (-B+Math.sqrt(discr))/(2*A); } Vector thisV=new Vector(v); Vector thisW=new Vector(w); currentNormalIn=thisV.add(thisW.scalMult(res[0])); currentNormalIn=currentNormalIn.diff(center); currentNormalIn.normalize(); currentNormalOut=thisV.add(thisW.scalMult(res[1])); currentNormalOut=currentNormalOut.diff(center); currentNormalOut.normalize(); return res; } Vector getNormal(double[] currPt){ double[] normV=diff(currPt, center); normV=normalize(normV); Vector res=new Vector(normV); return res; } public double intersect(double[] v, double[] w){ double A=dotP(w,w); toCenter=diff(v,center); double B=2*dotP(toCenter,w); double C=dotP(toCenter,toCenter) - R*R; double discr=B*B-4*A*C; if (discr<0) return 10500; if (discr==0) return -B/(2*A); if (discr>0) return (-B-Math.sqrt(discr))/(2*A); return 10500; } public double intersect2(double[] v, double[] w){ double A=dotP(w,w); toCenter=diff(v,center); double B=2*dotP(toCenter,w); double C=dotP(toCenter,toCenter) - R*R; double discr=B*B-4*A*C; if (discr<0) return 10500; if (discr==0) return -B/(2*A); //if (discr>0) return (-B-Math.sqrt(discr))/(2*A); if (discr>0){ double root1=(-B-Math.sqrt(discr))/(2*A); if (root1>=0) return root1; else return (-B+Math.sqrt(discr))/(2*A); } return 10500; } public double[] shade(light[] lights, double[] v, double[] w, double t){ double[] res = new double[] {0,0,0}; double[] currPt=new double[3]; for (int i=0; i<3; ++i){ currPt[i]=v[i]+t*w[i]; res[i]=m.ambient[i]; } double[] normV=diff(currPt, center); normV=normalize(normV); if (lights!=null){ for (int i=0; i0) res[j]+=lights[i].rgb[j]*m.diffuse[j]*vald;// diffuse double[] tmp=new double[3]; for (int k=0; k<3; ++k) tmp[k]=2*vald*normV[k]; double vals=dotP(diff(tmp,lights[i].dir),e); if (vals>0) res[j]+=lights[i].rgb[j]*m.specular[j]*Math.pow(vals,m.p); } } } return res; } public double[] shade(sphere[] obj, light[] lights, double[] v, double[] w, double t){ double[] res = new double[] {0,0,0}; double[] currPt=new double[3]; for (int i=0; i<3; ++i){ currPt[i]=v[i]+t*w[i]; res[i]=m.ambient[i]; } double[] normV=diff(currPt, center); normV=normalize(normV); if (lights!=null){ for (int i=0; i0 & tTmp<9995){ shadowed=1; break; } } if (shadowed==1){ continue; } for (int j=0;j<3;j++){ //double vald=lights[i].dir[0]*normV[0]+lights[i].dir[1]*normV[1]+lights[i].dir[2]*normV[2]; double vald=dotP(lights[i].dir, normV); if (vald>0) res[j]+=lights[i].rgb[j]*m.diffuse[j]*vald;// diffuse double[] tmp=new double[3]; for (int k=0; k<3; ++k) tmp[k]=2*vald*normV[k]; double vals=dotP(diff(tmp,lights[i].dir),e); if (vals>0) res[j]+=lights[i].rgb[j]*m.specular[j]*Math.pow(vals,m.p); } } } return res; } public double dotP(double[] vs, double[] ws){ double res=0; int n=vs.length; for (int i=0; i