#include class vec3{ public: double x; double y; double z; vec3() { x = 0; y = 0; z = 0; } vec3(double X, double Y, double Z) { x = X; y = Y; z = Z; } vec3 scale(double s) { return vec3(x*s, y*s, z*s); } void normalize() { double distance = x*x + y*y + z*z; distance = sqrt(distance); x = x/distance; y = y/distance; z = z/distance; } vec3 add(vec3 b) { return vec3(x + b.x, y + b.y, z + b.z); } vec3 crossProduct(vec3 b) { vec3 output; output.x = y*b.z - z*b.y; output.y = z*b.x - x*b.z; output.z = x*b.y - y*b.x; return output; } void negate() { x = -x; y = -y; z = -z; } float distance() { return (float)sqrt(x*x + y*y + z*z); } float dotProduct(vec3 b) { double output = x*b.x + y*b.y + z*b.z; return (float)output; } vec3 reflection(vec3 normal) { vec3 R; float temp = normal.dotProduct(vec3(x, y, z)); //View(dot)normal R.x = -(2*normal.x*temp - x); R.y = -(2*normal.y*temp - y); R.z = -(2*normal.z*temp - z); return R; } //this function uses snells law to calculate the refraction of our ray through a transparent surface vec3 refraction(vec3 normal, double dielectric) { double cosTheta1 = normal.dotProduct( vec3(-x, -y, -z) ); double cosTheta2 = sqrt( 1 - (dielectric*dielectric)*( 1 - (cosTheta1*cosTheta1)) ); if(cosTheta1 > 0) { vec3 vRefract = vec3(dielectric*x, dielectric*y, dielectric*z); double temp = (dielectric*cosTheta1) - cosTheta2; vRefract = vec3(vRefract.x + (temp*normal.x), vRefract.y + (temp*normal.y), vRefract.z + (temp*normal.z) ); vRefract.normalize(); return vRefract; } else { vec3 vRefract = vec3(dielectric*x, dielectric*y, dielectric*z); double temp = cosTheta2 + (dielectric*cosTheta1); vRefract = vec3(vRefract.x - (temp*normal.x), vRefract.y - (temp*normal.y), vRefract.z - (temp*normal.z) ); vRefract.normalize(); return vRefract; } } vec3 betterRefraction(vec3 normal, double dielectric) { normal.normalize(); float cosI = -normal.dotProduct(vec3(x, y, z)); if(cosI < 0) dielectric = 1.0/dielectric; float sin2T = dielectric*dielectric*(1.0 - cosI*cosI); if(sin2T < 1.0) { vec3 intRefrac = vec3(x*dielectric - (normal.x*(dielectric + sqrt(1.0-sin2T)) ), y*dielectric - (normal.y*(dielectric + sqrt(1.0-sin2T)) ), z*dielectric - (normal.z*(dielectric + sqrt(1.0-sin2T)) ) ); intRefrac.normalize(); return intRefrac; } return vec3(0,0,0); } };