00001
00002
00003
00004 #ifndef Edge_H
00005 #define Edge_H
00006
00007 #include "point3d.h"
00008 #include "util.h"
00009 #include "node.h"
00010
00011
00012 class Node;
00013 class Face;
00014 class Tetra;
00015 class NodeArray;
00016 class EdgeArray;
00017 class BoundingSphereLeaf;
00018
00019 class Edge
00020 {
00021 private:
00022
00023 Node *node[2];
00024
00025 ReallocableArray<Face*> face;
00026 ReallocableArray<Tetra*> tetra;
00027
00028
00029 double init_angle;
00030
00031 double restLength;
00032 double springConstant;
00033 double dampConstant;
00034 double marker;
00035 int cutting_marker;
00036
00037 BoundingSphereLeaf* boundingsphere;
00038
00039 EdgeArray* edgearray_p;
00040
00041 Node* splitNode[2];
00042
00043 public:
00044 Point3D force;
00045
00046 public:
00047 Edge();
00048 ~Edge();
00049 static const char* rcsid;
00050 static int debug;
00051
00052
00053 int init(NodeArray* nodearray_p, EdgeArray* edgearray_p_in,
00054 char *initString);
00055 int init(NodeArray* nodearray_p, EdgeArray* edgearray_p_in,
00056 int i1, int i2, double restLength=-1.0,
00057 double springConstant=1.0, double dampConstant=0.5);
00058 int init(NodeArray* nodearray_p, EdgeArray* edgearray_p_in,
00059 Node* n1, Node* n2, double restLength=-1.0,
00060 double springConstant=1.0, double dampConstant=0.5);
00061
00062
00063 int getIndex(void);
00064
00065 EdgeArray* getEdgeArray();
00066
00067 int SanityCheck(EdgeArray* real_ea_p);
00068
00069 friend ostream& operator<<(ostream& os, const Edge& e);
00070
00071 BoundingSphereLeaf* getBoundingSphere();
00072 void setBoundingSphere(BoundingSphereLeaf* sphere);
00073 Point3D getCenter();
00074
00075 double getRadius();
00076
00077
00078 Node* getOtherNode(Node *n);
00079 Node* getNodeLink(int which);
00080 void replaceNodeLink(Node* old_node, Node* new_node);
00081 int hasNodeLink(Node* n);
00082
00083 Face* getFaceLink(int which);
00084 Face* getOtherFace(Face* f);
00085 int numFaceLinks();
00086 void addFaceLink(Face* f);
00087 void deleteFaceLink(Face* f);
00088 int hasFaceLink(Face* n);
00089
00090 Tetra* getTetraLink(int index);
00091 int numTetraLinks();
00092 void addTetraLink(Tetra *t);
00093 void deleteTetraLink(Tetra* t);
00094 int hasTetraLink(Tetra* t);
00095
00096 int intersectsPlaneSweptByCuttingEdge(Edge* e_in, Point3D* intersection_p);
00097 int intersectsPlaneSweptFromEntryPt(Point3D entPt, Edge* cuttingEdge,Point3D
00098 *intPt);
00099 int stepOffVerts(Point3D intPt);
00100
00101 Node* getSplitNode(int which);
00102 void setSplitNodes(Node* node0, Node* node1);
00103
00104 void interpolateTextureCoords(Node* n0, Node* n1);
00105
00106 int isAdjacent(Edge* e);
00107
00108
00109 double getAngle(void);
00110 void addTorsion(void);
00111 double getLength(void);
00112 double getEnergy(void);
00113 double getRestLength(void);
00114 void setRestLength(double distance);
00115 void scaleRestLength(double scalefactor);
00116 void computeNewRestLength();
00117 void scaleRestingLengthFrom(Edge* oldEdge);
00118
00119
00120 double getSpringConstant(void);
00121 void setSpringConstant(double value, int restLengthScale = 0);
00122 double getDampConstant(void);
00123 void setDampConstant(double value);
00124 Point3D UnitDirectionVector(void);
00125 double EdgeDistanceToPoint(Point3D pt, double *near1 = NULL);
00126 double EdgeDistanceToEdge(Edge* e2, double *near1 = NULL,
00127 double *near2 = NULL);
00128 double EdgeDistanceToFaceNoIntersect(Face* f, double *near1,
00129 Point3D *nearpt);
00130 void setMarker(double value);
00131 void setCuttingMarker(int value);
00132
00133 void ComputeSpringForce(int dampingType);
00134 void ComputeSpringForceFullDamp(void);
00135 void ComputeSpringForceRelDamp(void);
00136
00137 void ComputeSpringForceNonlinear(int dampingType);
00138
00139
00140 void draw();
00141 void drawover(double scale);
00142 void drawInitial();
00143 void drawlabel(float offset);
00144 int crossesPlane(double a, double b, double c, double d,
00145 Point3D *intersection_p);
00146 int crossesPlane(Point3D p1, Point3D p2, Point3D p3, Point3D *intPt);
00147
00148
00149 void ResolveMyself(Edge* other_edge);
00150
00151 };
00152
00153 inline BoundingSphereLeaf* Edge::getBoundingSphere()
00154 { return(boundingsphere); }
00155
00156 inline void Edge::setBoundingSphere(BoundingSphereLeaf* sphere)
00157 { boundingsphere = sphere; }
00158
00159 inline Point3D Edge::getCenter()
00160 { return ((node[0]->p + node[1]->p)/2.0); }
00161
00162 inline Node* Edge::getNodeLink(int which)
00163 { if ((which < 0) || (which >= 2)) return(NULL);
00164 else return(node[which]);
00165 }
00166
00167
00168 inline double Edge::getLength(void)
00169 {
00170 Point3D diff = getNodeLink(1)->p - getNodeLink(0)->p;
00171 return (diff.Length());
00172 }
00173
00174 inline double Edge::getRadius()
00175 { return (getLength()/2.0); }
00176
00177 inline double Edge::getRestLength()
00178 { return(restLength); }
00179
00180 inline void Edge::setRestLength(double distance)
00181 { restLength = distance; }
00182
00183 inline void Edge::scaleRestLength(double scalefactor)
00184 { restLength *= scalefactor; }
00185
00186 inline double Edge::getSpringConstant()
00187 { return(springConstant); }
00188
00189
00190
00191
00192
00193 inline void Edge::setSpringConstant(double value, int restLengthScale)
00194 { if (restLengthScale)
00195 springConstant = value/restLength;
00196 else
00197 springConstant = value;
00198 }
00199
00200 inline double Edge::getDampConstant()
00201 { return(dampConstant); }
00202
00203 inline void Edge::setDampConstant(double value)
00204 { dampConstant = value; }
00205
00206 inline void Edge::setMarker(double value)
00207 { marker = value; }
00208 inline void Edge::setCuttingMarker(int value)
00209 { cutting_marker = value; }
00210
00211 inline EdgeArray* Edge::getEdgeArray()
00212 { return(edgearray_p); }
00213
00214
00215 inline int Edge::hasNodeLink(Node* n)
00216 {
00217 if ((node[0] == n) || (node[1] == n)) return(1);
00218 return(0);
00219 }
00220
00221 inline Face* Edge::getFaceLink(int which)
00222 { if ((which < 0) || (which >= face.NumElements()))
00223 return(NULL);
00224 else return(face[which]);
00225 }
00226
00227 inline int Edge::numFaceLinks()
00228 { return(face.NumElements()); }
00229
00230 inline int Edge::hasFaceLink(Face* f)
00231 {
00232 for (int i=0; i<face.NumElements(); i++)
00233 if (face[i] == f) return(1);
00234 return(0);
00235 }
00236
00237 inline int Edge::hasTetraLink(Tetra* t)
00238 {
00239 for (int i=0; i<tetra.NumElements(); i++)
00240 if (tetra[i] == t) return(1);
00241 return 0;
00242 }
00243
00244
00245
00246 inline Node *Edge::getOtherNode(Node *n)
00247 {
00248 if (n == node[0]) return node[1];
00249 else if (n == node[1]) return node[0];
00250 else return (NULL);
00251 }
00252
00253
00254 inline int Edge::isAdjacent(Edge *e)
00255 {
00256 if (node[0]->hasEdgeLink(e) || node[1]->hasEdgeLink(e))
00257 return(1);
00258 return(0);
00259 }
00260
00261
00262 inline void Edge::computeNewRestLength()
00263 {
00264 setRestLength(getLength());
00265 }
00266 inline void Edge::setSplitNodes(Node* node0, Node* node1)
00267 {splitNode[0] = node0; splitNode[1] = node1;}
00268
00269 inline Node* Edge::getSplitNode(int which)
00270 {return splitNode[which];}
00271 inline void Edge::scaleRestingLengthFrom(Edge* oldEdge)
00272 {
00273 double factor = getLength()/oldEdge->getLength();
00274 setRestLength(factor*oldEdge->getRestLength());
00275 }
00276 #endif