libcruft-util/geom/sphere.hpp

55 lines
1.4 KiB
C++

/*
* 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 <danny@nerdcruft.net>
*/
#pragma once
#include "../point.hpp"
#include "ray.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace cruft::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;
}
}