libcruft-util/geom/sphere.hpp

55 lines
1.4 KiB
C++
Raw Normal View History

2015-04-13 21:46:40 +10:00
/*
2018-08-04 15:14:06 +10:00
* 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/.
2015-04-13 21:46:40 +10:00
*
* Copyright 2015-2018 Danny Robson <danny@nerdcruft.net>
2015-04-13 21:46:40 +10:00
*/
#pragma once
2015-04-13 21:46:40 +10:00
#include "../point.hpp"
2015-04-13 21:46:40 +10:00
#include "ray.hpp"
2017-01-05 15:06:49 +11:00
///////////////////////////////////////////////////////////////////////////////
namespace cruft::geom {
2015-04-13 21:46:40 +10:00
template <size_t S, typename T>
struct sphere {
2015-04-15 14:29:20 +10:00
point<S,T> centre;
T radius;
2015-04-13 21:46:40 +10:00
};
typedef sphere<2,float> sphere2f;
2015-04-13 21:46:40 +10:00
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;
}
2017-01-05 15:06:49 +11:00
}