Geometry Class Reference

#include <Geometry.h>

List of all members.


Detailed Description

Geometry class.

Provides basic line inter- / bisecting and processing functions, needed to build the voronoi and determine neighborhood relationships.

Public Member Functions

void initialize (double deltax, double deltay, Vector2D center, Vector2D old_pos, Vector2D new_pos, double radius)
void reset ()
void setDebug (bool debugOutput)
Edgebisect (Site *s1, Site *s2)
Siteintersect (Halfedge *el1, Halfedge *el2)
void endpoint (Edge *e, int lr, Site *s)
void processEdge (Edge *e)
double dist (Site *s, Site *t)

Protected Member Functions

bool intersectCircleLine (Vector2D start, Vector2D dir, Vector2D center, bool lowerBound, bool upperBound)
bool intersectCircleSite (Site *s, Vector2D center)

Protected Attributes

Site ** SITEmemmap
Edge ** EDGEmemmap
int SITEcount
int EDGEcount
double deltax
double deltay
double sq_radius
Vector2D center [3]
bool debugOutput
bool doDiscovery


Member Function Documentation

void Geometry::initialize ( double  deltax,
double  deltay,
Vector2D  center,
Vector2D  old_pos,
Vector2D  new_pos,
double  radius 
)

Referenced by NeighborsList::buildVoronoi().

00027 {
00028     SITEcount = 0;
00029     EDGEcount = 0;
00030 
00031     SITEmemmap = new Site*[25];
00032     EDGEmemmap = new Edge*[25];
00033 
00034     this->deltay = deltay;
00035     this->deltax = deltax;
00036     this->center[0] = center;
00037     this->center[1] = old_pos;
00038     this->center[2] = new_pos;
00039     if((old_pos.x != new_pos.x) || (old_pos.y != new_pos.y)) doDiscovery = true;
00040     else doDiscovery = false;
00041     this->sq_radius = radius*radius;
00042 }

void Geometry::reset (  ) 

Referenced by NeighborsList::buildVoronoi().

00045 {
00046     int i;
00047     for(i=0; i<SITEcount; i++) delete SITEmemmap[i];
00048     for(i=0; i<EDGEcount; i++) delete EDGEmemmap[i];
00049     delete[] SITEmemmap;
00050     delete[] EDGEmemmap;
00051 }

void Geometry::setDebug ( bool  debugOutput  ) 

Referenced by NeighborsList::setDebug().

00054 {
00055     this->debugOutput = debugOutput;
00056 }

Edge * Geometry::bisect ( Site s1,
Site s2 
)

Referenced by NeighborsList::buildVoronoi().

00176 {
00177     double dx, dy, adx, ady;
00178     Edge *newedge;
00179 
00180     newedge = new Edge;
00181 
00182     newedge->reg[0] = s1;
00183     newedge->reg[1] = s2;
00184     newedge->ep[0] = NULL;
00185     newedge->ep[1] = NULL;
00186 
00187     dx = s2->coord.x - s1->coord.x;
00188     dy = s2->coord.y - s1->coord.y;
00189     adx = dx > 0 ? dx : -dx;
00190     ady = dy > 0 ? dy : -dy;
00191     newedge->c = s1->coord.x * dx + s1->coord.y * dy + (dx*dx + dy*dy)*0.5;
00192     if(adx>ady) {
00193         newedge->a = 1.0;
00194         newedge->b = dy/dx;
00195         newedge->c /= dx;
00196     }
00197     else {
00198         newedge->b = 1.0;
00199         newedge->a = dx/dy;
00200         newedge->c /= dy;
00201     }
00202 
00203     EDGEmemmap[EDGEcount++] = newedge;
00204     if(EDGEcount%25 == 0) {
00205         Edge **Temp = new Edge*[EDGEcount + 25];
00206         for(int i=0; i<EDGEcount; i++) Temp[i] = EDGEmemmap[i];
00207         delete[] EDGEmemmap;
00208         EDGEmemmap = Temp;
00209     }
00210     return newedge;
00211 }

Site * Geometry::intersect ( Halfedge el1,
Halfedge el2 
)

Referenced by NeighborsList::buildVoronoi().

