public static double intersection_ray_sphere(double[] position, double[] vector, sphere_class sphere) { double output_t = double.PositiveInfinity; position = vector_class.vector_subtract(position, sphere.center); double a = vector_class.vector_dot_product(vector, vector); double b = 2 * vector_class.vector_dot_product(vector, position); double c = vector_class.vector_dot_product(position, position) - (sphere.radius * sphere.radius); double discriminant = b * b - 4 * a * c; if (discriminant < 0) { return(output_t); } double distance_square_root = System.Math.Sqrt(discriminant); double q = 0; if (b < 0) { q = (-b - distance_square_root) * 0.5; } else { q = (-b + distance_square_root) * 0.5; } double t0 = q / a; double t1 = c / q; if (t0 > t1) { double temporary = t0; t0 = t1; t1 = temporary; } if (t1 < 0) { return(output_t); } if (t0 < 0) { output_t = t1; return(output_t); } else { output_t = t0; return(output_t); } }
private void read_spheres() { while (text_read_letter() == 's') { sphere_class sphere_temporary; sphere_temporary = new sphere_class(); for (int i = 0; i < 3; i++) { sphere_temporary.center[i] = text_read_number(); } sphere_temporary.radius = text_read_number(); sphere_temporary.material_index = (int)text_read_number(); sphere.Add(sphere_temporary); } }
public double[] get_next_direction_sphere(double[] input_position, double[] input_vector, sphere_class input_sphere, ref double incidence_ior, ref double[] multiplier) { double[] output_vector = new double[3]; double[] random_vector = new double[3]; double[] sphere_normal = new double[3]; double[] u = new double[3]; double[] v = new double[3]; double a, b, c, angle, radius; angle = 2 * System.Math.PI * random.NextDouble(); radius = System.Math.Sqrt(random.NextDouble()); a = System.Math.Sin(angle) * radius; b = System.Math.Cos(angle) * radius; c = System.Math.Sqrt(1.0 - (a * a + b * b)); sphere_normal = input_sphere.get_normal(input_position); if (vector_class.vector_dot_product(sphere_normal, input_vector) > 0) { sphere_normal = vector_class.vector_negative(sphere_normal); } double[] temporary = new double[3]; for (int i = 0; i < 3; i++) { temporary[i] = random.NextDouble(); } u = vector_class.vector_cross_product(sphere_normal, temporary); v = vector_class.vector_cross_product(sphere_normal, u); u = vector_class.vector_cross_product(sphere_normal, v); u = vector_class.vector_unitize(u); v = vector_class.vector_unitize(v); random_vector = vector_class.vector_add(vector_class.vector_add(vector_class.vector_scale(v, b), vector_class.vector_scale(u, a)), vector_class.vector_scale(sphere_normal, c)); if (random.NextDouble() * (reflectivity_mean + refractivity_mean) < reflectivity_mean) //reflect { output_vector = vector_class.vector_average(random_vector, get_reflection(input_vector, sphere_normal), reflect_glossiness); for (int n = 0; n < 3; n++) { multiplier[n] *= color[n].reflectivity; } } else //refract { output_vector = vector_class.vector_average(vector_class.vector_negative(random_vector), get_refraction(input_vector, sphere_normal, incidence_ior, ref multiplier), refract_glossiness); for (int n = 0; n < 3; n++) { multiplier[n] *= color[n].refractivity; } incidence_ior = refractive_index; } return(output_vector); }