Honeycomb  0.1
Component-Model Framework
Interp.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Math/Alge/Trig.h"
6 
7 namespace honey
8 {
9 
11 template<class Real>
12 class Interp_ : mt::NoCopy
13 {
14  typedef typename Numeral<Real>::Real_ Real_;
15  typedef Alge_<Real> Alge;
16  typedef Trig_<Real> Trig;
17  typedef Vec<2,Real> Vec2;
18  typedef Vec<3,Real> Vec3;
19  typedef Vec<4,Real> Vec4;
20  typedef Quat_<Real> Quat;
21  typedef Matrix<4,4,Real> Matrix4;
22  typedef Transform_<Real> Transform;
23 
24 public:
25 
27  template<class T>
28  static T linear(Real t, const T& a, const T& b) { return a + t*(b-a); }
29  static Quat linear(Real t, const Quat& a, const Quat& b) { return Quat::slerp(t, a, b); }
30 
31  static Transform linear(Real t, const Transform& a, const Transform& b)
32  {
33  if (t <= 0)
34  return a;
35  if (t >= 1)
36  return b;
37 
38  return Transform(
39  linear(t, a.getTrans(), b.getTrans()),
40  (a.hasRot() || b.hasRot()) ? linear(t, a.getRot(), b.getRot()) : a.getRot(),
41  (a.hasScale() || b.hasScale()) ? linear(t, a.getScale(), b.getScale()) : a.getScale(),
42  (a.hasSkew() || b.hasSkew()) ? linear(t, a.getSkew(), b.getSkew()) : a.getSkew()
43  );
44  }
45 
47  static Real linearAngle(Real t, Real angleStart, Real angleEnd, optional<int&> rotSign = optnull);
48 
50  static void alignDir(Vec3& dir, const Vec3& targetDir, Real angleAmount, optional<int&> rotSign = optnull);
51 
53 
59  template<class T>
60  static T baryCentric(Real f, Real g, const T& x0, const T& x1, const T& x2)
61  {
62  return (1-f-g)*x0 + f*x1 + g*x2;
63  }
64 
65  static Quat baryCentric(Real f, Real g, const Quat& q0, const Quat& q1, const Quat& q2)
66  {
67  return Quat::baryCentric(f, g, q0, q1, q2);
68  }
69 
70  static Transform baryCentric(Real f, Real g, const Transform& tm0, const Transform& tm1, const Transform& tm2)
71  {
72  Real t = f+g;
73  return t != 0 ? linear(g/t, linear(t, tm0, tm1), linear(t, tm0, tm2)) : tm0;
74  }
75 
77  template<class Range, class Seq>
78  static auto blend(Range&& vals, Seq&& weights_) -> mt_elemOf(vals)
79  {
80  auto val = begin(vals), last = end(vals);
81  auto weights = seqToIter(weights_);
82  //Get first non-zero weight, if not found then return first value
83  for (; val != last && *weights == 0; ++val, ++weights);
84  if (val == last) return *begin(vals);
85  //Blend the values
86  mt_elemOf(vals) ret(*val++);
87  Real weightAccum = *weights++;
88  for (; val != last; ++val, ++weights)
89  {
90  weightAccum += *weights;
91  Real weight = *weights / weightAccum;
92  ret = linear(weight, ret, *val);
93  }
94  return ret;
95  }
96 
98 
104  static Real sin(Real t, bool smoothIn, bool smoothOut)
105  {
106  if (smoothIn && smoothOut)
107  return 0.5 - (Trig::sin(Real_::piHalf + t*Real_::pi)/2);
108  else if (smoothIn)
109  return 1 - Trig::sin(Real_::piHalf + t*Real_::piHalf);
110  else
111  return Trig::sin(t*Real_::piHalf);
112  }
113 
114 
116  static Real gaussian(Real x, Real offset, Real scale)
117  {
118  static const Real sqrtTwoPi = Alge::sqrt(Real_::piTwo);
119  return Alge::exp( -Alge::sqr(x - offset) / (2 * Alge::sqr(scale)) ) / ( scale * sqrtTwoPi );
120  }
121 
123  template<class T>
124  static typename MatrixBase<T>::MatrixS gaussian(const MatrixBase<T>& x, const MatrixBase<T>& offset, const MatrixBase<T>& scale)
125  {
126  assert(x.size() == offset.size() && x.size() == scale.size());
127  return map(x, offset, scale, typename MatrixBase<T>::MatrixS().resize(x.rows(), x.cols()),
128  [](Real x, Real offset, Real scale) { return gaussian(x, offset, scale); });
129  }
130 
132 
140  template<class T>
141  static T bezier(Real t, const T& v0, const T& v1, const T& v2, const T& v3)
142  {
143  T c = 3 * (v1 - v0);
144  T b = 3 * (v2 - v1) - c;
145  T a = v3 - v0 - c - b;
146  Real tSqr = t * t;
147  Real tCube = tSqr * t;
148  return (a * tCube) + (b * tSqr) + (c * t) + v0;
149  }
150 
152 
156  static tuple<Vec3, int> bezierRoots(Real y, Real v0, Real v1, Real v2, Real v3);
157 
159  static tuple<Vec2, Vec2> bezierNormalizeHandles(const Vec2& v0, const Vec2& v1, const Vec2& v2, const Vec2& v3);
160 
162  static Real bezierAtTime(Real time, const Vec2& v0, const Vec2& v1, const Vec2& v2, const Vec2& v3);
163 
165  static Real bezierAngleAtTime(Real time, const Vec2& v0, const Vec2& v1, const Vec2& v2, const Vec2& v3);
166 
168  static void bezierSubdiv(vector<Vec2>& cs, int index, Real t);
169 
171 
174  static Real bezierSubdivAdapt(vector<Vec2>& cs, int index, Real tol = 0.01);
175 
177 
182  static Matrix4 bezierPatchCoeff(const Matrix4& val)
183  {
184  // Bezier basis matrix
185  static const Matrix4 m(
186  -1, 3, -3, 1,
187  3, -6, 3, 0,
188  -3, 3, 0, 0,
189  1, 0, 0, 0
190  );
191  static const Matrix4 t = m.transpose();
192  return m * (val * t);
193  }
194 
196 
203  static Real bezierPatch(const Matrix4& coeff, Real x, Real y)
204  {
205  return x*( x*( x*(y * (y * (y * coeff( 0) + coeff( 1)) + coeff( 2)) + coeff( 3))
206  + (y * (y * (y * coeff( 4) + coeff( 5)) + coeff( 6)) + coeff( 7))
207  ) + (y * (y * (y * coeff( 8) + coeff( 9)) + coeff(10)) + coeff(11))
208  ) + (y * (y * (y * coeff(12) + coeff(13)) + coeff(14)) + coeff(15));
209  }
210 
211 
213 
221  template<class T>
222  static T catmull(Real t, const T& v0, const T& v1, const T& v2, const T& v3)
223  {
224  T c1 = -0.5*v0 + 0.5*v2 ;
225  T c2 = v0 + -2.5*v1 + 2*v2 + -0.5*v3 ;
226  T c3 = -0.5*v0 + 1.5*v1 + -1.5*v2 + 0.5*v3 ;
227  return (((c3*t + c2)*t +c1)*t + v1);
228  }
229 
231 
236  static Matrix4 catmullPatchCoeff(const Matrix4& val)
237  {
238  // Catmull-Rom basis matrix
239  static const Matrix4 m(
240  -0.5, 1.5, -1.5, 0.5,
241  1, -2.5, 2, -0.5,
242  -0.5, 0, 0.5, 0,
243  0, 1, 0, 0
244  );
245  static const Matrix4 t = m.transpose();
246 
247  return m * (val * t);
248  }
249 
251 
258  static Real catmullPatch(const Matrix4& coeff, Real x, Real y)
259  {
260  return x*( x*( x*(y * (y * (y * coeff( 0) + coeff( 1)) + coeff( 2)) + coeff( 3))
261  + (y * (y * (y * coeff( 4) + coeff( 5)) + coeff( 6)) + coeff( 7))
262  ) + (y * (y * (y * coeff( 8) + coeff( 9)) + coeff(10)) + coeff(11))
263  ) + (y * (y * (y * coeff(12) + coeff(13)) + coeff(14)) + coeff(15));
264  }
265 
266 };
267 
271 
272 extern template class Interp_<Float>;
273 extern template class Interp_<Double>;
274 extern template class Interp_<Quad>;
275 
276 }
277 
const Quat & getSkew() const
Definition: Transform.h:174
static void alignDir(Vec3 &dir, const Vec3 &targetDir, Real angleAmount, optional< int & > rotSign=optnull)
Align a normalized direction towards a target direction, rotating around the Y axis, stepping angleAmount. rotSign is the direction rotated: (-ve, +ve, none) = (-1,1,0)
Definition: Interp.cpp:76
bool hasRot() const
Definition: Transform.h:207
static Quat baryCentric(Real f, Real g, const Quat &q0, const Quat &q1, const Quat &q2)
Definition: Interp.h:65
static Matrix4 catmullPatchCoeff(const Matrix4 &val)
Catmull-rom 2D patch coefficient matrix generator.
Definition: Interp.h:236
Subclass MatrixS
Definition: Base.h:22
Interp_< Float > Interp_f
Definition: Interp.h:269
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
const Vec3 & getScale() const
Definition: Transform.h:173
static Real linearAngle(Real t, Real angleStart, Real angleEnd, optional< int & > rotSign=optnull)
Linearly interpolate angles along the shortest path. Angles must be normalized. t range is [0...
Definition: Interp.cpp:10
static Real sin(Real x)
Sin of radian angle.
Definition: Trig.h:62
static Real bezierAtTime(Real time, const Vec2 &v0, const Vec2 &v1, const Vec2 &v2, const Vec2 &v3)
Given a bezier curve with dim (time, value), get value on curve parameterized by time in range [0...
Definition: Interp.cpp:138
static Real sin(Real t, bool smoothIn, bool smoothOut)
Sin interpolation.
Definition: Interp.h:104
static Matrix4 bezierPatchCoeff(const Matrix4 &val)
Bezier 2D patch coefficient matrix generator.
Definition: Interp.h:182
static MatrixBase< T >::MatrixS gaussian(const MatrixBase< T > &x, const MatrixBase< T > &offset, const MatrixBase< T > &scale)
Perform gaussian for each element.
Definition: Interp.h:124
Interpolation math.
Definition: Quat.h:10
static Transform baryCentric(Real f, Real g, const Transform &tm0, const Transform &tm1, const Transform &tm2)
Definition: Interp.h:70
static auto blend(Range &&vals, Seq &&weights_) -> mt_elemOf(vals)
Linearly blend a range of values by applying an associated weight to each value. If all weights are 0...
Definition: Interp.h:78
static T catmull(Real t, const T &v0, const T &v1, const T &v2, const T &v3)
Interpolate along a Catmull-Rom curve passing through v1 and v2, using handles (control points) v0 an...
Definition: Interp.h:222
static Real exp(Real x)
Euler's number e raised to exponent x (e^x)
Definition: Alge.h:68
static Real bezierSubdivAdapt(vector< Vec2 > &cs, int index, Real tol=0.01)
Adaptively subdivide a bezier curve segment at index (4 control points). Subdivides curve segment unt...
Definition: Interp.cpp:182
static Real sqrt(Real x)
Square Root.
Definition: Alge.h:63
#define mt_elemOf(Range)
elemOf for values
Definition: Range.h:43
static Real gaussian(Real x, Real offset, Real scale)
Gaussian / Normal distribution. The standard distribution parameters are (offset, scale) = (0...
Definition: Interp.h:116
Interp_< Real > Interp
Definition: Interp.h:268
const Quat & getRot() const
Definition: Transform.h:159
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
bool hasSkew() const
Definition: Transform.h:210
static Transform linear(Real t, const Transform &a, const Transform &b)
Definition: Interp.h:31
static tuple< Vec3, int > bezierRoots(Real y, Real v0, Real v1, Real v2, Real v3)
Find roots of bezier function at y-intercept y
Definition: Interp.cpp:93
static Real bezierAngleAtTime(Real time, const Vec2 &v0, const Vec2 &v1, const Vec2 &v2, const Vec2 &v3)
Similar to bezierAtTime() except the value is interpolated by taking the shortest angular path...
Definition: Interp.cpp:148
static tuple< Vec2, Vec2 > bezierNormalizeHandles(const Vec2 &v0, const Vec2 &v1, const Vec2 &v2, const Vec2 &v3)
Given a bezier curve with dim (time, value), normalize the handles (v1,v2) such that there is only 1 ...
Definition: Interp.cpp:119
static Real catmullPatch(const Matrix4 &coeff, Real x, Real y)
Catmull-rom 2D patch interpolation.
Definition: Interp.h:258
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
static Quat linear(Real t, const Quat &a, const Quat &b)
Definition: Interp.h:29
Numeral< Real >::Real_ Real_
Operations and constants for Real type. See Float_, Double_.
Definition: Real.h:25
static T linear(Real t, const T &a, const T &b)
Linear interpolation. t range is [0,1].
Definition: Interp.h:28
static Num sqr(Num x)
Square.
Definition: Alge.h:60
const Vec3 & getTrans() const
Definition: Transform.h:150
static void bezierSubdiv(vector< Vec2 > &cs, int index, Real t)
Subdivide a bezier curve segment at index (4 control points) by curve param 't' [0,1]. Replaces curve segment with equivalent left/right segments (7 control points)
Definition: Interp.cpp:160
static T baryCentric(Real f, Real g, const T &x0, const T &x1, const T &x2)
Triangular bary-centric interpolation.
Definition: Interp.h:60
bool hasScale() const
Definition: Transform.h:208
auto seqToIter(Iter &&seq) -> typename std::enable_if< mt::isIterator< Iter >::value, Iter && >::type
Convert a sequence to a forward iterator. Overload for iterator type. Returns the iterator itself...
Definition: Range.h:79
static T bezier(Real t, const T &v0, const T &v1, const T &v2, const T &v3)
Interpolate along a Bezier curve passing through v0 and v3, using handles (control points) v1 and v2...
Definition: Interp.h:141
Matrix base class.
Definition: Base.h:17
Global Honeycomb namespace.
static Quat_ baryCentric(Real f, Real g, const Quat_ &q0, const Quat_ &q1, const Quat_ &q2)
Triangular bary-centric interpolation.
static Real bezierPatch(const Matrix4 &coeff, Real x, Real y)
Bezier 2D patch interpolation.
Definition: Interp.h:203
Interp_< Double > Interp_d
Definition: Interp.h:270
static Quat_ slerp(Real t, const Quat_ &q0, const Quat_ &q1)
Spherical linear interpolation from q0 to q1. t ranges from [0,1].
Definition: Quat.h:262
Res && transpose(Res &&res) const
transpose and store result in res. Returns res.
Definition: Base.h:314
OutSeq && map(Range &&, Seqs &&..., OutSeq &&, Func &&)
Transform a series of sequences into an output.