|
HG-MD
1
|
This adds on the hierarchical grid code for 2D problems. More...
#include <HGRID_2D.h>


Public Member Functions | |
| HGRID_2D () | |
| This is the default constructor. All it does is set senible defaults. | |
| HGRID_2D (MD &other) | |
| Copy-constructor for creates an HGRID problem from an existing MD problem. | |
| HGRID_2D (HGRID_base &other) | |
| void | constructor () |
| This is the actually constructor it is called do both constructors above. | |
Protected Member Functions | |
| void | HGRID_UpdateParticleInHgrid (Particle *obj) |
| This adds a partcile to the Grid, called in the grid setup routies. | |
| void | HGRID_RemoveParticleFromHgrid (Particle *obj) |
| void | CheckCell (Cell cell, Particle *obj, HGrid *grid) |
| Check collisions for a general cell. | |
| void | CheckCell_current (Cell cell, HGrid *grid) |
| Checks for a collision in the particles own cell. | |
| void | CheckObjAgainstGrid (HGrid *grid, Particle *obj) |
| Check if an Particle has a collision in the grid; avoids multiple checks. | |
| void | CheckObjAgainstWholeGrid (HGrid *grid, Particle *obj) |
| Check if an Particle has a collision in the grid. | |
| bool | TestCell (Cell cell, Particle *obj, HGrid *grid) |
| Tests obj against all particles in cell similar to CheckCell, but links to TestObject instead of compute_internal_forces. | |
| bool | TestObjAgainstGrid (HGrid *grid, Particle *obj) |
| Tests obj against all neighbouring particles similar to CheckObjAgainstGrid, but links to TestCell instead of CheckCell. | |
This adds on the hierarchical grid code for 2D problems.
| HGRID_2D::HGRID_2D | ( | ) | [inline] |
This is the default constructor. All it does is set senible defaults.
References constructor().
{
constructor();
#ifdef CONSTUCTOR_OUTPUT
cerr << "HGRID_2D() finished"<<endl;
#endif
}
| HGRID_2D::HGRID_2D | ( | MD & | other | ) | [inline] |
Copy-constructor for creates an HGRID problem from an existing MD problem.
References constructor().
: MD(other), HGRID_base(other) { constructor(); #ifdef CONSTUCTOR_OUTPUT cerr << "HGRID_2D(MD& other) finished" << endl; #endif }
| HGRID_2D::HGRID_2D | ( | HGRID_base & | other | ) | [inline] |
References constructor().
: MD(other), HGRID_base(other) { constructor(); #ifdef CONSTUCTOR_OUTPUT cerr << "HGRID_2D(HGRID_base& other) finished" << endl; #endif }
| void HGRID_2D::CheckCell | ( | Cell | cell, |
| Particle * | obj, | ||
| HGrid * | grid | ||
| ) | [protected] |
Check collisions for a general cell.
Check for collisions with a general cell.
References MD::compute_internal_forces(), HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Cell::l, HGrid::objectBucket, Cell::x, and Cell::y.
Referenced by CheckObjAgainstGrid().
{
int bucket = grid->ComputeHashBucketIndex(cell);
if ((obj->get_HGRID_x() == cell.x) && (obj->get_HGRID_y() == cell.y) && (obj->get_HGRID_Level() == cell.l)) { return; }
// Loop through all objects in the bucket to find nearby objects
Particle *p = grid->objectBucket[bucket];
while (p!=NULL)
{
if ((p->get_HGRID_x() == cell.x) && (p->get_HGRID_y() == cell.y) && (p->get_HGRID_Level() == cell.l))
{
compute_internal_forces(obj,p);
}
p = p->get_HGRID_NextObject();
}
}
| void HGRID_2D::CheckCell_current | ( | Cell | cell, |
| HGrid * | grid | ||
| ) | [protected] |
Checks for a collision in the particles own cell.
Checks for collision in the particles own cell.
References HGrid::bucketIsChecked, MD::compute_internal_forces(), HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_NextObject(), and HGrid::objectBucket.
Referenced by CheckObjAgainstGrid().
{
int bucket = grid->ComputeHashBucketIndex(cell);
if (grid->bucketIsChecked[bucket]) { return; }
Particle* p1 = grid->objectBucket[bucket];
while (p1!=NULL)
{
Particle* p2 = p1->get_HGRID_NextObject();
while (p2!=NULL)
{
compute_internal_forces(p1,p2);
p2 = p2->get_HGRID_NextObject();
}
p1 = p1->get_HGRID_NextObject();
}
grid->bucketIsChecked[bucket] = true;
}
| void HGRID_2D::CheckObjAgainstGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected, virtual] |
Check if an Particle has a collision in the grid; avoids multiple checks.
Test collisions between object and all objects in hgrid.
Implements HGRID_base.
References CheckCell(), CheckCell_current(), Particle::get_HGRID_Level(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Particle::get_Position(), HGrid::HGRID_MAX_LEVELS, HGrid::inv_size, HGrid::occupiedLevelsMask, Vec3D::X, and Vec3D::Y.
{
int startLevel = obj->get_HGRID_Level();
int occupiedLevelsMask = grid->occupiedLevelsMask >> obj->get_HGRID_Level();
int x, y;
Mdouble inv_size;
for (int level = startLevel; level < grid->HGRID_MAX_LEVELS; occupiedLevelsMask >>= 1, level++)
{
// If no objects in rest of grid, stop now
if (occupiedLevelsMask == 0) break;
// If no objects at this level, go on to the next level
if ((occupiedLevelsMask & 1) == 0) continue;
if (level == startLevel)
{
x = obj->get_HGRID_x();
y = obj->get_HGRID_y();
CheckCell_current(Cell(x, y, 0, level), grid);
CheckCell(Cell(x+1, y , 0, level), obj, grid);
CheckCell(Cell(x+1, y+1, 0, level), obj, grid);
CheckCell(Cell(x , y+1, 0, level), obj, grid);
CheckCell(Cell(x+1, y-1, 0, level), obj, grid);
}
else
{
inv_size = grid->inv_size[level];
x = (int)floor(obj->get_Position().X * inv_size);
y = (int)floor(obj->get_Position().Y * inv_size);
CheckCell(Cell(x, y, 0, level), obj, grid);
CheckCell(Cell(x+1, y, 0, level), obj, grid);
CheckCell(Cell(x+1, y+1, 0, level), obj, grid);
CheckCell(Cell(x, y+1, 0, level), obj, grid);
CheckCell(Cell(x, y-1, 0, level), obj, grid);
CheckCell(Cell(x+1, y-1, 0, level), obj, grid);
CheckCell(Cell(x-1, y, 0, level), obj, grid);
CheckCell(Cell(x-1, y+1, 0, level), obj, grid);
CheckCell(Cell(x-1, y-1, 0, level), obj, grid);
}
}
}
| void HGRID_2D::CheckObjAgainstWholeGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected] |
Check if an Particle has a collision in the grid.
| void HGRID_2D::constructor | ( | ) | [inline] |
This is the actually constructor it is called do both constructors above.
Reimplemented from HGRID_base.
Referenced by HGRID_2D().
{}
| void HGRID_2D::HGRID_RemoveParticleFromHgrid | ( | Particle * | obj | ) | [protected] |
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), HGRID_base::grid, HGrid::objectBucket, and Particle::set_HGRID_NextObject().
{
Cell cell(obj->get_HGRID_x(),obj->get_HGRID_y(), 0, obj->get_HGRID_Level());
int bucket = grid->ComputeHashBucketIndex(cell);
Particle* prevObj=grid->objectBucket[bucket];
if(prevObj==obj)
grid->objectBucket[bucket]=obj->get_HGRID_NextObject();
else
{
while((prevObj!=NULL)&&(prevObj->get_HGRID_NextObject()!=obj))
prevObj=prevObj->get_HGRID_NextObject();
if(prevObj!=NULL)
prevObj->set_HGRID_NextObject(obj->get_HGRID_NextObject());
}
}
| void HGRID_2D::HGRID_UpdateParticleInHgrid | ( | Particle * | obj | ) | [protected] |
This adds a partcile to the Grid, called in the grid setup routies.
Add object to grid square, and remember cell and level numbers, treating level as a third dimension coordinate.
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_Position(), HGRID_base::grid, HGrid::inv_size, HGrid::objectBucket, Particle::set_HGRID_NextObject(), Particle::set_HGRID_x(), Particle::set_HGRID_y(), Vec3D::X, Cell::x, Vec3D::Y, and Cell::y.
{
int level = obj->get_HGRID_Level();
Mdouble inv_size = grid->inv_size[level];
Cell cell((int)floor(obj->get_Position().X * inv_size), (int)floor(obj->get_Position().Y * inv_size), 0, level);
int bucket = grid->ComputeHashBucketIndex(cell);
obj->set_HGRID_NextObject(grid->objectBucket[bucket]);
grid->objectBucket[bucket] = obj;
obj->set_HGRID_x(cell.x);
obj->set_HGRID_y(cell.y);
}
| bool HGRID_2D::TestCell | ( | Cell | cell, |
| Particle * | obj, | ||
| HGrid * | grid | ||
| ) | [protected] |
Tests obj against all particles in cell similar to CheckCell, but links to TestObject instead of compute_internal_forces.
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Cell::l, HGrid::objectBucket, HGRID_base::TestObject(), Cell::x, and Cell::y.
Referenced by TestObjAgainstGrid().
{
bool Test = true;
// Loop through all objects in the bucket to find nearby objects
int bucket = grid->ComputeHashBucketIndex(cell);
Particle *p = grid->objectBucket[bucket];
while (Test && p!=NULL)
{
if ((p->get_HGRID_x() == cell.x) && (p->get_HGRID_y() == cell.y) && (p->get_HGRID_Level() == cell.l))
{
Test = Test && TestObject(obj,p);
}
p = p->get_HGRID_NextObject();
}
return Test;
}
| bool HGRID_2D::TestObjAgainstGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected] |
Tests obj against all neighbouring particles similar to CheckObjAgainstGrid, but links to TestCell instead of CheckCell.
References Particle::get_Position(), HGrid::HGRID_MAX_LEVELS, HGrid::inv_size, HGrid::occupiedLevelsMask, TestCell(), Vec3D::X, and Vec3D::Y.
{
bool Test = true;
int x, y;
Mdouble inv_size;
int occupiedLevelsMask = grid->occupiedLevelsMask;
for (int level = 0; level < grid->HGRID_MAX_LEVELS && Test; occupiedLevelsMask >>= 1, level++)
{
// If no objects in rest of grid, stop now
if (occupiedLevelsMask == 0) break;
// If no objects at this level, go on to the next level
if ((occupiedLevelsMask & 1) == 0) continue;
// Treat level as a third dimension coordinate
inv_size = grid->inv_size[level];
x = (int)floor(obj->get_Position().X * inv_size);
y = (int)floor(obj->get_Position().Y * inv_size);
Test = Test
&& TestCell(Cell(x , y , 0, level), obj, grid)
&& TestCell(Cell(x , y-1, 0, level), obj, grid)
&& TestCell(Cell(x , y+1, 0, level), obj, grid)
&& TestCell(Cell(x-1, y , 0, level), obj, grid)
&& TestCell(Cell(x+1, y , 0, level), obj, grid)
&& TestCell(Cell(x-1, y-1, 0, level), obj, grid)
&& TestCell(Cell(x-1, y+1, 0, level), obj, grid)
&& TestCell(Cell(x+1, y-1, 0, level), obj, grid)
&& TestCell(Cell(x+1, y+1, 0, level), obj, grid);
} //end for level
return Test;
}
1.7.6.1