libcruft-util/geom/sphere.hpp
2018-04-16 16:00:32 +10:00

66 lines
1.8 KiB
C++

/*
* 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 <danny@nerdcruft.net>
*/
#ifndef __UTIL_GEOM_SPHERE_HPP
#define __UTIL_GEOM_SPHERE_HPP
#include "../point.hpp"
#include "ray.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace util::geom {
template <size_t S, typename T>
struct sphere {
point<S,T> 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 <size_t S, typename T>
constexpr T
distance (const ray<S,T> r, const sphere<S,T> 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