/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2015-2018 Danny Robson */ #ifndef __UTIL_GEOM_SPHERE_HPP #define __UTIL_GEOM_SPHERE_HPP #include "../point.hpp" #include "ray.hpp" /////////////////////////////////////////////////////////////////////////////// namespace util::geom { template struct sphere { point centre; T radius; }; typedef sphere<2,float> sphere2f; typedef sphere<3,float> sphere3f; /////////////////////////////////////////////////////////////////////////// /// returns the smallest distance from a ray to a sphere intersection /// /// returns NaN on miss /// returns NaN if behind template constexpr T distance (const ray r, const sphere s) { const T b = dot (r.direction, r.origin - s.centre); const T c = dot (r.origin - s.centre, r.origin - s.centre) - s.radius * s.radius; const T D = b * b - c; // no intersection if (D < 0) return INFINITY; auto t_ = std::sqrt (D); auto t0 = -b + t_; auto t1 = -b - t_; return t1 >= 0 ? t1 : t0 >= 0 ? t0 : INFINITY; } } #endif