Browse Source

simplex_interpolator: sorting coordinates in regular basis + tests.

undefined
Guillaume Bittoun Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
6bd7142428
2 changed files with 69 additions and 39 deletions
  1. +23
    -38
      src/lol/math/simplex_interpolator.h
  2. +46
    -1
      src/t/math/simplex_interpolator.cpp

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

@@ -55,10 +55,10 @@ public:

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

// Retrieving simplex samples to use
int sign;
// Resetting decimal point in regular orthonormal coordinates
decimal_point = m_base * decimal_point;

this->GetReference(floor_point, decimal_point, sign);
vec_t<float, N> index_order = this->GetIndexOrder(decimal_point);

return this->LastInterp(floor_point, decimal_point, sign);
}
@@ -69,26 +69,31 @@ protected:
vec_t<float, N> const & decimal_point,
int const & sign) const
{
T result(0);
float floor_coeff = 0;
float divider = 0;
// There is still a lot of work to do…
return T();
}

inline vec_t<int, N> GetIndexOrder(vec_t<float, N> const & decimal_point)
{
vec_t<int, N> result;
for (int i = 0 ; i < N ; ++i)
{
vec_t<int, N> samples_index = floor_point;
samples_index[i] = this->Mod(samples_index[i] + sign, i);
result[i] = i;

result += decimal_point[i] * this->m_samples[samples_index];
floor_coeff += decimal_point[i];
divider += decimal_point[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];
}
}
}

float sqr_norm = N;

result += (1 - 2 * floor_coeff / sqr_norm) * this->m_samples[floor_point];
divider += (1 - 2 * floor_coeff / sqr_norm);

return result / divider;
return result;
}

inline int Mod(int value, int index) const
@@ -98,26 +103,6 @@ protected:
return ret >= 0 ? ret : ret + dim;
}

inline void GetReference(vec_t<int, N> & floor_point, vec_t<float, N> & decimal_point, int & sign) const
{
// Choosing the reference point which determines in which simplex we are working
// ie. (0, 0, 0, …) and upper or (1, 1, 1, …) and lower

float cumul = 0;
for (int i = 0 ; i < N ; ++i)
cumul += decimal_point[i];

if (cumul < (sqrt((float)N) / 2))
sign = 1;
else
{
sign = -1;

decimal_point = vec_t<float, N>(1) - decimal_point;
floor_point = floor_point + vec_t<int, N>(1);
}
}

inline void ExtractFloorDecimal(vec_t<float, N> const & simplex_position, vec_t<int, N> & floor_point, vec_t<float, N> & decimal_point) const
{
// Finding floor point index


+ 46
- 1
src/t/math/simplex_interpolator.cpp View File

@@ -88,6 +88,11 @@ public:
}
}
}

vec_t<int, N> GetIndexOrder(vec_t<float, N> const & decimal_point)
{
return simplex_interpolator<N, T>::GetIndexOrder(decimal_point);
}
};

lolunit_declare_fixture(SimplexInterpolatorTest)
@@ -137,7 +142,7 @@ lolunit_declare_fixture(SimplexInterpolatorTest)
lolunit_assert_doubles_equal(1, norm, 1e-6);
}

// Check result of vectors x, y z => must have norm = 1
// Check result of sum of base vectors => must have norm = 1
float vec_result[N];
for (int i = 0; i < N; ++i)
{
@@ -170,6 +175,46 @@ lolunit_declare_fixture(SimplexInterpolatorTest)
check_base_matrix<10>();
}

template<int N>
void check_index_ordering()
{
static int gen = 12345678;
test_interpolator<N> s;

vec_t<float, N> vec_ref;
for (int i = 0 ; i < N ; ++i)
vec_ref[i] = (gen = gen * gen + gen);

vec_t<int, N> result = s.GetIndexOrder(vec_ref);

for (int i = 1 ; i < N ; ++i)
lolunit_assert(vec_ref[result[i]] >= vec_ref[result[i-1]]);
}

lolunit_declare_test(IndexOrderTest)
{
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<1>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<2>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<3>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<4>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<5>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<6>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<7>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<8>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<9>();
for (int i = 1 ; i < 10 ; ++i)
check_index_ordering<10>();
}

#if 0
lolunit_declare_test(FloatGridPoints2D1x1)
{


Loading…
Cancel
Save