Update to HaltonSequence to make it easier to fill your own custom structures with halton sequences.

This commit is contained in:
pruiksma
2021-05-25 21:34:53 -05:00
parent 29163fba1a
commit ab84a43a83
2 changed files with 56 additions and 11 deletions
+12 -7
View File
@@ -127,16 +127,13 @@ namespace AZ
m_increments.fill(1); // By default increment by 1 between each number.
}
//! Returns a Halton sequence in an array of N length
template<uint32_t N>
AZStd::array<AZStd::array<float, Dimensions>, N> GetHaltonSequence()
template<class Iterator>
void FillHaltonSequence(Iterator begin, Iterator end)
{
AZStd::array<AZStd::array<float, Dimensions>, N> result;
AZStd::array<uint32_t, Dimensions> indices = m_offsets;
// Generator that returns the Halton number for all bases for a single entry.
auto f = [&] ()
auto f = [&]()
{
AZStd::array<float, Dimensions> item;
for (auto d = 0; d < Dimensions; ++d)
@@ -147,7 +144,15 @@ namespace AZ
return item;
};
AZStd::generate(result.begin(), result.end(), f);
AZStd::generate(begin, end, f);
}
//! Returns a Halton sequence in an array of N length
template<uint32_t N>
AZStd::array<AZStd::array<float, Dimensions>, N> GetHaltonSequence()
{
AZStd::array<AZStd::array<float, Dimensions>, N> result;
FillHaltonSequence(result.begin(), result.end());
return result;
}
@@ -24,7 +24,7 @@ namespace UnitTest
EXPECT_FLOAT_EQ(5981.0f / 15625.0f, GetHaltonNumber(4321, 5));
}
TEST(MATH_Random, HaltonSequence)
TEST(MATH_Random, HaltonSequenceStandard)
{
HaltonSequence<3> sequence({ 2, 3, 5 });
auto regularSequence = sequence.GetHaltonSequence<5>();
@@ -48,7 +48,11 @@ namespace UnitTest
EXPECT_FLOAT_EQ(5.0f / 8.0f, regularSequence[4][0]);
EXPECT_FLOAT_EQ(7.0f / 9.0f, regularSequence[4][1]);
EXPECT_FLOAT_EQ(1.0f / 25.0f, regularSequence[4][2]);
}
TEST(MATH_Random, HaltonSequenceOffsets)
{
HaltonSequence<3> sequence({ 2, 3, 5 });
sequence.SetOffsets({ 1, 2, 3 });
auto offsetSequence = sequence.GetHaltonSequence<2>();
@@ -59,10 +63,15 @@ namespace UnitTest
EXPECT_FLOAT_EQ(3.0f / 4.0f, offsetSequence[1][0]);
EXPECT_FLOAT_EQ(4.0f / 9.0f, offsetSequence[1][1]);
EXPECT_FLOAT_EQ(1.0f / 25.0f, offsetSequence[1][2]);
}
TEST(MATH_Random, HaltonSequenceIncrements)
{
HaltonSequence<3> sequence({ 2, 3, 5 });
sequence.SetOffsets({ 1, 2, 3 });
sequence.SetIncrements({ 1, 2, 3 });
auto incrementedSequence = sequence.GetHaltonSequence<2>();
EXPECT_FLOAT_EQ(1.0f / 4.0f, incrementedSequence[0][0]);
EXPECT_FLOAT_EQ(1.0f / 9.0f, incrementedSequence[0][1]);
EXPECT_FLOAT_EQ(4.0f / 5.0f, incrementedSequence[0][2]);
@@ -71,4 +80,35 @@ namespace UnitTest
EXPECT_FLOAT_EQ(7.0f / 9.0f, incrementedSequence[1][1]);
EXPECT_FLOAT_EQ(11.0f / 25.0f, incrementedSequence[1][2]);
}
TEST(MATH_Random, FillHaltonSequence)
{
HaltonSequence<3> sequence({ 2, 3, 5 });
auto regularSequence = sequence.GetHaltonSequence<5>();
struct Point
{
Point() = default;
Point(AZStd::array<float, 3> arr)
:x(arr[0])
,y(arr[1])
,z(arr[2])
{}
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
};
AZStd::array<Point, 5> ownedContainer;
sequence.FillHaltonSequence(ownedContainer.begin(), ownedContainer.end());
for (uint32_t i = 0; i < regularSequence.size(); ++i)
{
EXPECT_FLOAT_EQ(regularSequence[i][0], ownedContainer[i].x);
EXPECT_FLOAT_EQ(regularSequence[i][1], ownedContainer[i].y);
EXPECT_FLOAT_EQ(regularSequence[i][2], ownedContainer[i].z);
}
}
}