Vector getRefractedRay(float initial_refraction, Spheres *sph, Vector surface_norm, Vector light_ray) { float refraction_index = sph->refraction_index; float n = initial_refraction/refraction_index; Vector refract_ray; //n = .9; //light_ray.x = 0.707107; //light_ray.y = -0.707107; //light_ray.z = 0; //surface_norm.x = 0; //surface_norm.y = 1; //surface_norm.z = 0; float cosTheta1 = vec_dot(surface_norm, vec_scale(light_ray,-1)); float cosTheta2 = sqrt(1.0f-pow(n,2)*(1-(cosTheta1*cosTheta1))); Vector a = vec_scale(light_ray, n); Vector b = vec_scale(surface_norm, n*cosTheta1 - cosTheta2); if(cosTheta1 > 0.0f) { refract_ray = vec_plus(vec_scale(light_ray,n), vec_scale(surface_norm, n*cosTheta1-cosTheta2)); } else { refract_ray = vec_minus(vec_scale(light_ray,n), vec_scale(surface_norm, n*cosTheta1-cosTheta2)); } return refract_ray; }
// // reflect vector p based on normalized vector n // Vector vec_reflect(Vector p, Vector n) { Vector rc; p.x = -(p.x); p.y = -(p.y); p.z = -(p.z); normalize(&n); rc = vec_minus(p ,vec_scale(n, (float)(2*(vec_dot(p, n))))); return rc; }
/* * Calculates the cost function for table tennis trajectory generation optimization * to find spline (3rd order strike+return) polynomials */ double costfunc(unsigned n, const double *x, double *grad, void *my_func_params) { int i; double a1[DOF]; double a2[DOF]; static double q0dot[DOF]; // all zeros static double qfdot[DOF]; // all zeros static double qf[DOF]; // opt value double T = x[2*DOF]; double *q0 = (double *) my_func_params; // instead of using global variables feeding parameters directly if (grad) { for (i = 0; i < DOF; i++) { qf[i] = x[i]; qfdot[i] = x[i+DOF]; grad[i] = (6/pow(T,3))*(qf[i]-q0[i]) - (3/(T*T))*(q0dot[i]+qfdot[i]); grad[i+DOF] = (-3/(T*T))*(qf[i]-q0[i]) + (1/T)*(2*qfdot[i]+q0dot[i]); } //time derivative of cost J vec_minus(qf,q0); //assuming q0dot = 0 here; grad[2*DOF] = (-9/pow(T,4))*inner_prod(qf,qf) + (6/pow(T,3))*inner_prod(qf,qfdot) + (3/(T*T))*inner_prod(q0dot,qfdot) - (1/(T*T))*inner_prod(qfdot,qfdot); } // calculate the polynomial coeffs which are used in the cost calculation calc_strike_poly_coeff(a1,a2,q0,x); return T * (3*T*T*inner_prod(a1,a1) + 3*T*inner_prod(a1,a2) + inner_prod(a2,a2)); }
RGB_float recursive_ray_trace(Vector ray, Point p, int step) { RGB_float color = background_clr; RGB_float reflected_color = {0,0,0}; RGB_float refracted_color = {0,0,0}; Spheres *closest_sph; Point *hit = new Point; closest_sph = intersect_scene(p, ray, scene, hit); //get the point color here //intersects a sphere Point *plane_hit = new Point; color = background_clr; if(chessboard_on && intersect_plane(p, ray, N_plane, p0, plane_hit)) { Vector eye_vec = get_vec(*plane_hit, eye_pos); Vector light_vec = get_vec(*plane_hit, p); normalize(&light_vec); normalize(&eye_vec); color = colorPlane(*plane_hit); Vector shadow_vec = get_vec(*plane_hit, light1); Spheres *sph = NULL; if(inShadow(*plane_hit, shadow_vec, scene, sph) && shadow_on) { color = clr_scale(color, .5); } } if(closest_sph != NULL) { Vector eye_vec = get_vec(*hit, eye_pos); Vector surf_norm = sphere_normal(*hit, closest_sph); Vector light_vec = get_vec(*hit, p); normalize(&light_vec); normalize(&surf_norm); normalize(&eye_vec); color = phong(*hit, eye_vec, surf_norm, closest_sph); if(step < step_max && reflection_on) { Vector reflect_vec = vec_minus(vec_scale(surf_norm, vec_dot(surf_norm, light_vec)*2), light_vec); step += 1; normalize(&reflect_vec); reflected_color = recursive_ray_trace(reflect_vec, *hit, step); reflected_color = clr_scale(reflected_color, closest_sph->reflectance); color = clr_add(color, reflected_color); } if(step < step_max && refraction_on) { Vector refracted_ray = getRefractedRay(1.51, closest_sph, surf_norm, light_vec); step += 1; normalize(&refracted_ray); refracted_ray.x = hit->x + refracted_ray.x; refracted_ray.y = hit->x + refracted_ray.y; refracted_ray.z = hit->x + refracted_ray.z; refracted_color = recursive_ray_trace(refracted_ray, *hit, step); color = clr_add(color, reflected_color); } return color; } else { return color; } }