00001 
00002 
00003 #ifndef NODE_H
00004 #define NODE_H
00005 
00006 #include <math.h>
00007 #include "ref.h"
00008 #define DIM 2
00009 
00010 class elemRef;
00011 class edgeRef;
00012 
00013 class node {  
00014   double x, y;  
00015   int reports;  
00016   double sumReports[DIM];  
00017   int theLock; 
00018   double lockLength;
00019   edgeRef lockHolder;
00020  public:
00021   int present;  
00022   int boundary; 
00023   int fixed;   
00024   
00025   node() {
00026     x=-1.0; y=-1.0; theLock = reports = boundary = fixed = 0; 
00027     sumReports[0]=sumReports[1]=0.0; present = 0;
00028   }
00029   node(double a, double b) { 
00030     x = a;  y = b;  reports = boundary = fixed = theLock = 0; 
00031     sumReports[0] = sumReports[1] = 0.0; present = 1;
00032   }
00033   node(const node& n) { 
00034     x = n.x;  y = n.y;  reports = n.reports; boundary = n.boundary; 
00035     theLock = n.theLock; present = n.present; fixed = n.fixed;
00036     sumReports[0] = n.sumReports[0];  sumReports[1] = n.sumReports[1];
00037   }
00038   void set(double a, double b) { 
00039     x = a;  y = b; present = 1;
00040   }
00041   void reset() { 
00042     theLock = reports = boundary = fixed = 0;
00043     sumReports[0] = sumReports[1] = 0.0; present = 0;
00044   }
00045   int operator==(const node& n) { return ((x == n.x) && (y == n.y)); }
00046   node& operator=(const node& n) { 
00047     x = n.x;  y = n.y;  reports = n.reports;  boundary = n.boundary;
00048     theLock = n.theLock; fixed = n.fixed;
00049     present = n.present;
00050     sumReports[0] = n.sumReports[0];  sumReports[1] = n.sumReports[1];
00051     return *this; 
00052   }
00053   void pup(PUP::er &p) {
00054     p(x); p(y); p(present); p(reports); p(theLock); p(boundary); 
00055     p(sumReports, DIM); p(fixed);
00056   }
00057   int isPresent() { return present; }
00058   double X() { return x; }
00059   double Y() { return y; }
00060   int lock(double l, edgeRef e) { 
00061     if (theLock == 0) {
00062       theLock = 1;
00063       lockLength = l;
00064       lockHolder = e;
00065       return 1;
00066     }
00067     else if (e == lockHolder) {
00068       return 1;
00069     }
00070     else if (e.cid == lockHolder.cid) {
00071       return 0;
00072     }
00073     else if (l >= lockLength) {
00074       return 0;
00075     }
00076     else if (l < lockLength) {
00077       
00078 
00079 
00080 
00081 
00082 
00083 
00084       return 0;
00085     }
00086     CkPrintf("WARNING: node::lock: unhandled case.\n");
00087     return 0;
00088   }
00089   void unlock() { 
00090     theLock = 0; 
00091   }
00092   double distance(const node& n) { 
00093     double dx = n.x - x, dy = n.y - y;
00094     double d = (sqrt ((dx * dx) + (dy * dy)));
00095     CkAssert(d > 0.0);
00096     return d;
00097   }
00098   void midpoint(const node& n, node& result) { 
00099     result.x = (x + n.x) / 2.0;  result.y = (y + n.y) / 2.0;
00100     CkAssert(result.x >= 0.0);
00101     CkAssert(result.y >= 0.0);
00102   }
00103   node midpoint(const node& n) { 
00104     double a=(x + n.x) / 2.0, b=(y + n.y) / 2.0;
00105     return node(a, b);
00106   }
00107 
00108   
00109   void improvePos() {
00110     x = sumReports[0]/reports;
00111     y = sumReports[1]/reports;
00112     reports = 0;
00113     sumReports[0] = sumReports[1] = 0.0;
00114   }
00115   void reportPos(const node& n) {
00116     sumReports[0] += n.x;
00117     sumReports[1] += n.y;
00118     reports++;
00119   }
00120   int safeToMove(node m) {
00121     if (boundary) return 0;  
00122     return 1;
00123   }
00124   int safeToMove(node m, elemRef E0, edgeRef e0, edgeRef e1, 
00125          node n1, node n2, node n3) {
00126     
00127 
00128 
00129 
00130 
00131 
00132     if (boundary) return 0;  
00133     return 1;
00134     
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160   }
00161   int findIntersection(node m, node pi, node pj, node mi) {
00162     
00163     double num, den, ua;
00164     
00165     num = ((pj.X() - pi.X()) * (y - pi.Y())) -
00166       ((pj.Y() - pi.Y()) * (x - pi.X()));
00167     den = ((pj.Y() - pi.Y()) * (m.X() - x)) - 
00168       ((pj.X() - pi.X()) * (m.Y() - y));
00169     if (den == 0) return 0;  
00170     ua = num / den;
00171     mi.set(x + (ua * (m.X() - x)), y + (ua * (m.Y() - y)));
00172     return 1;
00173   }
00174   int between(node m, node mi) {
00175     
00176     return((((mi.X() >= x) && (mi.X() <= m.X())) ||
00177         ((mi.X() >= m.X()) && (mi.X() <= x)))
00178        && (((mi.Y() >= y) && (mi.Y() <= m.Y())) ||
00179            ((mi.Y() >= m.Y()) && (mi.Y() <= y))));
00180   }
00181   void sanityCheck(int cid, int idx) {
00182     if ((x == -1.0) && (y == -1.0)) {
00183       CkPrintf("TMRC2D: [%d] node::sanityCheck WARNING: node %d has default coordinate values.\n", cid, idx);
00184     }   
00185     if (theLock)
00186       CkAbort("TMRC2D: node::sanityCheck: WARNING: node is locked.\n");
00187   }
00188   void dump() {
00189     CkPrintf("[%5.9f,%5.9f]", x, y);
00190   }
00191 };
00192 
00193 #endif