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