11#ifndef PECLET_CORE_GEOM_SDF_HPP
12#define PECLET_CORE_GEOM_SDF_HPP
23 return {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
26 return std::sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
43 Vec<3> q{std::fabs(d[0]) -
half[0], std::fabs(d[1]) -
half[1], std::fabs(d[2]) -
half[2]};
44 double outside =
detail::norm({std::max(q[0], 0.0), std::max(q[1], 0.0), std::max(q[2], 0.0)});
45 double inside = std::min(std::max(q[0], std::max(q[1], q[2])), 0.0);
46 return outside + inside;
61 int a0 = (
axis + 1) % 3, a1 = (
axis + 2) % 3;
62 double r = std::sqrt(d[a0] * d[a0] + d[a1] * d[a1]);
80 for (
int i = 0; i < 3; ++i) {
84 g[i] = (shape.eval(pp) - shape.eval(pm)) / (2.0 * h);
89#if defined(__cpp_concepts)
92concept Sdf =
requires(
const S s,
Vec<3> p) {
93 { s.eval(p) } -> std::convertible_to<double>;
double norm(const Vec< 3 > &a)
Vec< 3 > sub(const Vec< 3 > &a, const Vec< 3 > &b)
Vec< 3 > gradient(const S &shape, const Vec< 3 > &p, double h=1e-4)
Generic outward normal via central differences; works for any shape with eval().
std::array< Real, Dim > Vec
Multi-dimensional real vector.
Axis-aligned solid box of half-extents half: standard exact box SDF, negative inside.
double eval(const Vec< 3 > &p) const
Negation: the solid and the void swap (sdf -> -sdf).
double eval(const Vec< 3 > &p) const
Solid hollow cylinder (a tube wall) of given outer/inner radius and height about axis.
double eval(const Vec< 3 > &p) const
Solid ball: negative inside.
double eval(const Vec< 3 > &p) const