I spent a day writing my first ray tracing after lrj's guidance !!
First, we will try to add new elements, such as adding a sphere or a texture.
First, there is a mirror:
Then, the last one has a refraction
(There is also the phenomenon of total reflection !)
Er ~~~ Is it very serious? I learned a anti-sawtooth skill, but it still has a little effect:
In addition, the comparison of anti-aliasing (code writing is ugly .. Rendering the following figure takes 10 minutes)
Okay, admit that I am very scum-resistant .....
Next we plan to add textures and sphere. (Is there any such thing about the elliptical model ?)
Code (various 3D ~~ It is actually a little shorter than the sterilization Plan)
#include <cmath>#include <cstdio>#include <algorithm>#include <vector>#define maxdepth 2#define e 1e-8using namespace std;struct P{double x,y,z;};P operator +(P a,P b) {return (P){a.x+b.x,a.y+b.y,a.z+b.z};}P operator -(P a,P b) {return (P){a.x-b.x,a.y-b.y,a.z-b.z};}P operator *(P a,double b) {return (P){a.x*b,a.y*b,a.z*b};}P operator /(P a,double b) {return a*(1/b);}P operator *(P a,P b) {return (P){a.y*b.z-a.z*b.y,a.z*b.x-b.z*a.x,a.x*b.y-a.y*b.x};}double operator /(P a,P b) {return a.x*b.x+a.y*b.y+a.z*b.z;}double mo(P a) {return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}int C(double a) {return (a<-e)?-1:a>e;}struct SJ{P p[4],X,Y,Z,color;double refl,refr,indx;};struct RAY{P a,b;};P change(P a,SJ b) {return (P){a/b.X,a/b.Y,a/b.Z};}RAY get_f(SJ s,RAY r) { RAY ans; ans.a=(P){1e50,1e50}; if (s.indx>1e3) return ans; P a=change(r.a,s); P b=change(r.b,s); if (!C(b.z)) return ans; double dt=(s.p[0].z-a.z)/b.z; if (C(dt)<=0) return ans; a=a+(b*dt); for (int i=0;i<3;i++) { P tt=(s.p[i+1]-s.p[i])*(a-s.p[i]); if (C(tt.z)<0) return ans; }; b.z=-b.z; P dx=(P){1,0,0}; P dy=(P){0,1,0}; P dz=(P){0,0,1}; dx=change(dx,s); dy=change(dy,s); dz=change(dz,s); dx=dx/(mo(dx)); dy=dy/(mo(dy)); dz=dz/(mo(dz)); ans.a=(P){a/dx,a/dy,a/dz}; ans.b=(P){b/dx,b/dy,b/dz}; return ans;}RAY get_z(SJ s,RAY r,double zr) { RAY ans; ans.a=(P){1e50,1e50}; P a=change(r.a,s); P b=change(r.b,s); if (!C(b.z)) return ans; double dt=(s.p[0].z-a.z)/b.z; if (C(dt)<=0) return ans; double gm; if (C(zr-s.indx)) gm=mo(b)*s.indx; else gm=mo(b)/s.indx; a=a+(b*dt); for (int i=0;i<3;i++) { P tt=(s.p[i+1]-s.p[i])*(a-s.p[i]); if (C(tt.z)<0) return ans; }; P dx=(P){1,0,0}; P dy=(P){0,1,0}; P dz=(P){0,0,1}; dx=change(dx,s); dy=change(dy,s); dz=change(dz,s); dx=dx/(mo(dx)); dy=dy/(mo(dy)); dz=dz/(mo(dz)); gm=gm*gm-b.x*b.x-b.y*b.y; if (C(gm)<=0) return ans; gm=sqrt(gm); if (b.z>0) b.z=gm; else b.z=-gm; ans.a=(P){a/dx,a/dy,a/dz}; ans.b=(P){b/dx,b/dy,b/dz}; return ans;}vector<SJ> s(0);SJ getclose(RAY a) { SJ b; b.indx=1e9; P c,d=(P){1e30,1e30}; for (int i=0;i<(int)s.size();i++) { c=get_f(s[i],a).a; if (mo(c-a.a)<mo(d-a.a)) b=s[i],d=c; }; return b;}SJ makeSJ(P a,P b,P c) { SJ h; h.p[0]=h.p[3]=a; h.p[1]=b, h.p[2]=c; h.Z=(b-a)*(c-a); h.X=(b-a)*h.Z; h.Y=h.Z*h.X; h.X=h.X/(mo(h.X)); h.Y=h.Y/(mo(h.Y)); h.Z=h.Z/(mo(h.Z)); for (int i=0;i<4;i++) h.p[i]=change(h.p[i],h); return h;}P sun,sunl;double amb;P get_point_color(SJ a,P b) { RAY r=(RAY){b,sun-b}; r.b=r.b/(mo(r.b)); P x=get_f(getclose(r),r).a; double l; if (C(mo(b-x)-mo(sun-b))>=0) { l=abs(a.Z/r.b); } else l=0; l=amb+(1-amb)*l; a.color.x*=sunl.x; a.color.y*=sunl.y; a.color.z*=sunl.z; return a.color*l;}P trace_ray(int depth, RAY r,double zr) { P point_color=(P){0,0,0},reflect_color=(P){0,0,0},refract_color=(P){0,0,0}; if (mo(r.a)>1e20) return point_color; SJ i=getclose(r); if(i.indx<1e3) { double refl=i.refl; double refr=i.refr; P x=get_f(i,r).a; point_color=get_point_color(i,x) * (1-refl-refr); if(depth<maxdepth && C(refl)>0) reflect_color=trace_ray(depth+1, get_f(i,r),zr) * refl; if(depth<maxdepth && C(refr)>0) refract_color=trace_ray(depth+1, get_z(i,r,zr),(!C(zr-1))?i.indx:1) * refr; } return point_color+reflect_color+refract_color;}int main() { freopen("N_input_6.txt","r",stdin); freopen("image.txt","w",stdout); s.clear(); int n; scanf("%d",&n); while (n--) { int np; vector<P> p(0); scanf("%d",&np); while (np--) { P h; scanf("%lf%lf%lf",&h.x,&h.y,&h.z); p.push_back(h); }; int mp; scanf("%d",&mp); for (int i=1;i<=mp;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); s.push_back(makeSJ(p[a],p[b],p[c])); }; P color; scanf("%lf%lf%lf",&color.x,&color.y,&color.z); double refl,refr,idx; scanf("%lf%lf%lf",&refl,&refr,&idx); for (int i=1;i<=mp;i++) { s[s.size()-i].color=color; s[s.size()-i].refl=refl; s[s.size()-i].refr=refr; s[s.size()-i].indx=idx; }; }; scanf("%lf%lf%lf",&sun.x,&sun.y,&sun.z); scanf("%lf",&amb); scanf("%lf%lf%lf",&sunl.x,&sunl.y,&sunl.z); int np; scanf("%d",&np); while (np--) { P cs,ct,cu; scanf("%lf%lf%lf",&cs.x,&cs.y,&cs.z); scanf("%lf%lf%lf",&ct.x,&ct.y,&ct.z); scanf("%lf%lf%lf",&cu.x,&cu.y,&cu.z); ct=ct-cs; P cl=ct*cu; cu=cu/mo(cu); cl=cl/mo(cl); ct=ct/mo(ct); double fov; int w,d; scanf("%lf",&fov); scanf("%d%d",&w,&d); printf("%d %d\n",w,d); double ld=tan(fov/180*M_PI/2)/(w*.5); P rs=cl*ld,ds=cu*(-ld); P ss=ct-(rs*(w*.5))-(ds*(d*.5)); for (int i=1;i<=d;i++) { for (int j=1;j<=w;j++) { if (!((i*w+j)%500))fprintf(stderr,"loading.... %.2lf%%\n",((i-1.)*w+j)/(d*w)*100); P ns=ss+(rs*(j-.5))+(ds*(i-.5)); RAY go=(RAY){cs,ns}; P cl=trace_ray(0,go,1); printf("%02x%02x%02x ",(int)(cl.x*255),(int)(cl.y*255),(int)(cl.z*255)); //printf("%lf %lf %lf ",cl.x,cl.y,cl.z); }; printf("\n"); }; }; return 0;}