/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015-2018 Danny Robson */ #pragma once #include "../point.hpp" #include "ray.hpp" /////////////////////////////////////////////////////////////////////////////// namespace cruft::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; } }