text: #include "rtweekend.h"
  
  /*const double sin_table[360] = {
  	0.00000000, 0.01745241, 0.03489950, 0.05233596, 0.06975647, 0.08715574, 0.10452846, 0.12186934,
  0.13917310, 0.15643447, 0.17364818, 0.19080900, 0.20791169, 0.22495105, 0.24192190, 0.25881905,
  0.27563736, 0.29237170, 0.30901699, 0.32556815, 0.34202014, 0.35836795, 0.37460659, 0.39073113,
  0.40673664, 0.42261826, 0.43837115, 0.45399050, 0.46947156, 0.48480962, 0.50000000, 0.51503807,
  0.52991926, 0.54463904, 0.55919290, 0.57357644, 0.58778525, 0.60181502, 0.61566148, 0.62932039,
  0.64278761, 0.65605903, 0.66913061, 0.68199836, 0.69465837, 0.70710678, 0.71933980, 0.73135370,
  0.74314483, 0.75470958, 0.76604444, 0.77714596, 0.78801075, 0.79863551, 0.80901699, 0.81915204,
  0.82903757, 0.83867057, 0.84804810, 0.85716730, 0.86602540, 0.87461971, 0.88294759, 0.89100652,
  0.89879405, 0.90630779, 0.91354546, 0.92050485, 0.92718385, 0.93358043, 0.93969262, 0.94551858,
  0.95105652, 0.95630476, 0.96126170, 0.96592583, 0.97029573, 0.97437006, 0.97814760, 0.98162718,
  0.98480775, 0.98768834, 0.99026807, 0.99254615, 0.99452190, 0.99619470, 0.99756405, 0.99862953,
  0.99939083, 0.99984770, 1.00000000, 0.99984770, 0.99939083, 0.99862953, 0.99756405, 0.99619470,
  0.99452190, 0.99254615, 0.99026807, 0.98768834, 0.98480775, 0.98162718, 0.97814760, 0.97437006,
  0.97029573, 0.96592583, 0.96126170, 0.95630476, 0.95105652, 0.94551858, 0.93969262, 0.93358043,
  0.92718385, 0.92050485, 0.91354546, 0.90630779, 0.89879405, 0.89100652, 0.88294759, 0.87461971,
  0.86602540, 0.85716730, 0.84804810, 0.83867057, 0.82903757, 0.81915204, 0.80901699, 0.79863551,
  0.78801075, 0.77714596, 0.76604444, 0.75470958, 0.74314483, 0.73135370, 0.71933980, 0.70710678,
  0.69465837, 0.68199836, 0.66913061, 0.65605903, 0.64278761, 0.62932039, 0.61566148, 0.60181502,
  0.58778525, 0.57357644, 0.55919290, 0.54463904, 0.52991926, 0.51503807, 0.50000000, 0.48480962,
  0.46947156, 0.45399050, 0.43837115, 0.42261826, 0.40673664, 0.39073113, 0.37460659, 0.35836795,
  0.34202014, 0.32556815, 0.30901699, 0.29237170, 0.27563736, 0.25881905, 0.24192190, 0.22495105,
  0.20791169, 0.19080900, 0.17364818, 0.15643447, 0.13917310, 0.12186934, 0.10452846, 0.08715574,
  0.06975647, 0.05233596, 0.03489950, 0.01745241, 0.00000000, -0.01745241, -0.03489950, -0.05233596,
  -0.06975647, -0.08715574, -0.10452846, -0.12186934, -0.13917310, -0.15643447, -0.17364818, -0.19080900,
  -0.20791169, -0.22495105, -0.24192190, -0.25881905, -0.27563736, -0.29237170, -0.30901699, -0.32556815,
  -0.34202014, -0.35836795, -0.37460659, -0.39073113, -0.40673664, -0.42261826, -0.43837115, -0.45399050,
  -0.46947156, -0.48480962, -0.50000000, -0.51503807, -0.52991926, -0.54463904, -0.55919290, -0.57357644,
  -0.58778525, -0.60181502, -0.61566148, -0.62932039, -0.64278761, -0.65605903, -0.66913061, -0.68199836,
  -0.69465837, -0.70710678, -0.71933980, -0.73135370, -0.74314483, -0.75470958, -0.76604444, -0.77714596,
  -0.78801075, -0.79863551, -0.80901699, -0.81915204, -0.82903757, -0.83867057, -0.84804810, -0.85716730,
  -0.86602540, -0.87461971, -0.88294759, -0.89100652, -0.89879405, -0.90630779, -0.91354546, -0.92050485,
  -0.92718385, -0.93358043, -0.93969262, -0.94551858, -0.95105652, -0.95630476, -0.96126170, -0.96592583,
  -0.97029573, -0.97437006, -0.97814760, -0.98162718, -0.98480775, -0.98768834, -0.99026807, -0.99254615,
  -0.99452190, -0.99619470, -0.99756405, -0.99862953, -0.99939083, -0.99984770, -1.00000000, -0.99984770,
  -0.99939083, -0.99862953, -0.99756405, -0.99619470, -0.99452190, -0.99254615, -0.99026807, -0.98768834,
  -0.98480775, -0.98162718, -0.97814760, -0.97437006, -0.97029573, -0.96592583, -0.96126170, -0.95630476,
  -0.95105652, -0.94551858, -0.93969262, -0.93358043, -0.92718385, -0.92050485, -0.91354546, -0.90630779,
  -0.89879405, -0.89100652, -0.88294759, -0.87461971, -0.86602540, -0.85716730, -0.84804810, -0.83867057,
  -0.82903757, -0.81915204, -0.80901699, -0.79863551, -0.78801075, -0.77714596, -0.76604444, -0.75470958,
  -0.74314483, -0.73135370, -0.71933980, -0.70710678, -0.69465837, -0.68199836, -0.66913061, -0.65605903,
  -0.64278761, -0.62932039, -0.61566148, -0.60181502, -0.58778525, -0.57357644, -0.55919290, -0.54463904,
  -0.52991926, -0.51503807, -0.50000000, -0.48480962, -0.46947156, -0.45399050, -0.43837115, -0.42261826,
  -0.40673664, -0.39073113, -0.37460659, -0.35836795, -0.34202014, -0.32556815, -0.30901699, -0.29237170,
  -0.27563736, -0.25881905, -0.24192190, -0.22495105, -0.20791169, -0.19080900, -0.17364818, -0.15643447,
  -0.13917310, -0.12186934, -0.10452846, -0.08715574, -0.06975647, -0.05233596, -0.03489950, -0.01745241
  };
  
  const double cos_table[360] = {
  	1.00000000, 0.99984770, 0.99939083, 0.99862953, 0.99756405, 0.99619470, 0.99452190, 0.99254615,
  0.99026807, 0.98768834, 0.98480775, 0.98162718, 0.97814760, 0.97437006, 0.97029573, 0.96592583,
  0.96126170, 0.95630476, 0.95105652, 0.94551858, 0.93969262, 0.93358043, 0.92718385, 0.92050485,
  0.91354546, 0.90630779, 0.89879405, 0.89100652, 0.88294759, 0.87461971, 0.86602540, 0.85716730,
  0.84804810, 0.83867057, 0.82903757, 0.81915204, 0.80901699, 0.79863551, 0.78801075, 0.77714596,
  0.76604444, 0.75470958, 0.74314483, 0.73135370, 0.71933980, 0.70710678, 0.69465837, 0.68199836,
  0.66913061, 0.65605903, 0.64278761, 0.62932039, 0.61566148, 0.60181502, 0.58778525, 0.57357644,
  0.55919290, 0.54463904, 0.52991926, 0.51503807, 0.50000000, 0.48480962, 0.46947156, 0.45399050,
  0.43837115, 0.42261826, 0.40673664, 0.39073113, 0.37460659, 0.35836795, 0.34202014, 0.32556815,
  0.30901699, 0.29237170, 0.27563736, 0.25881905, 0.24192190, 0.22495105, 0.20791169, 0.19080900,
  0.17364818, 0.15643447, 0.13917310, 0.12186934, 0.10452846, 0.08715574, 0.06975647, 0.05233596,
  0.03489950, 0.01745241, 0.00000000, -0.01745241, -0.03489950, -0.05233596, -0.06975647, -0.08715574,
  -0.10452846, -0.12186934, -0.13917310, -0.15643447, -0.17364818, -0.19080900, -0.20791169, -0.22495105,
  -0.24192190, -0.25881905, -0.27563736, -0.29237170, -0.30901699, -0.32556815, -0.34202014, -0.35836795,
  -0.37460659, -0.39073113, -0.40673664, -0.42261826, -0.43837115, -0.45399050, -0.46947156, -0.48480962,
  -0.50000000, -0.51503807, -0.52991926, -0.54463904, -0.55919290, -0.57357644, -0.58778525, -0.60181502,
  -0.61566148, -0.62932039, -0.64278761, -0.65605903, -0.66913061, -0.68199836, -0.69465837, -0.70710678,
  -0.71933980, -0.73135370, -0.74314483, -0.75470958, -0.76604444, -0.77714596, -0.78801075, -0.79863551,
  -0.80901699, -0.81915204, -0.82903757, -0.83867057, -0.84804810, -0.85716730, -0.86602540, -0.87461971,
  -0.88294759, -0.89100652, -0.89879405, -0.90630779, -0.91354546, -0.92050485, -0.92718385, -0.93358043,
  -0.93969262, -0.94551858, -0.95105652, -0.95630476, -0.96126170, -0.96592583, -0.97029573, -0.97437006,
  -0.97814760, -0.98162718, -0.98480775, -0.98768834, -0.99026807, -0.99254615, -0.99452190, -0.99619470,
  -0.99756405, -0.99862953, -0.99939083, -0.99984770, -1.00000000, -0.99984770, -0.99939083, -0.99862953,
  -0.99756405, -0.99619470, -0.99452190, -0.99254615, -0.99026807, -0.98768834, -0.98480775, -0.98162718,
  -0.97814760, -0.97437006, -0.97029573, -0.96592583, -0.96126170, -0.95630476, -0.95105652, -0.94551858,
  -0.93969262, -0.93358043, -0.92718385, -0.92050485, -0.91354546, -0.90630779, -0.89879405, -0.89100652,
  -0.88294759, -0.87461971, -0.86602540, -0.85716730, -0.84804810, -0.83867057, -0.82903757, -0.81915204,
  -0.80901699, -0.79863551, -0.78801075, -0.77714596, -0.76604444, -0.75470958, -0.74314483, -0.73135370,
  -0.71933980, -0.70710678, -0.69465837, -0.68199836, -0.66913061, -0.65605903, -0.64278761, -0.62932039,
  -0.61566148, -0.60181502, -0.58778525, -0.57357644, -0.55919290, -0.54463904, -0.52991926, -0.51503807,
  -0.50000000, -0.48480962, -0.46947156, -0.45399050, -0.43837115, -0.42261826, -0.40673664, -0.39073113,
  -0.37460659, -0.35836795, -0.34202014, -0.32556815, -0.30901699, -0.29237170, -0.27563736, -0.25881905,
  -0.24192190, -0.22495105, -0.20791169, -0.19080900, -0.17364818, -0.15643447, -0.13917310, -0.12186934,
  -0.10452846, -0.08715574, -0.06975647, -0.05233596, -0.03489950, -0.01745241, -0.00000000, 0.01745241,
  0.03489950, 0.05233596, 0.06975647, 0.08715574, 0.10452846, 0.12186934, 0.13917310, 0.15643447,
  0.17364818, 0.19080900, 0.20791169, 0.22495105, 0.24192190, 0.25881905, 0.27563736, 0.29237170,
  0.30901699, 0.32556815, 0.34202014, 0.35836795, 0.37460659, 0.39073113, 0.40673664, 0.42261826,
  0.43837115, 0.45399050, 0.46947156, 0.48480962, 0.50000000, 0.51503807, 0.52991926, 0.54463904,
  0.55919290, 0.57357644, 0.58778525, 0.60181502, 0.61566148, 0.62932039, 0.64278761, 0.65605903,
  0.66913061, 0.68199836, 0.69465837, 0.70710678, 0.71933980, 0.73135370, 0.74314483, 0.75470958,
  0.76604444, 0.77714596, 0.78801075, 0.79863551, 0.80901699, 0.81915204, 0.82903757, 0.83867057,
  0.84804810, 0.85716730, 0.86602540, 0.87461971, 0.88294759, 0.89100652, 0.89879405, 0.90630779,
  0.91354546, 0.92050485, 0.92718385, 0.93358043, 0.93969262, 0.94551858, 0.95105652, 0.95630476,
  0.96126170, 0.96592583, 0.97029573, 0.97437006, 0.97814760, 0.98162718, 0.98480775, 0.98768834,
  0.99026807, 0.99254615, 0.99452190, 0.99619470, 0.99756405, 0.99862953, 0.99939083, 0.99984770
  };*/
  
  const double infinity = std::numeric_limits<double>::infinity();
  const double PI = 3.141592653589793;
  
  std::random_device seed;
  std::default_random_engine generator(seed());
  std::uniform_real_distribution<double> distribution(0.0, 1.0);
  
  double clamp(double x) { return clamp(x, 0, 1); }
  
  double gamma(double x) { // gamma correction
  	return pow(clamp(x), 1 / 2.2);
  }
  
  double random_double() {
  	return distribution(generator);
  }
  
  double random_double(double min, double max) { // range is [min, max)
  	return min + random_double() * (max - min);
  }
  
  int random_int(int min, int max) { // including min and max
  	return static_cast<int>(random_double(min, max + 1.0));
  }
  
  Vec3 random_in_unit_disk() {
  	double theta = 2 * PI * random_double();
  	double r = sqrt(random_double());
  	return Vec3(r * cos(theta), r * sin(theta), 0);
  }
  
  Vec3 random_in_unit_sphere() { // unifrom on unit sphere
  	double phi = 2 * PI * random_double();
  	double r2 = random_double();
  	return Vec3(cos(phi) * 2 * sqrt(r2 * (1 - r2)), sin(phi) * 2 * sqrt(r2 * (1 - r2)), 1 - 2 * r2);
  }
  
  Vec3 random_in_unit_semisphere(Vec3 normal) {
  	double phi = 2 * PI * random_double(); // random angle
  	double r2 = random_double(); // random distance to z-axis
  	double r2s = sqrt(r2); // uniform in circle area
  	Vec3 w = unit_vector(normal);
  	Vec3 u = unit_vector((cross(fabs(w.x()) > 0.1 ? Vec3(0, 1, 0) : Vec3(1, 0, 0), w)));
  	Vec3 v = cross(w, u);
  	return unit_vector((u * cos(phi) * r2s + v * sin(phi) * r2s + w * sqrt(1 - r2)));
  }
  
  Vec3 reflect(const Vec3& v, const Vec3& n) {
  	return v - 2 * dot(v, n) * n;
  }
  
  Vec3 refract(const Vec3 in_dir, const Vec3& n, double rior) { // roir == relative index of refraction
  	double cos_theta = fmin(dot(-in_dir, n), 1.0);
  	Vec3 r_out_perp = rior * (in_dir + cos_theta * n);
  	Vec3 r_out_parallel = -sqrt(1 - r_out_perp.length_squared()) * n;
  	return r_out_perp + r_out_parallel;
  }