Vector3D Vector3D::refract( const Vector3D &normal, double n) const { double cos_s = Vector3D::dot(*this, normal) / len() / normal.len(); if (cos_s > 0) { n = 1.0 / n; } double abs_cos_s = fabs(cos_s); Vector3D true_normal = - (cos_s * normal).normalized(); Vector3D result = *this / n + (abs_cos_s / n - sqrt(1 - (1 - abs_cos_s * abs_cos_s) / n / n)) * true_normal; return result; }
Vector3D normalized(const Vector3D &a) { return a / a.len(); }
Vector3D Vector3D::reflect(const Vector3D &normal) const { return *this - 2 * Vector3D::dot(*this, normal) / normal.len() / len() * normal; }