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; }