diff --git a/src/pe/ccd/HashGrids.cpp b/src/pe/ccd/HashGrids.cpp
index e126e554d56db11e2325c9d5ea8e7860c55ce2c4..b30a4d9dd89c42e7ed69ebe2481314a9f6db6612 100644
--- a/src/pe/ccd/HashGrids.cpp
+++ b/src/pe/ccd/HashGrids.cpp
@@ -326,14 +326,16 @@ void HashGrids::HashGrid::initializeNeighborOffsets()
  */
 size_t HashGrids::HashGrid::hash( BodyID body ) const
 {
-   real_t x = body->getAABB().xMin();
-   real_t y = body->getAABB().yMin();
-   real_t z = body->getAABB().zMin();
+   const AABB bodyAABB = body->getAABB();
+   return hashPoint(bodyAABB.xMin(), bodyAABB.yMin(), bodyAABB.zMin());
+}
+//*************************************************************************************************
 
+size_t HashGrids::HashGrid::hashPoint(real_t x, real_t y, real_t z) const {
    size_t xHash;
    size_t yHash;
    size_t zHash;
-
+   
    if( x < 0 ) {
       real_t i = ( -x ) * inverseCellSpan_;
       xHash  = xCellCount_ - 1 - ( static_cast<size_t>( i ) & xHashMask_ );
@@ -342,7 +344,7 @@ size_t HashGrids::HashGrid::hash( BodyID body ) const
       real_t i = x * inverseCellSpan_;
       xHash  = static_cast<size_t>( i ) & xHashMask_;
    }
-
+   
    if( y < 0 ) {
       real_t i = ( -y ) * inverseCellSpan_;
       yHash  = yCellCount_ - 1 - ( static_cast<size_t>( i ) & yHashMask_ );
@@ -351,7 +353,7 @@ size_t HashGrids::HashGrid::hash( BodyID body ) const
       real_t i = y * inverseCellSpan_;
       yHash  = static_cast<size_t>( i ) & yHashMask_;
    }
-
+   
    if( z < 0 ) {
       real_t i = ( -z ) * inverseCellSpan_;
       zHash  = zCellCount_ - 1 - ( static_cast<size_t>( i ) & zHashMask_ );
@@ -360,12 +362,60 @@ size_t HashGrids::HashGrid::hash( BodyID body ) const
       real_t i = z * inverseCellSpan_;
       zHash  = static_cast<size_t>( i ) & zHashMask_;
    }
-
+   
    return xHash + yHash * xCellCount_ + zHash * xyCellCount_;
 }
