#include <Geometry.h>
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) |
Edge * | bisect (Site *s1, Site *s2) |
Site * | intersect (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 |
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::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 }
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 }
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 }
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 }
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] |
Referenced by initialize(), intersectCircleLine(), and intersectCircleSite().
Vector2D Geometry::center[3] [protected] |
Referenced by processEdge().
bool Geometry::debugOutput [protected] |
Referenced by processEdge().
bool Geometry::doDiscovery [protected] |
Referenced by initialize(), and processEdge().