5#ifndef PECLET_PNM_TESTS_SYNTHETIC_SDF_HPP
6#define PECLET_PNM_TESTS_SYNTHETIC_SDF_HPP
19 const float R = 0.22f * std::min(gd[0], std::min(gd[1], gd[2]));
21 for (
int cz = 0; cz < 2; ++cz)
22 for (
int cy = 0; cy < 2; ++cy)
23 for (
int cx = 0; cx < 2; ++cx) {
24 const float ccx = gd[0] * (2 * cx + 1) / 4.0f, ccy = gd[1] * (2 * cy + 1) / 4.0f,
25 ccz = gd[2] * (2 * cz + 1) / 4.0f;
26 float dx = std::fabs(gx - ccx), dy = std::fabs(gy - ccy), dz = std::fabs(gz - ccz);
27 dx = std::min(dx, gd[0] - dx);
28 dy = std::min(dy, gd[1] - dy);
29 dz = std::min(dz, gd[2] - dz);
30 best = std::min(best, std::sqrt(dx * dx + dy * dy + dz * dz) - R);
36inline float trigSdf(
int gx,
int gy,
int gz, std::array<int, 3> gd) {
37 const float x = 2.0f * float(M_PI) * gx / gd[0], y = 2.0f * float(M_PI) * gy / gd[1],
38 z = 2.0f * float(M_PI) * gz / gd[2];
39 return std::sin(x) * std::cos(y) + 0.7f * std::sin(2.0f * z) - 0.1f;
44inline float spherePoreSdf(
int gx,
int gy,
int gz, std::array<int, 3> c,
float radius) {
45 const float dx = float(gx - c[0]), dy = float(gy - c[1]), dz = float(gz - c[2]);
46 return radius - std::sqrt(dx * dx + dy * dy + dz * dz);
51inline float twoSpherePoresSdf(
int gx,
int gy,
int gz, std::array<int, 3> c1, std::array<int, 3> c2,
58std::vector<float>
sampleGrid(std::array<int, 3> gd,
const SdfFn& fn) {
59 std::vector<float> v(std::size_t(gd[0]) * gd[1] * gd[2]);
60 for (
int z = 0; z < gd[2]; ++z)
61 for (
int y = 0; y < gd[1]; ++y)
62 for (
int x = 0; x < gd[0]; ++x)
63 v[(std::size_t(z) * gd[1] + y) * gd[0] + x] = fn(x, y, z);
float sphereLatticeSdf(int gx, int gy, int gz, std::array< int, 3 > gd)
2x2x2 lattice of SOLID spheres in a periodic box (min-image distance); pores at the interstices.
std::vector< float > sampleGrid(std::array< int, 3 > gd, const SdfFn &fn)
Sample fn(gx, gy, gz) over the whole gd grid in pnm's flat x-fastest layout.
float trigSdf(int gx, int gy, int gz, std::array< int, 3 > gd)
Smooth trigonometric field with wrap-around components (exercises the periodic images).
float twoSpherePoresSdf(int gx, int gy, int gz, std::array< int, 3 > c1, std::array< int, 3 > c2, float radius)
Two overlapping spherical pores (the union = max of the two SDFs); a throat at the mid-plane when the...
float spherePoreSdf(int gx, int gy, int gz, std::array< int, 3 > c, float radius)
One spherical PORE (SDF > 0 inside) of radius radius centred on the integer voxel c; solid everywhere...