-//*************************************************************************************************
-
+   
+void HashGrids::HashGrid::possibleRayIntersectingBodies(const raytracing::Ray& ray, const AABB& blockAABB) const {
+   real_t halfCellSpan = getCellSpan() / real_t(2);
+      
+   for (int i = 0; i <= xCellCount_; i++) {
+      real_t xValue = blockAABB.minCorner()[0] + i*cellSpan_;
+      real_t lambda = (xValue - ray.getOrigin()[0]) * ray.getInvDirection()[0];
+      real_t yValue = ray.getOrigin()[1] + lambda * ray.getDirection()[1];
+      real_t zValue = ray.getOrigin()[2] + lambda * ray.getDirection()[2];
+      if (yValue > blockAABB.maxCorner()[1] || yValue < blockAABB.minCorner()[1] ||
+          zValue > blockAABB.maxCorner()[2] || zValue < blockAABB.minCorner()[2] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_x" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t arrayIndex = hashPoint(xValue + halfCellSpan, yValue, zValue);
+         WALBERLA_LOG_INFO("P_x" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+      }
+   }
+   
+   for (int i = 0; i < yCellCount_; i++) {
+      real_t yValue = blockAABB.minCorner()[1] + i*cellSpan_;
+      real_t lambda = (yValue - ray.getOrigin()[1]) * ray.getInvDirection()[1];
+      real_t xValue = ray.getOrigin()[0] + lambda * ray.getDirection()[0];
+      real_t zValue = ray.getOrigin()[2] + lambda * ray.getDirection()[2];
+      if (xValue > blockAABB.maxCorner()[0] || xValue < blockAABB.minCorner()[0] ||
+          zValue > blockAABB.maxCorner()[2] || zValue < blockAABB.minCorner()[2] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_y" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t arrayIndex = hashPoint(xValue, yValue + halfCellSpan, zValue);
+         WALBERLA_LOG_INFO("P_y" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+      }
+   }
+   
+   for (int i = 0; i < zCellCount_; i++) {
+      real_t zValue = blockAABB.minCorner()[2] + i*cellSpan_;
+      real_t lambda = (zValue - ray.getOrigin()[2]) * ray.getInvDirection()[2];
+      real_t xValue = ray.getOrigin()[0] + lambda * ray.getDirection()[0];
+      real_t yValue = ray.getOrigin()[1] + lambda * ray.getDirection()[1];
+      if (xValue > blockAABB.maxCorner()[0] || xValue < blockAABB.minCorner()[0] ||
+          yValue > blockAABB.maxCorner()[1] || yValue < blockAABB.minCorner()[1] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_z" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t arrayIndex = hashPoint(xValue, yValue, zValue + halfCellSpan);
+         WALBERLA_LOG_INFO("P_z" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+      }
+   }
+}
 
+   
 //*************************************************************************************************
 /*!\brief Adds a body to a specific cell in this hash grid.
  *
@@ -1183,7 +1233,7 @@ bool HashGrids::powerOfTwo( size_t number )
  * note that the initial number of cells does not necessarily have to be equal for all three
  * coordinate directions.
  */
-const size_t HashGrids::xCellCount = 16;
+const size_t HashGrids::xCellCount = 4;
 //*************************************************************************************************
 
 
@@ -1200,7 +1250,7 @@ const size_t HashGrids::xCellCount = 16;
  * note that the initial number of cells does not necessarily have to be equal for all three
  * coordinate directions.
  */
-const size_t HashGrids::yCellCount = 16;
+const size_t HashGrids::yCellCount = 4;
 //*************************************************************************************************
 
 
@@ -1217,7 +1267,7 @@ const size_t HashGrids::yCellCount = 16;
  * note that the initial number of cells does not necessarily have to be equal for all three
  * coordinate directions.
  */
-const size_t HashGrids::zCellCount = 16;
+const size_t HashGrids::zCellCount = 4;
 //*************************************************************************************************
 
 
diff --git a/src/pe/ccd/HashGrids.h b/src/pe/ccd/HashGrids.h
index 060be9447c6cf4e5163da18f503dcdf446cf7c73..67bbcfe62ab92cf0c118a872b7e29328b0590ea5 100644
--- a/src/pe/ccd/HashGrids.h
+++ b/src/pe/ccd/HashGrids.h
@@ -40,6 +40,7 @@
 #include <sstream>
 #include <vector>
 
+#include <pe/raytracing/Ray.h>
 
 namespace walberla{
 namespace pe{
@@ -94,7 +95,7 @@ public:
    static const real_t hierarchyFactor;
    //**********************************************************************************************
 
-private:
+public: //ToDo fix to private again
    //**Type definitions****************************************************************************
    //! Vector for storing (handles to) rigid bodies.
    typedef std::vector<BodyID>  BodyVector;
@@ -181,6 +182,10 @@ private:
       //@}
       //*******************************************************************************************
 
+      
+      void possibleRayIntersectingBodies(const raytracing::Ray& ray, const AABB& blockAABB) const;
+      size_t hashPoint(real_t x, real_t y, real_t z) const;
+
     private:
       //**Utility functions************************************************************************
       /*!\name Utility functions */
diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp
index 1bf0b12bc8947c4b58c0df8d10c999b00fb91072..75b25ff58ec220296ab1dc1d93dfef075d7c8b36 100644
--- a/tests/pe/Raytracing.cpp
+++ b/tests/pe/Raytracing.cpp
@@ -22,6 +22,8 @@
 #include <pe/raytracing/Color.h>
 #include <pe/raytracing/ShadingFunctions.h>
 
+#include <pe/ccd/HashGrids.h>
+
 using namespace walberla;
 using namespace walberla::pe;
 using namespace walberla::pe::raytracing;
@@ -372,6 +374,153 @@ void RaytracerSpheresTest() {
    raytracer.rayTrace<BodyTuple>(0);
 }
 
+void playground() {
+   AABB gridAABB(0,0,0,3,3,3);
+   AABB blockAABB(-1,-1,-1,2,2,2);
+   real_t c = 1; // cell width / height
+   real_t c_inv = real_t(1) / c;
+   size_t n_x = 3;
+   size_t n_y = 3;
+   size_t n_z = 3;
+   
+   Ray ray(Vec3(-1, -2, 0), Vec3(2, 9, 0).getNormalized());
+   
+   for (int i = 0; i < n_x; i++) {
+      real_t xValue = blockAABB.minCorner()[0] + i*c;
+      real_t lambda = (xValue - ray.getOrigin()[0]) * ray.getInvDirection()[0];
+      real_t yValue = ray.getOrigin()[1] + lambda * ray.getDirection()[1];
+      real_t zValue = ray.getOrigin()[2] + lambda * ray.getDirection()[2];
+      if (yValue > blockAABB.maxCorner()[1] || yValue < blockAABB.minCorner()[1] ||
+          zValue > blockAABB.maxCorner()[2] || zValue < blockAABB.minCorner()[2] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_x" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t xIndex = size_t(xValue * c_inv) % n_x;
+         size_t yIndex = size_t(yValue * c_inv) % n_y;
+         size_t zIndex = size_t(zValue * c_inv) % n_z;
+         if (xValue < 0) {
+            xIndex = n_x - 1 - (size_t(-xValue * c_inv) % n_x);
+         }
+         if (yValue < 0) {
+            yIndex = n_y - 1 - (size_t(-yValue * c_inv) % n_y);
+         }
+         if (zValue < 0) {
+            zIndex = n_z - 1 - (size_t(-zValue * c_inv) % n_z);
+         }
+         size_t arrayIndex = xIndex + yIndex*n_x + zIndex*n_x*n_y;
+         WALBERLA_LOG_INFO("P_x" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+         WALBERLA_LOG_INFO("\t xIndex = " << xIndex << "; yIndex = " << yIndex << "; zIndex = " << zIndex);
+      }
+   }
+   
+   for (int i = 0; i < n_y; i++) {
+      real_t yValue = blockAABB.minCorner()[1] + i*c;
+      real_t lambda = (yValue - ray.getOrigin()[1]) * ray.getInvDirection()[1];
+      real_t xValue = ray.getOrigin()[0] + lambda * ray.getDirection()[0];
+      real_t zValue = ray.getOrigin()[2] + lambda * ray.getDirection()[2];
+      if (xValue > blockAABB.maxCorner()[0] || xValue < blockAABB.minCorner()[0] ||
+          zValue > blockAABB.maxCorner()[2] || zValue < blockAABB.minCorner()[2] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_y" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t xIndex = size_t(xValue * c_inv) % n_x;
+         size_t yIndex = size_t(yValue * c_inv) % n_y;
+         size_t zIndex = size_t(zValue * c_inv) % n_z;
+         if (xValue < 0) {
+            xIndex = n_x - 1 - (size_t(-xValue * c_inv) % n_x);
+         }
+         if (yValue < 0) {
+            yIndex = n_y - 1 - (size_t(-yValue * c_inv) % n_y);
+         }
+         if (zValue < 0) {
+            zIndex = n_z - 1 - (size_t(-zValue * c_inv) % n_z);
+         }
+         size_t arrayIndex = xIndex + yIndex*n_x + zIndex*n_x*n_y;
+         WALBERLA_LOG_INFO("P_y" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+         WALBERLA_LOG_INFO("\t xIndex = " << xIndex << "; yIndex = " << yIndex << "; zIndex = " << zIndex);
+      }
+   }
+   
+   for (int i = 0; i < n_z; i++) {
+      real_t zValue = blockAABB.minCorner()[2] + i*c;
+      real_t lambda = (zValue - ray.getOrigin()[2]) * ray.getInvDirection()[2];
+      real_t xValue = ray.getOrigin()[0] + lambda * ray.getDirection()[0];
+      real_t yValue = ray.getOrigin()[1] + lambda * ray.getDirection()[1];
+      if (xValue > blockAABB.maxCorner()[0] || xValue < blockAABB.minCorner()[0] ||
+          yValue > blockAABB.maxCorner()[1] || yValue < blockAABB.minCorner()[1] ||
+          lambda != lambda) {
+         WALBERLA_LOG_INFO("P_z" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") invalid");
+      } else {
+         size_t xIndex = size_t(xValue * c_inv) % n_x;
+         size_t yIndex = size_t(yValue * c_inv) % n_y;
+         size_t zIndex = size_t(zValue * c_inv) % n_z;
+         if (xValue < 0) {
+            xIndex = n_x - 1 - (size_t(-xValue * c_inv) % n_x);
+         }
+         if (yValue < 0) {
+            yIndex = n_y - 1 - (size_t(-yValue * c_inv) % n_y);
+         }
+         if (zValue < 0) {
+            zIndex = n_z - 1 - (size_t(-zValue * c_inv) % n_z);
+         }
+         size_t arrayIndex = xIndex + yIndex*n_x + zIndex*n_x*n_y;
+         WALBERLA_LOG_INFO("P_z" << i << " = (" << xValue << "/" << yValue << "/" << zValue << ") maps to cell " << arrayIndex);
+         WALBERLA_LOG_INFO("\t xIndex = " << xIndex << "; yIndex = " << yIndex << "; zIndex = " << zIndex);
+      }
+   }
+}
+
+void hashgridsPlayground() {
+   using namespace walberla::pe::ccd;
+   
+   /*shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
+   shared_ptr<BlockForest> forest = createBlockForest(AABB(-8,-8,-8,8,8,8), Vec3(1,1,1), Vec3(false, false, false));
+   auto storageID = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage");
+
+   HashGrids::HashGrid hashgrid(1.0); // initialize a 16x16x16 hashgrid with cellspan 1.0 (can hold a block with 16x16x16 in size.)
+   
+   std::vector<Vec3> minCorners;
+   minCorners.push_back(Vec3(0,0,0));
+   minCorners.push_back(Vec3(0.1,0.1,0.1));
+   minCorners.push_back(Vec3(0.2,0.2,0.2));
+   minCorners.push_back(Vec3(0.3,0.3,0.3));
+   minCorners.push_back(Vec3(0.9,0.9,0.9));
+   minCorners.push_back(Vec3(1,1,1));
+   minCorners.push_back(Vec3(1.1,1.1,1.1));
+   minCorners.push_back(Vec3(1.4,1.4,1.4));
+   minCorners.push_back(Vec3(1.6,1.6,1.6));
+
+   minCorners.push_back(Vec3(-8+1e-5,-8+1e-5,-8+1e-5));
+   
+
+   Vec3 lengths(0.5,0.5,0.5);
+   for (auto minCorner: minCorners) {
+      BoxID box = createBox(*globalBodyStorage, *forest, storageID, 9, minCorner+lengths/2, lengths);
+      if (box == NULL) {
+         WALBERLA_LOG_INFO("could not create box at " << minCorner);
+         continue;
+      }
+      hashgrid.add(box);
+      WALBERLA_LOG_INFO("hash of box at " << minCorner << " (" << box->getAABB().minCorner() << "): " << box->getHash());
+   }*/
+   
+   HashGrids::HashGrid hashgrid(1.0); // initialize a 4x4x4 hashgrid with cellspan 1.0 (can hold a block with 4x4x4 in size.)
+   
+   const AABB blockAABB(-2,-2,-2,2,2,2);
+   
+   Ray ray(Vec3(-3, -1.6, 0), Vec3(4, 1, 0).getNormalized());
+   
+   hashgrid.possibleRayIntersectingBodies(ray, blockAABB);
+   
+   Ray ray2(Vec3(-2.1, -2.1, 0), Vec3(1, 1, 0).getNormalized());
+   hashgrid.possibleRayIntersectingBodies(ray2, blockAABB);
+   
+   WALBERLA_LOG_INFO(hashgrid.hashPoint(-0.5, -0.5, 0));
+   WALBERLA_LOG_INFO(hashgrid.hashPoint(-1.5, -1.5, 0));
+   WALBERLA_LOG_INFO(hashgrid.hashPoint(-1.5, 1.5, 0));
+   WALBERLA_LOG_INFO(hashgrid.hashPoint(1.5, -1.5, 0));
+}
+
 int main( int argc, char** argv )
 {
    walberla::debug::enterTestMode();
@@ -384,8 +533,10 @@ int main( int argc, char** argv )
    //BoxIntersectsTest();
    //AABBIntersectsTest();
    //CapsuleIntersectsTest();
-   RaytracerTest();
+   //RaytracerTest();
    //RaytracerSpheresTest();
+   
+   hashgridsPlayground();
 
    return EXIT_SUCCESS;
 }