diff --git a/avogadro/core/neighborperceiver.cpp b/avogadro/core/neighborperceiver.cpp index d5ea7acdd9..fed8235c95 100644 --- a/avogadro/core/neighborperceiver.cpp +++ b/avogadro/core/neighborperceiver.cpp @@ -37,7 +37,7 @@ NeighborPerceiver::NeighborPerceiver(const Array points, float maxDista ); m_bins = bins; for (Index i = 0; i < points.size(); i++) { - std::array bin_index = getBinIndex(points[i]); + std::array bin_index = getBinIndex(points[i]); m_bins.at(bin_index[0]).at(bin_index[1]).at(bin_index[2]).push_back(i); } } @@ -45,12 +45,12 @@ NeighborPerceiver::NeighborPerceiver(const Array points, float maxDista const Array NeighborPerceiver::getNeighbors(const Vector3 point) const { Array r; - const std::array bin_index = getBinIndex(point); - for (size_t xi = std::max(size_t(1), bin_index[0]) - 1; + const std::array bin_index = getBinIndex(point); + for (int xi = std::max(int(1), bin_index[0]) - 1; xi < std::min(m_binCount[0], bin_index[0] + 2); xi++) { - for (size_t yi = std::max(size_t(1), bin_index[1]) - 1; + for (int yi = std::max(int(1), bin_index[1]) - 1; yi < std::min(m_binCount[1], bin_index[1] + 2); yi++) { - for (size_t zi = std::max(size_t(1), bin_index[2]) - 1; + for (int zi = std::max(int(1), bin_index[2]) - 1; zi < std::min(m_binCount[2], bin_index[2] + 2); zi++) { std::vector bin = m_bins[xi][yi][zi]; r.insert(r.end(), bin.begin(), bin.end()); @@ -60,9 +60,9 @@ const Array NeighborPerceiver::getNeighbors(const Vector3 point) const return r; } -const std::array NeighborPerceiver::getBinIndex(const Vector3 point) const +const std::array NeighborPerceiver::getBinIndex(const Vector3 point) const { - std::array r; + std::array r; for (size_t c = 0; c < 3; c++) { r[c] = std::floor((point(c) - m_minPos(c)) / m_maxDistance); } diff --git a/avogadro/core/neighborperceiver.h b/avogadro/core/neighborperceiver.h index 793a05e74e..d3c49980a7 100644 --- a/avogadro/core/neighborperceiver.h +++ b/avogadro/core/neighborperceiver.h @@ -43,10 +43,10 @@ class AVOGADROCORE_EXPORT NeighborPerceiver const Array getNeighbors(const Vector3 point) const; private: - const std::array getBinIndex(const Vector3 point) const; + const std::array getBinIndex(const Vector3 point) const; protected: float m_maxDistance; - std::array m_binCount; + std::array m_binCount; std::vector>>> m_bins; Vector3 m_minPos; Vector3 m_maxPos; diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index 210e5de771..cca39b6809 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -14,6 +14,7 @@ set(tests Mesh Molecule Mutex + NeighborPerceiver RingPerceiver Spacegroup Utilities diff --git a/tests/core/neighborperceivertest.cpp b/tests/core/neighborperceivertest.cpp new file mode 100644 index 0000000000..0bd28216e3 --- /dev/null +++ b/tests/core/neighborperceivertest.cpp @@ -0,0 +1,61 @@ +/****************************************************************************** + This source file is part of the Avogadro project. + This source code is released under the 3-Clause BSD License, (see "LICENSE"). +******************************************************************************/ + +#include + +#include +#include +#include + +using Avogadro::Core::Array; +using Avogadro::Core::NeighborPerceiver; +using Avogadro::Vector3; + +TEST(NeighborPerceiverTest, positive) +{ + Array points; + points.push_back(Vector3(0.0, 0.0, 0.0)); + points.push_back(Vector3(1.0, 0.0, 0.0)); + points.push_back(Vector3(0.0, 1.5, 1.5)); + points.push_back(Vector3(2.1, 0.0, 0.0)); + + NeighborPerceiver perceiver(points, 1.0f); + + auto neighbors = perceiver.getNeighbors(Vector3(0.0, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(3)); +} + +TEST(NeighborPerceiverTest, negative) +{ + Array points; + points.push_back(Vector3(0.0, 0.0, 0.0)); + points.push_back(Vector3(-1.0, 0.0, 0.0)); + points.push_back(Vector3(0.0, -1.5, -1.5)); + points.push_back(Vector3(-2.1, 0.0, 0.0)); + + NeighborPerceiver perceiver(points, 1.0f); + + auto neighbors = perceiver.getNeighbors(Vector3(0.0, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(3)); +} + +TEST(NeighborPerceiverTest, bounds) +{ + Array points; + points.push_back(Vector3(0.0, 0.0, 0.0)); + + NeighborPerceiver perceiver(points, 1.0f); + + auto neighbors = perceiver.getNeighbors(Vector3(0.0, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(1)); + neighbors = perceiver.getNeighbors(Vector3(1.5, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(1)); + neighbors = perceiver.getNeighbors(Vector3(2.5, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(0)); + neighbors = perceiver.getNeighbors(Vector3(-0.5, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(1)); + neighbors = perceiver.getNeighbors(Vector3(-1.5, 0.0, 0.0)); + EXPECT_EQ(neighbors.size(), static_cast(0)); +}