00214 {
00215     Edge *e1, *e2, *e;
00216     Halfedge *el;
00217     double d, xint, yint;
00218     int right_of_site;
00219     Site *v;
00220 
00221     e1 = el1->ELedge;
00222     e2 = el2->ELedge;
00223     if(e1 == NULL || e2 == NULL) return NULL;
00224     if(e1->reg[1] == e2->reg[1]) return NULL;
00225 
00226     d = e1->a * e2->b - e1->b * e2->a;
00227     if(-1.0e-10 < d && d < 1.0e-10) return NULL;
00228 
00229     xint = (e1->c * e2->b - e2->c * e1->b)/d;
00230     yint = (e2->c * e1->a - e1->c * e2->a)/d;
00231 
00232     if((e1->reg[1]->coord.y < e2->reg[1]->coord.y) || (e1->reg[1]->coord.y == e2->reg[1]->coord.y && e1->reg[1]->coord.x < e2->reg[1]->coord.x)) {
00233         el = el1;
00234         e = e1;
00235     }
00236     else {
00237         el = el2;
00238         e = e2;
00239     }
00240 
00241     right_of_site = xint >= e->reg[1]->coord.x;
00242     if((right_of_site && el->ELpm == le) || (!right_of_site && el->ELpm == re)) return NULL;
00243 
00244     v = new Site;
00245 
00246     v->coord.x = xint;
00247     v->coord.y = yint;
00248 
00249     SITEmemmap[SITEcount++] = v;
00250     if(SITEcount%25 == 0) {
00251         Site **Temp = new Site*[SITEcount + 25];
00252         for(int i=0; i<SITEcount; i++) Temp[i] = SITEmemmap[i];
00253         delete[] SITEmemmap;
00254         SITEmemmap = Temp;
00255     }
00256     return v;
00257 }

void Geometry::endpoint ( Edge e,
int  lr,
Site s 
)

Referenced by NeighborsList::buildVoronoi().

00260 {
00261     e->ep[lr] = s;
00262     if(e->ep[re-lr] == NULL) return;
00263     processEdge(e);
00264 }

void Geometry::processEdge ( Edge e  ) 

Referenced by NeighborsList::buildVoronoi(), and endpoint().

00091 {
00092     bool leftEndpoint_In[3], rightEndpoint_In[3];
00093     int i, numTest;
00094     // test the edge just against our own AOI or also against AOI's of a moving neighbor
00095     numTest = doDiscovery ? 3 : 1;
00096 
00097     for(i = 0; i < numTest; i++) {
00098         if(e->ep[le]) leftEndpoint_In[i] = intersectCircleSite(e->ep[le], center[i]);
00099         else leftEndpoint_In[i] = false;
00100         if(e->ep[re]) rightEndpoint_In[i] = intersectCircleSite(e->ep[re], center[i]);
00101         else rightEndpoint_In[i] = false;
00102     }
00103     for(i = 0; i < numTest; i++) {
00104         if(leftEndpoint_In[i] || rightEndpoint_In[i]) {
00105             if(!e->reg[le]->innerEdge[i]) e->reg[le]->innerEdge[i] = true;
00106             if(!e->reg[re]->innerEdge[i]) e->reg[re]->innerEdge[i] = true;
00107         }
00108     }
00109     if(!leftEndpoint_In[0] || !rightEndpoint_In[0]) {
00110         if(!e->reg[le]->outerEdge) e->reg[le]->outerEdge = true;
00111         if(!e->reg[re]->outerEdge) e->reg[re]->outerEdge = true;
00112     }
00113     for(i = 0; i < numTest; i++) {
00114         if(!(leftEndpoint_In[i] || rightEndpoint_In[i])) {
00115             bool lineTest = false;
00116             if(e->ep[le] && e->ep[re]) {
00117                 Vector2D t_dir;
00118                 t_dir.x = e->ep[re]->coord.x - e->ep[le]->coord.x;
00119                 t_dir.y = e->ep[re]->coord.y - e->ep[le]->coord.y;
00120                 lineTest = intersectCircleLine(e->ep[le]->coord, t_dir, center[i], true, true);
00121             }
00122             if((e->ep[le] && !e->ep[re]) || (!e->ep[le] && e->ep[re])) {
00123                 Vector2D t_dir;
00124                 t_dir.x = e->b;
00125                 t_dir.y = -(e->a);
00126                 if(e->ep[le]) {
00127                     if(t_dir.x < 0.0f) {
00128                         t_dir.x = -t_dir.x;
00129                         t_dir.y = -t_dir.y;
00130                     }
00131                     lineTest = intersectCircleLine(e->ep[le]->coord, t_dir, center[i], true, false);
00132                 }
00133                 else {
00134                     if(t_dir.x >= 0.0f) {
00135                         t_dir.x = -t_dir.x;
00136                         t_dir.y = -t_dir.y;
00137                     }
00138                     lineTest = intersectCircleLine(e->ep[re]->coord, t_dir, center[i], true, false);
00139                 }
00140             }
00141             if(!(e->ep[le] || e->ep[re])) {
00142                 Vector2D t_start, t_dir;
00143                 if(e->b == 0.0f) {
00144                     t_start.x = e->c / e->a;
00145                     t_start.y = 0.0f;
00146                 }
00147                 else {
00148                     t_start.x = 0.0f;
00149                     t_start.y = e->c / e->b;
00150                 }
00151                 t_dir.x = e->b;
00152                 t_dir.y = -(e->a);
00153                 lineTest = intersectCircleLine(t_start, t_dir, center[i], false, false);
00154             }
00155 
00156             if(lineTest) {
00157                 if(!e->reg[le]->innerEdge[i]) e->reg[le]->innerEdge[i] = true;
00158                 if(!e->reg[re]->innerEdge[i]) e->reg[re]->innerEdge[i] = true;
00159             }
00160         }
00161     }
00162     // test if one of the nodes bisected by the edge is an enclosing neighbor
00163     if(e->reg[le]->type == THIS) {
00164         e->reg[re]->type |= ENCLOSING;
00165         // Debug output
00166         if(debugOutput) ev << "  VAST: Site at [" << e->reg[re]->coord.x << ", " << e->reg[re]->coord.y << "] is a enclosing neighbor." << endl;
00167     }
00168     if(e->reg[re]->type == THIS) {
00169         e->reg[le]->type |= ENCLOSING;
00170         // Debug output
00171         if(debugOutput) ev << "  VAST: Site at [" << e->reg[le]->coord.x << ", " << e->reg[le]->coord.y << "] is a enclosing neighbor." << endl;
00172     }
00173 }

