Atoms Crowd  7.0.0
ImathSphere.h
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // A 3D sphere class template
8 //
9 
10 #ifndef INCLUDED_ATOMSMATHSPHERE_H
11 #define INCLUDED_ATOMSMATHSPHERE_H
12 
13 #include <AtomsMath/ImathBox.h>
14 #include <AtomsMath/ImathLine.h>
15 #include <AtomsMath/ImathNamespace.h>
16 #include <AtomsMath/ImathVec.h>
17 
18 ATOMSMATH_INTERNAL_NAMESPACE_HEADER_ENTER
19 
23 
24 template <class T> class Sphere3
25 {
26  public:
27 
30 
33 
35  T radius;
36 
38 
41 
43  ATOMSMATH_HOSTDEVICE constexpr Sphere3() : center (0, 0, 0), radius (0) {}
44 
46  ATOMSMATH_HOSTDEVICE constexpr Sphere3 (const Vec3<T>& c, T r) : center (c), radius (r) {}
47 
49 
52 
55  ATOMSMATH_HOSTDEVICE void circumscribe (const Box<Vec3<T>>& box);
56 
58 
61 
69  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool
70  intersect (const Line3<T>& l, Vec3<T>& intersection) const;
71 
79  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool intersectT (const Line3<T>& l, T& t) const;
80 
82 };
83 
85 typedef Sphere3<float> Sphere3f;
86 
89 
90 //---------------
91 // Implementation
92 //---------------
93 
94 template <class T>
95 inline void
97 {
98  center = T (0.5) * (box.min + box.max);
99  radius = (box.max - center).length();
100 }
101 
102 template <class T>
103 ATOMSMATH_CONSTEXPR14 bool
104 Sphere3<T>::intersectT (const Line3<T>& line, T& t) const
105 {
106  bool doesIntersect = true;
107 
108  Vec3<T> v = line.pos - center;
109  T B = T (2.0) * (line.dir ^ v);
110  T C = (v ^ v) - (radius * radius);
111 
112  // compute discriminant
113  // if negative, there is no intersection
114 
115  T discr = B * B - T (4.0) * C;
116 
117  if (discr < 0.0)
118  {
119  // line and Sphere3 do not intersect
120 
121  doesIntersect = false;
122  }
123  else
124  {
125  // t0: (-B - sqrt(B^2 - 4AC)) / 2A (A = 1)
126 
127  T sqroot = std::sqrt (discr);
128  t = (-B - sqroot) * T (0.5);
129 
130  if (t < 0.0)
131  {
132  // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1)
133 
134  t = (-B + sqroot) * T (0.5);
135  }
136 
137  if (t < 0.0)
138  doesIntersect = false;
139  }
140 
141  return doesIntersect;
142 }
143 
144 template <class T>
145 ATOMSMATH_CONSTEXPR14 bool
146 Sphere3<T>::intersect (const Line3<T>& line, Vec3<T>& intersection) const
147 {
148  T t (0);
149 
150  if (intersectT (line, t))
151  {
152  intersection = line (t);
153  return true;
154  }
155  else
156  {
157  return false;
158  }
159 }
160 
161 ATOMSMATH_INTERNAL_NAMESPACE_HEADER_EXIT
162 
163 #endif // INCLUDED_ATOMSMATHSPHERE_H
Definition: ImathBox.h:36
Definition: ImathLine.h:25
Vec3< T > pos
A point on the line.
Definition: ImathLine.h:32
Vec3< T > dir
The direction of the line.
Definition: ImathLine.h:35
Definition: ImathSphere.h:25
constexpr ATOMSMATH_HOSTDEVICE Sphere3()
Default is center at (0,0,0) and radius of 0.
Definition: ImathSphere.h:43
ATOMSMATH_HOSTDEVICE void circumscribe(const Box< Vec3< T >> &box)
Definition: ImathSphere.h:96
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool intersectT(const Line3< T > &l, T &t) const
Definition: ImathSphere.h:104
constexpr ATOMSMATH_HOSTDEVICE Sphere3(const Vec3< T > &c, T r)
Initialize to a given center and radius.
Definition: ImathSphere.h:46
Vec3< T > center
Center.
Definition: ImathSphere.h:32
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool intersect(const Line3< T > &l, Vec3< T > &intersection) const
Definition: ImathSphere.h:146
T radius
Radius.
Definition: ImathSphere.h:35
Definition: ImathVec.h:260