Browse Source

simplex: some refactoring and comments, but no changes to the algorithm.

undefined
Sam Hocevar 10 years ago
parent
commit
ce75538bcb
1 changed files with 36 additions and 38 deletions
  1. +36
    -38
      src/lol/math/simplex_interpolator.h

+ 36
- 38
src/lol/math/simplex_interpolator.h View File

@@ -43,40 +43,41 @@ public:
vec_t<float, N> simplex_position = m_base_inverse * position;

// Retrieving the closest floor point and decimals
vec_t<int, N> floor_point;
vec_t<float, N> decimal_point;
vec_t<int, N> origin;
vec_t<float, N> pos;

this->ExtractFloorDecimal(simplex_position, floor_point, decimal_point);
this->ExtractFloorDecimal(simplex_position, origin, pos);

vec_t<int, N> index_order = this->GetIndexOrder(decimal_point);
vec_t<int, N> index_order = this->GetIndexOrder(pos);

// Resetting decimal point in regular orthonormal coordinates
//decimal_point = m_base * decimal_point;
// pos = m_base * pos;

return this->LastInterp(floor_point, decimal_point, index_order);
return this->LastInterp(origin, pos, index_order);
}

protected:

inline float LastInterp(vec_t<int, N> & floor_point,
vec_t<float, N> const & decimal_point,
vec_t<int, N> index_order) const
inline float LastInterp(vec_t<int, N> & origin,
vec_t<float, N> const & pos,
vec_t<int, N> index_order) const
{
vec_t<float, N> point_of_interest(0);
// “corner” will traverse the simplex along its edges
vec_t<float, N> corner(0);
float result = 0;

for (int i = 0 ; i < N+1 ; ++i)
for (int i = 0; i < N + 1; ++i)
{
float dist = 0.5 - 0.75f * sqlength(this->m_base * (decimal_point - point_of_interest));
vec_t<float, N> gradient = this->m_gradients[floor_point];
float dist = 0.5f - 0.75f * sqlength(this->m_base * (pos - corner));
vec_t<float, N> const &gradient = this->m_gradients[origin];

if (dist > 0)
result += dist * dist * dist * dist * dot(gradient, this->m_base * (decimal_point - point_of_interest));
result += dist * dist * dist * dist * dot(gradient, this->m_base * (pos - corner));

if (i < N)
{
point_of_interest[index_order[i]] += 1;
floor_point[index_order[i]] = this->Mod(floor_point[index_order[i]] + 1, index_order[i]);
corner[index_order[i]] += 1;
origin[index_order[i]] = this->Mod(origin[index_order[i]] + 1, index_order[i]);
}
}

@@ -85,25 +86,19 @@ protected:
return result * 100;
}

inline vec_t<int, N> GetIndexOrder(vec_t<float, N> const & decimal_point) const
/* For a given position [0…1]^n inside a square/cube/hypercube etc.,
* find the simplex which contains that position, and return the path
* from (0,0,…,0) to (1,1,…,1) that describes that simplex. */
inline vec_t<int, N> GetIndexOrder(vec_t<float, N> const & pos) const
{
vec_t<int, N> result;
for (int i = 0 ; i < N ; ++i)
for (int i = 0; i < N; ++i)
result[i] = i;

for (int i = 0 ; i < N ; ++i)
{
for (int j = i + 1 ; j < N ; ++j)
{
if (decimal_point[result[i]] < decimal_point[result[j]])
{
// just swapping…
result[i] ^= result[j];
result[j] ^= result[i];
result[i] ^= result[j];
}
}
}
for (int i = 0; i < N; ++i)
for (int j = i + 1; j < N; ++j)
if (pos[result[i]] < pos[result[j]])
std::swap(result[i], result[j]);

return result;
}
@@ -115,19 +110,22 @@ protected:
return ret >= 0 ? ret : ret + dim;
}

inline void ExtractFloorDecimal(vec_t<float, N> const & simplex_position, vec_t<int, N> & floor_point, vec_t<float, N> & decimal_point) const
/* For a given world position, extract grid coordinates (origin) and
* the corresponding delta position (pos). */
inline void ExtractFloorDecimal(vec_t<float, N> const & simplex_position,
vec_t<int, N> & origin,
vec_t<float, N> & pos) const
{
// Finding floor point index
for (int i = 0 ; i < N ; ++i)
floor_point[i] = ((int) simplex_position[i]) - (simplex_position[i] < 0 ? 1 : 0);
for (int i = 0; i < N; ++i)
origin[i] = ((int) simplex_position[i]) - (simplex_position[i] < 0 ? 1 : 0);

// Extracting decimal part from simplex sample
for (int i = 0 ; i < N ; ++i)
decimal_point[i] = simplex_position[i] - floor_point[i];
pos = simplex_position - (vec_t<float, N>)origin;

// Never exceed the size of the gradients and loop on it
for (int i = 0 ; i < N ; ++i)
floor_point[i] = this->Mod(floor_point[i], i);
for (int i = 0; i < N; ++i)
origin[i] = this->Mod(origin[i], i);
}

inline void InitBase()


Loading…
Cancel
Save