43#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_RAY_3D_SPHERE_3D_H
44#define LASS_GUARDIAN_OF_INCLUSION_PRIM_RAY_3D_SPHERE_3D_H
61 template <
class NormalizingPolicy>
64 template <
typename T,
class PP>
66 const Sphere3D<T>& sphere,
const Ray3D<T, NormalizingPolicy, PP>& ray,
70 using TVector = Vector3D<TValue>;
71 using TNumTraits =
typename TVector::TNumTraits;
73 using TDouble = std::conditional_t<std::is_same_v<T, float>, double, T>;
74 using TVectorDouble = Vector3D<TDouble>;
76 const TVector cs = ray.support() - sphere.center();
77 const TVector& d = ray.direction();
78 const TValue r2 =
num::sqr(sphere.radius());
81 const TValue a = d.squaredNorm();
82 const TValue b = dot(cs, d);
83 const TValue c =
static_cast<TValue
>(
84 static_cast<TVectorDouble
>(cs).squaredNorm() -
85 num::sqr(
static_cast<TDouble
>(sphere.radius())));
89 const TVector l = cs - (b / a) * d;
90 const TValue discriminant = r2 - l.squaredNorm();
92 if (discriminant > TNumTraits::zero)
95 const TValue q = -(b + std::copysign(num::sqrt(a * discriminant), b));
113 else if (discriminant == TNumTraits::zero)
115 const TValue t1 = - b / a;
129 struct RaySphere<Normalized>
131 template <
typename T,
class PP>
132 static Result intersect(
const Sphere3D<T>& sphere,
133 const Ray3D<T, Normalized, PP>& ray,
137 using TVector = Vector3D<TValue>;
138 using TNumTraits =
typename TVector::TNumTraits;
140 using TDouble = std::conditional_t<std::is_same_v<T, float>, double, T>;
141 using TVectorDouble = Vector3D<TDouble>;
143 const TVector cs = ray.support() - sphere.center();
144 const TVector& d = ray.direction();
145 const TValue r2 =
num::sqr(sphere.radius());
149 const TValue b = dot(cs, d);
150 const TValue c =
static_cast<TValue
>(
151 static_cast<TVectorDouble
>(cs).squaredNorm() -
152 num::sqr(
static_cast<TDouble
>(sphere.radius())));
156 const TVector l = cs - b * d;
157 const TValue discriminant = r2 - l.squaredNorm();
159 if (discriminant > TNumTraits::zero)
162 const TValue q = -(b + std::copysign(num::sqrt(discriminant), b));
180 else if (discriminant == TNumTraits::zero)
182 const TValue t1 = -b;
216template<
typename T,
class NP,
class PP>
inline
219 T& t,
const T& tMin = T())
222 return impl::RaySphere<NP>::intersect(sphere, ray, t, tMin);
224 const Result result = impl::RaySphere<NP>::intersect(sphere, ray, t, tMin);
225 LASS_ASSERT(t > tMin || result ==
rNone);
T sqr(const T &x)
return x * x
implementation details of lass::prim
set of geometrical primitives
Result
meta information on the result you have from an operation like an intersection ...
@ rNone
operation has no answer, output arguments are meaningless
@ rOne
there's exactly one answer, 1 output argument contains the answer
Library for Assembled Shared Sources.