double Geometry::dist ( Site s,
Site t 
)

Referenced by NeighborsList::buildVoronoi().

00267 {
00268     double dx, dy;
00269     dx = s->coord.x - t->coord.x;
00270     dy = s->coord.y - t->coord.y;
00271     return sqrt(dx*dx + dy*dy);
00272 }

bool Geometry::intersectCircleLine ( Vector2D  start,
Vector2D  dir,
Vector2D  center,
bool  lowerBound,
bool  upperBound 
) [protected]

Referenced by processEdge().

00069 {
00070     Vector2D StartMinusCenter;
00071     double DirDotStartMinusCenter, DirSq, StartMinusCenterSq, discriminant;
00072     StartMinusCenter.x = start.x - center.x;
00073     StartMinusCenter.y = start.y - center.y;
00074     StartMinusCenterSq = StartMinusCenter.x * StartMinusCenter.x + StartMinusCenter.y * StartMinusCenter.y;
00075 
00076     DirDotStartMinusCenter = dir.x * StartMinusCenter.x + dir.y * StartMinusCenter.y;
00077     DirSq = dir.x * dir.x + dir.y * dir.y;
00078 
00079     discriminant = DirDotStartMinusCenter * DirDotStartMinusCenter - DirSq * (StartMinusCenterSq - sq_radius);
00080 
00081     if(discriminant <= 0.0f) return false;
00082     else if(lowerBound) {
00083         double s = (-DirDotStartMinusCenter - sqrtf(discriminant)) / DirSq;
00084         if(s < 0.0f) return false;
00085         else if(upperBound && s > 1.0f) return false;
00086     }
00087     return true;
00088 }

bool Geometry::intersectCircleSite ( Site s,
Vector2D  center 
) [protected]

Referenced by processEdge().

00059 {
00060     double sq_distance;
00061     Vector2D temp;
00062     temp.x = s->coord.x - center.x;
00063     temp.y = s->coord.y - center.y;
00064     sq_distance = temp.x*temp.x + temp.y*temp.y;
00065     return sq_distance < sq_radius ? true : false;
00066 }


Member Data Documentation

Site** Geometry::SITEmemmap [protected]

Referenced by initialize(), intersect(), and reset().

Edge** Geometry::EDGEmemmap [protected]

Referenced by bisect(), initialize(), and reset().

int Geometry::SITEcount [protected]

Referenced by initialize(), intersect(), and reset().

int Geometry::EDGEcount [protected]

Referenced by bisect(), initialize(), and reset().

double Geometry::deltax [protected]

double Geometry::deltay [protected]

double Geometry::sq_radius [protected]

Vector2D Geometry::center[3] [protected]

Referenced by processEdge().

bool Geometry::debugOutput [protected]

Referenced by processEdge().

bool Geometry::doDiscovery [protected]

Referenced by initialize(), and processEdge().


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:06 2008 for ITM OverSim by  doxygen 1.5.5