MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TendencyFactories.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Tendency.hpp"
4
5namespace MayaFlux::Kinesis {
6
7// =========================================================================
8// Constant
9// =========================================================================
10
11/**
12 * @brief Tendency returning a fixed value regardless of input
13 * @tparam D Domain type
14 * @tparam R Range type
15 * @param value Constant output value
16 * @return Tendency that always returns value
17 */
18template <typename D, typename R>
20{
21 return { .fn = [value](const D&) -> R { return value; } };
22}
23
24// =========================================================================
25// Distance
26// =========================================================================
27
28/**
29 * @enum DistanceMetric
30 * @brief Distance computation strategy for spatial queries
31 */
32enum class DistanceMetric : uint8_t {
37};
38
39/**
40 * @brief Normalized distance from an anchor point using the specified metric
41 * @param anchor Reference point
42 * @param radius Normalizing distance (output is 1.0 at this distance)
43 * @param metric Distance computation strategy
44 * @return SpatialField: glm::vec3 -> float
45 *
46 * Returns raw normalized distance. Compose with transfer_curve, smoothstep,
47 * sigmoid, or any ScalarField via chain() to shape the result.
48 */
50 const glm::vec3& anchor,
51 float radius,
53{
54 switch (metric) {
56 return { .fn = [anchor, radius](const glm::vec3& p) -> float {
57 return glm::length(p - anchor) / radius;
58 } };
60 float r_sq = radius * radius;
61 return { .fn = [anchor, r_sq](const glm::vec3& p) -> float {
62 glm::vec3 d = p - anchor;
63 return glm::dot(d, d) / r_sq;
64 } };
65 }
67 return { .fn = [anchor, radius](const glm::vec3& p) -> float {
68 glm::vec3 d = glm::abs(p - anchor);
69 return (d.x + d.y + d.z) / radius;
70 } };
72 return { .fn = [anchor, radius](const glm::vec3& p) -> float {
73 glm::vec3 d = glm::abs(p - anchor);
74 return std::max({ d.x, d.y, d.z }) / radius;
75 } };
76 }
77 return { .fn = [anchor, radius](const glm::vec3& p) -> float {
78 return glm::length(p - anchor) / radius;
79 } };
80}
81
82// =========================================================================
83// Scalar transfer functions
84// =========================================================================
85
86/**
87 * @brief Transfer curve from polynomial coefficients (highest power first)
88 * @param coefficients Coefficient vector, e.g. {1, 0, -1} evaluates as x^2 - 1
89 * @return ScalarField: float -> float
90 *
91 * Distinct from the Polynomial node which is a stateful, buffer-aware
92 * processor in the signal graph. This is a pure stateless evaluation.
93 */
94inline ScalarField transfer_curve(const std::vector<float>& coefficients)
95{
96 return { .fn = [coefficients](const float& x) -> float {
97 float result = 0.0F;
98 float power = 1.0F;
99
100 for (float coefficient : std::views::reverse(coefficients)) {
101 result += coefficient * power;
102 power *= x;
103 }
104 return result;
105 } };
106}
107
108/**
109 * @brief Smoothstep: cubic Hermite interpolation between two edges
110 * @param edge0 Lower edge (output 0.0 at and below)
111 * @param edge1 Upper edge (output 1.0 at and above)
112 * @return ScalarField: float -> float
113 */
114inline ScalarField smoothstep(float edge0, float edge1)
115{
116 return { .fn = [edge0, edge1](const float& x) -> float {
117 float t = std::clamp((x - edge0) / (edge1 - edge0), 0.0F, 1.0F);
118 return t * t * (3.0F - 2.0F * t);
119 } };
120}
121
122/**
123 * @brief Sigmoid: 1 / (1 + e^(-k * (x - midpoint)))
124 * @param k Steepness
125 * @param midpoint Centre of the transition
126 * @return ScalarField: float -> float
127 */
128inline ScalarField sigmoid(float k, float midpoint = 0.0F)
129{
130 return { .fn = [k, midpoint](const float& x) -> float {
131 return 1.0F / (1.0F + std::exp(-k * (x - midpoint)));
132 } };
133}
134
135} // namespace MayaFlux::Kinesis
Range radius
ScalarField transfer_curve(const std::vector< float > &coefficients)
Transfer curve from polynomial coefficients (highest power first)
ScalarField smoothstep(float edge0, float edge1)
Smoothstep: cubic Hermite interpolation between two edges.
ScalarField sigmoid(float k, float midpoint=0.0F)
Sigmoid: 1 / (1 + e^(-k * (x - midpoint)))
DistanceMetric
Distance computation strategy for spatial queries.
SpatialField distance(const glm::vec3 &anchor, float radius, DistanceMetric metric=DistanceMetric::EUCLIDEAN)
Normalized distance from an anchor point using the specified metric.
Tendency< D, R > constant(R value)
Tendency returning a fixed value regardless of input.
std::function< R(const D &)> fn
Definition Tendency.hpp:23
Typed, composable, stateless callable from domain D to range R.
Definition Tendency.hpp:22