EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
EBGeometry_AnalyticDistanceFunctions.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022 Robert Marskar <robert.marskar@sintef.no>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
11#ifndef EBGEOMETRY_ANALYTICDISTANCEFUNCTIONS_HPP
12#define EBGEOMETRY_ANALYTICDISTANCEFUNCTIONS_HPP
13
14// Std includes
15#include <algorithm>
16#include <array>
17#include <cmath>
18#include <cstddef>
19#include <limits>
20#include <memory>
21#include <random>
22#include <type_traits>
23
24// Our includes
27#include "EBGeometry_Macros.hpp"
29#include "EBGeometry_Vec.hpp"
30
31namespace EBGeometry {
32
41template <class T>
43{
44 static_assert(std::is_floating_point_v<T>, "PlaneSDF<T>: T must be a floating-point type");
45
46public:
52 PlaneSDF() = default;
53
59 PlaneSDF(const Vec3T<T>& a_point, const Vec3T<T>& a_normal) noexcept
60 {
61 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
62 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
63 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
64 EBGEOMETRY_EXPECT(std::isfinite(a_normal[0]));
65 EBGEOMETRY_EXPECT(std::isfinite(a_normal[1]));
66 EBGEOMETRY_EXPECT(std::isfinite(a_normal[2]));
67 EBGEOMETRY_EXPECT(a_normal.length() > T(0));
68
69 m_point = a_point;
70 m_normal = a_normal / a_normal.length();
71 }
72
76 PlaneSDF(const PlaneSDF&) = default;
77
81 PlaneSDF(PlaneSDF&&) = default;
82
88 operator=(const PlaneSDF&) = default;
89
95 operator=(PlaneSDF&&) = default;
96
100 ~PlaneSDF() override = default;
101
107 [[nodiscard]] T
108 signedDistance(const Vec3T<T>& a_point) const noexcept override
109 {
110 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
111 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
112 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
113 EBGEOMETRY_EXPECT(std::abs(m_normal.length() - T(1)) < std::sqrt(std::numeric_limits<T>::epsilon()));
114
115 return dot((a_point - m_point), m_normal);
116 }
117
118protected:
123
127 Vec3T<T> m_normal = Vec3T<T>(T(0), T(1), T(0));
128};
129
137template <class T>
139{
140 static_assert(std::is_floating_point_v<T>, "SphereSDF<T>: T must be a floating-point type");
141
142public:
146 SphereSDF() = default;
147
153 SphereSDF(const Vec3T<T>& a_center, const T& a_radius) noexcept
154 {
155 EBGEOMETRY_EXPECT(std::isfinite(a_center[0]));
156 EBGEOMETRY_EXPECT(std::isfinite(a_center[1]));
157 EBGEOMETRY_EXPECT(std::isfinite(a_center[2]));
158 EBGEOMETRY_EXPECT(std::isfinite(a_radius));
160
163 }
164
168 SphereSDF(const SphereSDF&) = default;
169
173 SphereSDF(SphereSDF&&) = default;
174
179 SphereSDF&
180 operator=(const SphereSDF&) = default;
181
186 SphereSDF&
187 operator=(SphereSDF&&) = default;
188
192 ~SphereSDF() override = default;
193
198 [[nodiscard]] const Vec3T<T>&
200 {
201 return m_center;
202 }
203
208 Vec3T<T>&
210 {
211 return m_center;
212 }
213
218 [[nodiscard]] const T&
220 {
221 return m_radius;
222 }
223
228 T&
230 {
231 return m_radius;
232 }
233
239 [[nodiscard]] T
240 signedDistance(const Vec3T<T>& a_point) const noexcept override
241 {
242 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
243 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
244 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
245
246 return (a_point - m_center).length() - m_radius;
247 }
248
249protected:
254
258 T m_radius = T(1);
259};
260
269template <class T>
271{
272 static_assert(std::is_floating_point_v<T>, "BoxSDF<T>: T must be a floating-point type");
273
274public:
278 BoxSDF() = default;
279
287 {
288 EBGEOMETRY_EXPECT(std::isfinite(a_loCorner[0]));
289 EBGEOMETRY_EXPECT(std::isfinite(a_loCorner[1]));
290 EBGEOMETRY_EXPECT(std::isfinite(a_loCorner[2]));
291 EBGEOMETRY_EXPECT(std::isfinite(a_hiCorner[0]));
292 EBGEOMETRY_EXPECT(std::isfinite(a_hiCorner[1]));
293 EBGEOMETRY_EXPECT(std::isfinite(a_hiCorner[2]));
297
300 }
301
305 BoxSDF(const BoxSDF&) = default;
306
310 BoxSDF(BoxSDF&&) = default;
311
316 BoxSDF&
317 operator=(const BoxSDF&) = default;
318
323 BoxSDF&
324 operator=(BoxSDF&&) = default;
325
329 ~BoxSDF() override = default;
330
335 [[nodiscard]] const Vec3T<T>&
337 {
338 return m_loCorner;
339 }
340
345 Vec3T<T>&
347 {
348 return m_loCorner;
349 }
350
355 [[nodiscard]] const Vec3T<T>&
357 {
358 return m_hiCorner;
359 }
360
365 Vec3T<T>&
367 {
368 return m_hiCorner;
369 }
370
376 [[nodiscard]] T
377 signedDistance(const Vec3T<T>& a_point) const noexcept override
378 {
379 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
380 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
381 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
382
383 // For each coordinate direction, we have delta[dir] if a_point[dir] falls
384 // between xLo and xHi. In this case delta[dir] will be the signed distance
385 // to the closest box face in the dir-direction. Otherwise, if a_point[dir]
386 // is outside the corner we have delta[dir] > 0.
387 const Vec3T<T> delta(std::max(m_loCorner[0] - a_point[0], a_point[0] - m_hiCorner[0]),
388 std::max(m_loCorner[1] - a_point[1], a_point[1] - m_hiCorner[1]),
389 std::max(m_loCorner[2] - a_point[2], a_point[2] - m_hiCorner[2]));
390
391 // Note: max is max(Vec3T<T>, Vec3T<T>) and not std::max. It returns a
392 // vector with coordinate-wise largest components. Note that the first part
393 // std::min(...) is the signed distance on the inside of the box (delta will
394 // have negative components). The other part max(Vec3T<T>::zeros(), ...) is
395 // for outside the box.
396 const T d = std::min(T(0.0), delta[delta.maxDir(false)]) + max(Vec3T<T>::zeros(), delta).length();
397
398 return d;
399 }
400
401protected:
405 Vec3T<T> m_loCorner = Vec3T<T>(T(-0.5), T(-0.5), T(-0.5));
406
410 Vec3T<T> m_hiCorner = Vec3T<T>(T(0.5), T(0.5), T(0.5));
411};
412
424template <class T>
426{
427 static_assert(std::is_floating_point_v<T>, "TorusSDF<T>: T must be a floating-point type");
428
429public:
433 TorusSDF() = default;
434
441 TorusSDF(const Vec3T<T>& a_center, const T& a_majorRadius, const T& a_minorRadius) noexcept
442 {
443 EBGEOMETRY_EXPECT(std::isfinite(a_center[0]));
444 EBGEOMETRY_EXPECT(std::isfinite(a_center[1]));
445 EBGEOMETRY_EXPECT(std::isfinite(a_center[2]));
446 EBGEOMETRY_EXPECT(std::isfinite(a_majorRadius));
447 EBGEOMETRY_EXPECT(std::isfinite(a_minorRadius));
451
455 }
456
460 TorusSDF(const TorusSDF&) = default;
461
465 TorusSDF(TorusSDF&&) = default;
466
471 TorusSDF&
472 operator=(const TorusSDF&) = default;
473
478 TorusSDF&
479 operator=(TorusSDF&&) = default;
480
484 ~TorusSDF() override = default;
485
490 [[nodiscard]] const Vec3T<T>&
492 {
493 return m_center;
494 }
495
500 Vec3T<T>&
502 {
503 return m_center;
504 }
505
510 [[nodiscard]] const T&
512 {
513 return m_majorRadius;
514 }
515
520 T&
522 {
523 return m_majorRadius;
524 }
525
530 [[nodiscard]] const T&
532 {
533 return m_minorRadius;
534 }
535
540 T&
542 {
543 return m_minorRadius;
544 }
550 [[nodiscard]] T
551 signedDistance(const Vec3T<T>& a_point) const noexcept override
552 {
553 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
554 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
555 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
556
557 const Vec3T<T> p = a_point - m_center;
558 const T rho = std::sqrt(p[0] * p[0] + p[1] * p[1]) - m_majorRadius;
559 const T d = std::sqrt(rho * rho + p[2] * p[2]) - m_minorRadius;
560
561 return d;
562 }
563
564protected:
569
574
578 T m_minorRadius = T(0.5);
579};
580
590template <class T>
592{
593 static_assert(std::is_floating_point_v<T>, "CylinderSDF<T>: T must be a floating-point type");
594
595public:
600 CylinderSDF() = default;
601
608 CylinderSDF(const Vec3T<T>& a_center1, const Vec3T<T>& a_center2, const T& a_radius) noexcept
609 {
610 EBGEOMETRY_EXPECT(std::isfinite(a_center1[0]));
611 EBGEOMETRY_EXPECT(std::isfinite(a_center1[1]));
612 EBGEOMETRY_EXPECT(std::isfinite(a_center1[2]));
613 EBGEOMETRY_EXPECT(std::isfinite(a_center2[0]));
614 EBGEOMETRY_EXPECT(std::isfinite(a_center2[1]));
615 EBGEOMETRY_EXPECT(std::isfinite(a_center2[2]));
616 EBGEOMETRY_EXPECT(std::isfinite(a_radius));
619
623
624 m_center = (m_center2 + m_center1) * T(0.5);
627 }
628
632 CylinderSDF(const CylinderSDF&) = default;
633
638
644 operator=(const CylinderSDF&) = default;
645
651 operator=(CylinderSDF&&) = default;
652
656 ~CylinderSDF() override = default;
657
662 [[nodiscard]] const Vec3T<T>&
664 {
665 return m_center1;
666 }
667
672 [[nodiscard]] const Vec3T<T>&
674 {
675 return m_center2;
676 }
677
682 [[nodiscard]] const T&
684 {
685 return m_radius;
686 }
687
693 [[nodiscard]] T
694 signedDistance(const Vec3T<T>& a_point) const noexcept override
695 {
696 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
697 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
698 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
699
700 T d = std::numeric_limits<T>::infinity();
701
702 if (m_length > T(0.0) && m_radius > T(0.0)) {
703 EBGEOMETRY_EXPECT(std::abs(m_axis.length() - T(1)) < std::sqrt(std::numeric_limits<T>::epsilon()));
704
705 const Vec3T<T> point = a_point - m_center;
706 const T para = dot(point, m_axis);
707 const Vec3T<T> ortho = point - para * m_axis; // Distance from cylinder axis.
708
709 // w: Distance from cylinder wall. < 0 on inside and > 0 on outside.
710 // h: Distance from cylinder top. < 0 on inside and > 0 on outside.
711 const T w = ortho.length() - m_radius;
712 const T h = std::abs(para) - T(0.5) * m_length;
713
714 constexpr T zero = T(0.0);
715
716 if (w <= zero && h <= zero) {
717 // Inside cylinder
718 d = (std::abs(w) < std::abs(h)) ? w : h;
719 }
720 else if (w <= zero && h > zero) {
721 // Above one of the endcaps.
722 d = h;
723 }
724 else if (w > zero && h < zero) {
725 // Outside radius but between the endcaps.
726 d = w;
727 }
728 else {
729 d = std::sqrt(w * w + h * h);
730 }
731 }
732
733 return d;
734 }
735
736protected:
740 Vec3T<T> m_center1 = Vec3T<T>(T(0), T(-0.5), T(0));
741
745 Vec3T<T> m_center2 = Vec3T<T>(T(0), T(0.5), T(0));
746
751
755 Vec3T<T> m_axis = Vec3T<T>(T(0), T(1), T(0));
756
760 T m_length = T(1);
761
765 T m_radius = T(1);
766};
767
777template <class T>
779{
780 static_assert(std::is_floating_point_v<T>, "InfiniteCylinderSDF<T>: T must be a floating-point type");
781
782public:
788
795 InfiniteCylinderSDF(const Vec3T<T>& a_center, const T& a_radius, const size_t a_axis) noexcept
796 {
797 EBGEOMETRY_EXPECT(std::isfinite(a_center[0]));
798 EBGEOMETRY_EXPECT(std::isfinite(a_center[1]));
799 EBGEOMETRY_EXPECT(std::isfinite(a_center[2]));
800 EBGEOMETRY_EXPECT(std::isfinite(a_radius));
803
806 m_axis = a_axis;
807 }
808
813
818
825
832
836 ~InfiniteCylinderSDF() override = default;
837
843 [[nodiscard]] T
844 signedDistance(const Vec3T<T>& a_point) const noexcept override
845 {
846 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
847 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
848 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
849
851 delta[m_axis] = 0.0;
852
853 const T d = delta.length() - m_radius;
854
855 return d;
856 }
857
858protected:
863
867 T m_radius = T(1);
868
872 size_t m_axis = 1U;
873};
874
892template <class T>
894{
895 static_assert(std::is_floating_point_v<T>, "CapsuleSDF<T>: T must be a floating-point type");
896
897public:
903 CapsuleSDF() = default;
904
916 CapsuleSDF(const Vec3T<T>& a_tip1, const Vec3T<T>& a_tip2, const T& a_radius) noexcept
917 {
918 EBGEOMETRY_EXPECT(std::isfinite(a_tip1[0]));
919 EBGEOMETRY_EXPECT(std::isfinite(a_tip1[1]));
920 EBGEOMETRY_EXPECT(std::isfinite(a_tip1[2]));
921 EBGEOMETRY_EXPECT(std::isfinite(a_tip2[0]));
922 EBGEOMETRY_EXPECT(std::isfinite(a_tip2[1]));
923 EBGEOMETRY_EXPECT(std::isfinite(a_tip2[2]));
924 EBGEOMETRY_EXPECT(std::isfinite(a_radius));
927
928 const Vec3T<T> axis = (a_tip2 - a_tip1) / length(a_tip2 - a_tip1);
929
933 }
934
938 CapsuleSDF(const CapsuleSDF&) = default;
939
943 CapsuleSDF(CapsuleSDF&&) = default;
944
950 operator=(const CapsuleSDF&) = default;
951
957 operator=(CapsuleSDF&&) = default;
958
962 ~CapsuleSDF() override = default;
963
969 [[nodiscard]] T
970 signedDistance(const Vec3T<T>& a_point) const noexcept override
971 {
972 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
973 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
974 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
976
977 const Vec3T<T> v1 = a_point - m_center1;
978 const Vec3T<T> v2 = m_center2 - m_center1;
979
980 const T h = std::clamp(dot(v1, v2) / dot(v2, v2), T(0.0), T(1.0));
981 const T d = length(v1 - h * v2) - m_radius;
982
983 return d;
984 }
985
986protected:
990 Vec3T<T> m_center1 = Vec3T<T>(T(0), T(-0.5), T(0));
991
995 Vec3T<T> m_center2 = Vec3T<T>(T(0), T(0.5), T(0));
996
1000 T m_radius = T(0.5);
1001};
1002
1018template <class T>
1020{
1021 static_assert(std::is_floating_point_v<T>, "InfiniteConeSDF<T>: T must be a floating-point type");
1022
1023public:
1028 InfiniteConeSDF() = default;
1029
1036 InfiniteConeSDF(const Vec3T<T>& a_tip, const T& a_angle) noexcept
1037 {
1038 EBGEOMETRY_EXPECT(std::isfinite(a_tip[0]));
1039 EBGEOMETRY_EXPECT(std::isfinite(a_tip[1]));
1040 EBGEOMETRY_EXPECT(std::isfinite(a_tip[2]));
1041 EBGEOMETRY_EXPECT(std::isfinite(a_angle));
1042 EBGEOMETRY_EXPECT(a_angle > T(0));
1043 EBGEOMETRY_EXPECT(a_angle < T(180));
1044
1045 m_tip = a_tip;
1046 m_c.x = std::sin(T(0.5) * a_angle * pi<T> / T(180));
1047 m_c.y = std::cos(T(0.5) * a_angle * pi<T> / T(180));
1048 }
1049
1054
1059
1065 operator=(const InfiniteConeSDF&) = default;
1066
1073
1077 ~InfiniteConeSDF() override = default;
1078
1084 [[nodiscard]] T
1085 signedDistance(const Vec3T<T>& a_point) const noexcept override
1086 {
1087 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
1088 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
1089 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
1090 EBGEOMETRY_EXPECT(std::abs(length(m_c) - T(1)) < std::sqrt(std::numeric_limits<T>::epsilon()));
1091
1092 const Vec3T<T> delta = a_point - m_tip;
1093 const Vec2T<T> q(std::sqrt(delta[0] * delta[0] + delta[1] * delta[1]), -delta[2]);
1094
1095 const T d1 = length(q - m_c * std::max(dot(q, m_c), T(0.0)));
1096 const T d2 = d1 * ((q.x * m_c.y - q.y * m_c.x < T(0.0)) ? T(-1.0) : T(1.0));
1097
1098 return d2;
1099 }
1100
1101protected:
1106
1110 Vec2T<T> m_c = Vec2T<T>(std::sin(pi<T> / T(8)), std::cos(pi<T> / T(8)));
1111};
1112
1125template <class T>
1127{
1128 static_assert(std::is_floating_point_v<T>, "ConeSDF<T>: T must be a floating-point type");
1129
1130public:
1135 ConeSDF() = default;
1136
1143 ConeSDF(const Vec3T<T>& a_tip, const T& a_height, const T& a_angle) noexcept
1144 {
1145 EBGEOMETRY_EXPECT(std::isfinite(a_tip[0]));
1146 EBGEOMETRY_EXPECT(std::isfinite(a_tip[1]));
1147 EBGEOMETRY_EXPECT(std::isfinite(a_tip[2]));
1148 EBGEOMETRY_EXPECT(std::isfinite(a_height));
1149 EBGEOMETRY_EXPECT(std::isfinite(a_angle));
1151 EBGEOMETRY_EXPECT(a_angle > T(0));
1152 EBGEOMETRY_EXPECT(a_angle < T(180));
1153
1154 m_tip = a_tip;
1156 m_c.x = std::sin(T(0.5) * a_angle * pi<T> / T(180));
1157 m_c.y = std::cos(T(0.5) * a_angle * pi<T> / T(180));
1158 }
1159
1163 ConeSDF(const ConeSDF&) = default;
1164
1168 ConeSDF(ConeSDF&&) = default;
1169
1174 ConeSDF&
1175 operator=(const ConeSDF&) = default;
1176
1181 ConeSDF&
1182 operator=(ConeSDF&&) = default;
1183
1187 ~ConeSDF() override = default;
1188
1194 [[nodiscard]] T
1195 signedDistance(const Vec3T<T>& a_point) const noexcept override
1196 {
1197 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
1198 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
1199 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
1200 EBGEOMETRY_EXPECT(std::abs(length(m_c) - T(1)) < std::sqrt(std::numeric_limits<T>::epsilon()));
1201 EBGEOMETRY_EXPECT(m_c.y > T(0));
1202
1203 const Vec3T<T> delta = a_point - m_tip;
1204 const T dr = std::sqrt(delta[0] * delta[0] + delta[1] * delta[1]);
1205 const T dz = delta[2];
1206
1207 constexpr T zero = T(0.0);
1208 constexpr T one = T(1.0);
1209
1210 const Vec2T<T> q = m_height * Vec2T<T>(m_c.x / m_c.y, -1.0);
1211 const Vec2T<T> w = Vec2T<T>(dr, dz);
1212 const Vec2T<T> a = w - std::clamp(dot(w, q) / dot(q, q), zero, one) * q;
1213 const Vec2T<T> b = w - Vec2T<T>(q.x * std::clamp(w.x / q.x, zero, one), q.y);
1214
1215 auto sign = [](const T& x) -> int { return (x > zero) - (x < zero); };
1216
1217 const T k = sign(q.y);
1218 const T d = std::min(dot(a, a), dot(b, b));
1219 const T s = std::max(k * (w.x * q.y - w.y * q.x), k * (w.y - q.y));
1220
1221 return std::sqrt(d) * sign(s);
1222 }
1223
1224protected:
1229
1233 Vec2T<T> m_c = Vec2T<T>(std::sin(pi<T> / T(8)), std::cos(pi<T> / T(8)));
1234
1238 T m_height = T(1);
1239};
1240
1251template <class T>
1253{
1254 static_assert(std::is_floating_point_v<T>, "RoundedBoxSDF<T>: T must be a floating-point type");
1255
1256public:
1262 RoundedBoxSDF() = default;
1263
1271 {
1272 EBGEOMETRY_EXPECT(std::isfinite(a_dimensions[0]));
1273 EBGEOMETRY_EXPECT(std::isfinite(a_dimensions[1]));
1274 EBGEOMETRY_EXPECT(std::isfinite(a_dimensions[2]));
1275 EBGEOMETRY_EXPECT(std::isfinite(a_curvature));
1280
1281 m_dimensions = T(0.5) * a_dimensions;
1282 m_sphere = std::make_shared<SphereSDF<T>>(Vec3T<T>::zeros(), a_curvature);
1283 }
1284
1288 RoundedBoxSDF(const RoundedBoxSDF&) = default;
1289
1294
1300 operator=(const RoundedBoxSDF&) = default;
1301
1308
1312 ~RoundedBoxSDF() override = default;
1313
1319 [[nodiscard]] T
1320 signedDistance(const Vec3T<T>& a_point) const noexcept override
1321 {
1322 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
1323 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
1324 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
1325
1326 return m_sphere->signedDistance(a_point - clamp(a_point, -m_dimensions, m_dimensions));
1327 }
1328
1329protected:
1333 std::shared_ptr<SphereSDF<T>> m_sphere = std::make_shared<SphereSDF<T>>(Vec3T<T>::zeros(), T(0.1));
1334
1338 Vec3T<T> m_dimensions = Vec3T<T>(T(0.5), T(0.5), T(0.5));
1339};
1340
1358template <class T>
1360{
1361 static_assert(std::is_floating_point_v<T>, "PerlinSDF<T>: T must be a floating-point type");
1362
1363public:
1368 PerlinSDF() = default;
1369
1379 const T a_noisePersistence,
1380 const unsigned int a_noiseOctaves) noexcept
1381 {
1382 EBGEOMETRY_EXPECT(std::isfinite(a_noiseAmplitude));
1383 EBGEOMETRY_EXPECT(std::isfinite(a_noiseFrequency[0]));
1384 EBGEOMETRY_EXPECT(std::isfinite(a_noiseFrequency[1]));
1385 EBGEOMETRY_EXPECT(std::isfinite(a_noiseFrequency[2]));
1386 EBGEOMETRY_EXPECT(std::isfinite(a_noisePersistence));
1387
1390 m_noisePersistence = std::min(T(1), a_noisePersistence);
1391 m_noiseOctaves = std::max(1U, a_noiseOctaves);
1392
1393 for (int i = 0; i < 256; i++) {
1396 }
1397
1398 std::mt19937 g(0);
1399 this->shuffle(g);
1400 }
1401
1405 PerlinSDF(const PerlinSDF&) = default;
1406
1410 PerlinSDF(PerlinSDF&&) = default;
1411
1416 PerlinSDF&
1417 operator=(const PerlinSDF&) = default;
1418
1423 PerlinSDF&
1424 operator=(PerlinSDF&&) = default;
1425
1429 ~PerlinSDF() override = default;
1430
1436 [[nodiscard]] T
1437 signedDistance(const Vec3T<T>& a_point) const noexcept override
1438 {
1439 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
1440 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
1441 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
1442
1443 T ret = 0.0;
1444
1446 T curAmp = 1.0;
1447
1448 for (unsigned int curOctave = 0; curOctave < m_noiseOctaves; curOctave++) {
1449 ret += T(0.5) * curAmp * (T(1) + this->noise(a_point * curFreq));
1450
1453 }
1454
1455 return ret * m_noiseAmplitude;
1456 };
1457
1470 template <class URNG>
1471 void
1472 shuffle(URNG& g) noexcept
1473 {
1474
1475 for (unsigned int i = 0; i < 256; i++) {
1476 m_permutationTable[i] = static_cast<int>(i);
1477 }
1478
1479 std::shuffle(m_permutationTable.begin(), m_permutationTable.begin() + 256, g);
1480
1481 for (int i = 0; i < 256; i++) {
1483 }
1484 }
1485
1490 std::array<int, 512>&
1495
1496protected:
1503 static constexpr std::array<int, 256> s_perlinPermutationTable = {
1504 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142,
1505 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203,
1506 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165,
1507 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
1508 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
1509 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250,
1510 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
1511 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
1512 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34,
1513 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
1514 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114,
1515 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};
1516
1521
1526
1531
1537 std::array<int, 512> m_permutationTable = {};
1538
1542 unsigned int m_noiseOctaves = 1U;
1543
1551 [[nodiscard]] virtual T
1552 lerp(const T t, const T a, const T b) const noexcept
1553 {
1554 return a + t * (b - a);
1555 };
1556
1562 [[nodiscard]] virtual T
1563 fade(const T t) const noexcept
1564 {
1565 return t * t * t * (t * (t * 6 - 15) + 10);
1566 };
1567
1576 [[nodiscard]] T
1577 grad(const int hash, const T x, const T y, const T z) const noexcept
1578 {
1579 const int h = hash & 15;
1580 const T u = h < 8 ? x : y;
1581 const T v = h < 4 ? y : h == 12 || h == 14 ? x : z;
1582 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
1583 }
1584
1590 [[nodiscard]] T
1591 noise(const Vec3T<T>& a_point) const noexcept
1592 {
1593 // Lower cube corner
1594 const int X = static_cast<int>(std::floor(a_point[0])) & 255;
1595 const int Y = static_cast<int>(std::floor(a_point[1])) & 255;
1596 const int Z = static_cast<int>(std::floor(a_point[2])) & 255;
1597
1598 // Relative distance wrt lower cube corner
1599 const T x = a_point[0] - std::floor(a_point[0]);
1600 const T y = a_point[1] - std::floor(a_point[1]);
1601 const T z = a_point[2] - std::floor(a_point[2]);
1602
1603 // Fade curves
1604 const T u = fade(x);
1605 const T v = fade(y);
1606 const T w = fade(z);
1607
1608 // Hash coordinates of 8 cube corners
1609 const int A = m_permutationTable[X] + Y;
1610 const int AA = m_permutationTable[A] + Z;
1611 const int AB = m_permutationTable[A + 1] + Z;
1612 const int B = m_permutationTable[X + 1] + Y;
1613 const int BA = m_permutationTable[B] + Z;
1614 const int BB = m_permutationTable[B + 1] + Z;
1615
1616 // Add blended results from 8 corners of cube
1617 return lerp(
1618 w,
1619 lerp(v,
1620 lerp(u, grad(m_permutationTable[AA], x, y, z), grad(m_permutationTable[BA], x - 1, y, z)),
1621 lerp(u, grad(m_permutationTable[AB], x, y - 1, z), grad(m_permutationTable[BB], x - 1, y - 1, z))),
1622 lerp(v,
1623 lerp(u, grad(m_permutationTable[AA + 1], x, y, z - 1), grad(m_permutationTable[BA + 1], x - 1, y, z - 1)),
1624 lerp(u,
1625 grad(m_permutationTable[AB + 1], x, y - 1, z - 1),
1626 grad(m_permutationTable[BB + 1], x - 1, y - 1, z - 1))));
1627 };
1628};
1629
1652template <class T>
1654{
1655 static_assert(std::is_floating_point_v<T>, "RoundedCylinderSDF<T>: T must be a floating-point type");
1656
1657public:
1663
1671 RoundedCylinderSDF(const T a_radius, const T a_curvature, const T a_height) noexcept
1672 {
1673 EBGEOMETRY_EXPECT(std::isfinite(a_radius));
1674 EBGEOMETRY_EXPECT(std::isfinite(a_curvature));
1675 EBGEOMETRY_EXPECT(std::isfinite(a_height));
1681
1684 m_height = T(0.5) * a_height - a_curvature;
1685 }
1686
1691
1696
1703
1710
1714 ~RoundedCylinderSDF() override = default;
1715
1721 [[nodiscard]] T
1722 signedDistance(const Vec3T<T>& a_point) const noexcept override
1723 {
1724 EBGEOMETRY_EXPECT(std::isfinite(a_point[0]));
1725 EBGEOMETRY_EXPECT(std::isfinite(a_point[1]));
1726 EBGEOMETRY_EXPECT(std::isfinite(a_point[2]));
1727
1728 const T xz = std::sqrt(a_point[2] * a_point[2] + a_point[0] * a_point[0]);
1729 const auto d1 = Vec2T<T>(xz - m_majorRadius, std::abs(a_point[1]) - m_height);
1730 const auto d2 = Vec2T<T>(std::max(d1.x, T(0)), std::max(d1.y, T(0)));
1731
1732 return std::min(std::max(d1.x, d1.y), T(0)) + std::sqrt(d2.x * d2.x + d2.y * d2.y) - m_minorRadius;
1733 }
1734
1735protected:
1739 T m_majorRadius = T(0.9);
1740
1744 T m_minorRadius = T(0.1);
1745
1749 T m_height = T(0.4);
1750};
1751
1752} // namespace EBGeometry
1753
1754#endif
Declarations of bounding volume types used in bounding volume hierarchies.
Mathematical constants for EBGeometry.
Utility macros for EBGeometry.
#define EBGEOMETRY_EXPECT(cond)
Runtime precondition assertion for EBGeometry.
Definition EBGeometry_Macros.hpp:62
Abstract base class for representing a signed distance function.
Declaration of 2D and 3D point/vector classes with templated precision. Used with DCEL tools.
Signed distance field for an axis-aligned box (AABB).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:271
BoxSDF & operator=(const BoxSDF &)=default
Copy assignment.
BoxSDF()=default
Default constructor. Constructs a unit cube centered at the origin: [-0.5, 0.5]^3.
~BoxSDF() override=default
Destructor.
BoxSDF(const BoxSDF &)=default
Copy constructor.
Vec3T< T > m_loCorner
Low box corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:405
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the axis-aligned box.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:377
Vec3T< T > & getHighCorner() noexcept
Get upper-right corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:366
Vec3T< T > & getLowCorner() noexcept
Get lower-left corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:346
BoxSDF & operator=(BoxSDF &&)=default
Move assignment.
const Vec3T< T > & getHighCorner() const noexcept
Get upper-right corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:356
const Vec3T< T > & getLowCorner() const noexcept
Get lower-left corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:336
Vec3T< T > m_hiCorner
High box corner.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:410
BoxSDF(BoxSDF &&)=default
Move constructor.
BoxSDF(const Vec3T< T > &a_loCorner, const Vec3T< T > &a_hiCorner) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:286
Signed distance field for a capsule (pill shape): a cylinder capped with hemispheres.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:894
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the capsule.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:970
CapsuleSDF & operator=(const CapsuleSDF &)=default
Copy assignment.
Vec3T< T > m_center2
Center of the other hemispherical cap.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:995
CapsuleSDF()=default
Default constructor. Constructs a capsule with tips at (0,-1,0) and (0,1,0), radius 0....
~CapsuleSDF() override=default
Destructor.
CapsuleSDF(const CapsuleSDF &)=default
Copy constructor.
CapsuleSDF & operator=(CapsuleSDF &&)=default
Move assignment.
T m_radius
Capsule radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1000
CapsuleSDF(const Vec3T< T > &a_tip1, const Vec3T< T > &a_tip2, const T &a_radius) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:916
CapsuleSDF(CapsuleSDF &&)=default
Move constructor.
Vec3T< T > m_center1
Center of one hemispherical cap.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:990
Signed distance field for a finite cone.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1127
ConeSDF()=default
Default constructor. Constructs a finite cone with its tip at the origin, height 1,...
Vec3T< T > m_tip
Tip position.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1228
ConeSDF & operator=(ConeSDF &&)=default
Move assignment.
ConeSDF & operator=(const ConeSDF &)=default
Copy assignment.
ConeSDF(ConeSDF &&)=default
Move constructor.
T m_height
Cone height (tip to base).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1238
ConeSDF(const Vec3T< T > &a_tip, const T &a_height, const T &a_angle) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1143
~ConeSDF() override=default
Destructor.
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the finite cone.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1195
ConeSDF(const ConeSDF &)=default
Copy constructor.
Vec2T< T > m_c
(sin, cos) of the half opening-angle. Default: 45° full angle → half-angle 22.5°.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1233
Signed distance field for a finite, flat-capped cylinder.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:592
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the cylinder.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:694
T m_length
Distance between the two endpoints.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:760
Vec3T< T > m_center1
One endpoint (cap center).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:740
const Vec3T< T > & getCenter2() const noexcept
Get the other endpoint.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:673
Vec3T< T > m_center2
Other endpoint (cap center).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:745
CylinderSDF(const Vec3T< T > &a_center1, const Vec3T< T > &a_center2, const T &a_radius) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:608
CylinderSDF()=default
Default constructor. Constructs a unit cylinder of radius 1 and height 1, centred at the origin with ...
CylinderSDF(const CylinderSDF &)=default
Copy constructor.
Vec3T< T > m_center
Midpoint of m_center1 and m_center2.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:750
const T & getRadius() const noexcept
Get radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:683
Vec3T< T > m_axis
Unit axis pointing from m_center1 to m_center2.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:755
const Vec3T< T > & getCenter1() const noexcept
Get one endpoint.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:663
~CylinderSDF() override=default
Destructor.
T m_radius
Cylinder radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:765
CylinderSDF(CylinderSDF &&)=default
Move constructor.
CylinderSDF & operator=(CylinderSDF &&)=default
Move assignment.
CylinderSDF & operator=(const CylinderSDF &)=default
Copy assignment.
Signed distance field for an infinite cone.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1020
InfiniteConeSDF(const InfiniteConeSDF &)=default
Copy constructor.
InfiniteConeSDF()=default
Default constructor. Constructs an infinite cone with tip at the origin, 45° full opening angle,...
Vec3T< T > m_tip
Tip position.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1105
Vec2T< T > m_c
(sin, cos) of the half opening-angle. Default: 45° full angle → half-angle 22.5°.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1110
InfiniteConeSDF(const Vec3T< T > &a_tip, const T &a_angle) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1036
InfiniteConeSDF(InfiniteConeSDF &&)=default
Move constructor.
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the infinite cone.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1085
~InfiniteConeSDF() override=default
Destructor.
InfiniteConeSDF & operator=(InfiniteConeSDF &&)=default
Move assignment.
InfiniteConeSDF & operator=(const InfiniteConeSDF &)=default
Copy assignment.
Signed distance field for an infinitely long cylinder.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:779
T m_radius
Cylinder radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:867
InfiniteCylinderSDF & operator=(const InfiniteCylinderSDF &)=default
Copy assignment.
InfiniteCylinderSDF(const Vec3T< T > &a_center, const T &a_radius, const size_t a_axis) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:795
InfiniteCylinderSDF(const InfiniteCylinderSDF &)=default
Copy constructor.
Vec3T< T > m_center
Center point on the cylinder axis.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:862
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the infinite cylinder.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:844
InfiniteCylinderSDF(InfiniteCylinderSDF &&)=default
Move constructor.
InfiniteCylinderSDF()=default
Default constructor. Constructs an infinite cylinder of radius 1 centred at the origin with its axis ...
size_t m_axis
Coordinate axis index (0 = x, 1 = y, 2 = z).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:872
~InfiniteCylinderSDF() override=default
Destructor.
InfiniteCylinderSDF & operator=(InfiniteCylinderSDF &&)=default
Move assignment.
Ken Perlin's gradient-noise implicit function.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1360
PerlinSDF(const T a_noiseAmplitude, const Vec3T< T > a_noiseFrequency, const T a_noisePersistence, const unsigned int a_noiseOctaves) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1377
unsigned int m_noiseOctaves
Number of noise octaves.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1542
PerlinSDF()=default
Default constructor. Constructs a single-octave Perlin noise field with unit amplitude,...
Vec3T< T > m_noiseFrequency
Spatial noise frequency along each Cartesian axis.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1520
PerlinSDF & operator=(const PerlinSDF &)=default
Copy assignment.
PerlinSDF(const PerlinSDF &)=default
Copy constructor.
std::array< int, 512 > & getPermutationTable() noexcept
Get the internal permutation table.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1491
static constexpr std::array< int, 256 > s_perlinPermutationTable
Ken Perlin's original 256-entry permutation table.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1503
T noise(const Vec3T< T > &a_point) const noexcept
Single-octave Perlin noise evaluation.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1591
T grad(const int hash, const T x, const T y, const T z) const noexcept
Ken Perlin's gradient hash function.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1577
PerlinSDF(PerlinSDF &&)=default
Move constructor.
std::array< int, 512 > m_permutationTable
Integer hash permutation table (512 entries: [0..255] mirrored).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1537
PerlinSDF & operator=(PerlinSDF &&)=default
Move assignment.
virtual T fade(const T t) const noexcept
Ken Perlin's fade (smoothstep) function: 6t^5 - 15t^4 + 10t^3.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1563
~PerlinSDF() override=default
Destructor.
T m_noiseAmplitude
Noise amplitude (output scale).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1525
T m_noisePersistence
Per-octave amplitude decay factor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1530
virtual T lerp(const T t, const T a, const T b) const noexcept
Ken Perlin's linear interpolation helper.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1552
void shuffle(URNG &g) noexcept
Shuffle the permutation table with the provided uniform random number generator.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1472
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function. Generates a noise value on [0, m_noiseAmplitude].
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1437
Signed distance function for a plane.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:43
PlaneSDF()=default
Default constructor. Constructs the y = 0 plane with outward normal (0, 1, 0).
PlaneSDF(const Vec3T< T > &a_point, const Vec3T< T > &a_normal) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:59
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the plane.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:108
~PlaneSDF() override=default
Destructor.
PlaneSDF(const PlaneSDF &)=default
Copy constructor.
PlaneSDF & operator=(PlaneSDF &&)=default
Move assignment.
PlaneSDF(PlaneSDF &&)=default
Move constructor.
Vec3T< T > m_point
Point on plane.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:122
Vec3T< T > m_normal
Plane normal vector (unit length).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:127
PlaneSDF & operator=(const PlaneSDF &)=default
Copy assignment.
Signed distance field for an axis-aligned box with rounded corners.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1253
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the rounded box.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1320
RoundedBoxSDF()=default
Default constructor. Constructs a rounded unit cube centered at the origin ([-0.5,...
RoundedBoxSDF(const Vec3T< T > &a_dimensions, const T a_curvature) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1270
RoundedBoxSDF & operator=(RoundedBoxSDF &&)=default
Move assignment.
~RoundedBoxSDF() override=default
Destructor.
RoundedBoxSDF(const RoundedBoxSDF &)=default
Copy constructor. Shares the internal sphere object.
Vec3T< T > m_dimensions
Half-extents of the inner box (= 0.5 * the user-supplied dimensions).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1338
std::shared_ptr< SphereSDF< T > > m_sphere
Sphere of radius = curvature used to round the corners.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1333
RoundedBoxSDF(RoundedBoxSDF &&)=default
Move constructor.
RoundedBoxSDF & operator=(const RoundedBoxSDF &)=default
Copy assignment. Shares the internal sphere object.
Signed distance field for a cylinder with rounded (toroidal) edges.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1654
RoundedCylinderSDF(RoundedCylinderSDF &&)=default
Move constructor.
RoundedCylinderSDF(const T a_radius, const T a_curvature, const T a_height) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1671
RoundedCylinderSDF & operator=(RoundedCylinderSDF &&)=default
Move assignment.
RoundedCylinderSDF(const RoundedCylinderSDF &)=default
Copy constructor.
T m_height
Inner half-height (= 0.5*height - curvature).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1749
RoundedCylinderSDF & operator=(const RoundedCylinderSDF &)=default
Copy assignment.
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the rounded cylinder.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1722
T m_majorRadius
Inner cylinder radius (= outer radius - curvature).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1739
T m_minorRadius
Edge rounding radius (= curvature).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:1744
RoundedCylinderSDF()=default
Default constructor. Constructs a rounded cylinder centred at the origin, axis along y,...
~RoundedCylinderSDF() override=default
Destructor.
Abstract representation of a signed distance function.
Definition EBGeometry_SignedDistanceFunction.hpp:34
Signed distance field for a sphere.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:139
Vec3T< T > & getCenter() noexcept
Get sphere center (mutable).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:209
SphereSDF()=default
Default constructor. Constructs a unit sphere centered at the origin.
~SphereSDF() override=default
Destructor.
SphereSDF & operator=(SphereSDF &&)=default
Move assignment.
SphereSDF & operator=(const SphereSDF &)=default
Copy assignment.
const Vec3T< T > & getCenter() const noexcept
Get sphere center (const).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:199
Vec3T< T > m_center
Sphere center.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:253
T m_radius
Sphere radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:258
const T & getRadius() const noexcept
Get sphere radius (const).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:219
SphereSDF(SphereSDF &&)=default
Move constructor.
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the sphere.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:240
SphereSDF(const SphereSDF &)=default
Copy constructor.
T & getRadius() noexcept
Get sphere radius (mutable).
Definition EBGeometry_AnalyticDistanceFunctions.hpp:229
SphereSDF(const Vec3T< T > &a_center, const T &a_radius) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:153
Signed distance field for a torus.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:426
TorusSDF & operator=(const TorusSDF &)=default
Copy assignment.
T m_minorRadius
Minor (tube) radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:578
Vec3T< T > & getCenter() noexcept
Get torus center.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:501
T m_majorRadius
Major (ring) radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:573
TorusSDF(const Vec3T< T > &a_center, const T &a_majorRadius, const T &a_minorRadius) noexcept
Full constructor.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:441
const T & getMinorRadius() const noexcept
Get minor radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:531
TorusSDF(TorusSDF &&)=default
Move constructor.
TorusSDF(const TorusSDF &)=default
Copy constructor.
~TorusSDF() override=default
Destructor.
const T & getMajorRadius() const noexcept
Get major radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:511
T & getMajorRadius() noexcept
Get major radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:521
Vec3T< T > m_center
Torus center.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:568
T signedDistance(const Vec3T< T > &a_point) const noexcept override
Signed distance function for the torus.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:551
TorusSDF & operator=(TorusSDF &&)=default
Move assignment.
T & getMinorRadius() noexcept
Get minor radius.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:541
TorusSDF()=default
Default constructor. Constructs a torus centered at the origin with major radius 1 and minor radius 0...
const Vec3T< T > & getCenter() const noexcept
Get torus center.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:491
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:225
constexpr T length() const noexcept
Compute vector length.
size_t maxDir(const bool a_doAbs) const noexcept
Return the direction which has the largest component (can be absolute)
static constexpr Vec3T< T > zeros() noexcept
Return a vector with x = y = z = 0.
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_AnalyticDistanceFunctions.hpp:31
constexpr Vec3T< T > clamp(const Vec3T< T > &v, const Vec3T< T > &lo, const Vec3T< T > &hi) noexcept
Component-wise clamp of a 3D vector.
T length(const Vec2T< T > &v) noexcept
Euclidean length of a 2D vector.
T dot(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Dot product of two 2D vectors.
Vec2T< T > max(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Component-wise maximum of two vectors.