/Users/craigcornelius/Projects/SPRING Mac Release 0.2/edge.h

Go to the documentation of this file.
00001 // $Id: edge.h,v 1.46 2006/05/24 16:52:42 sean Exp $
00002 // $Copyright: (c)2001 National Biocomputation Center, Stanford University $
00003 
00004 #ifndef Edge_H
00005 #define Edge_H
00006 
00007 #include "point3d.h"
00008 #include "util.h"
00009 #include "node.h"
00010 //#include "boundingsphere.h"
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     // every edge connects 2 nodes
00023     Node *node[2];
00024     
00025     ReallocableArray<Face*>  face;      // reallocable array of face pointers
00026     ReallocableArray<Tetra*> tetra;     // reallocable array of tetra pointers
00027     
00028     // physical properties
00029     double init_angle;         // initial angle between its 2 faces
00030     
00031     double restLength;
00032     double springConstant;
00033     double dampConstant;
00034     double marker;                // -1: no collision, [0,1]: collision param
00035     int cutting_marker;
00036     
00037     BoundingSphereLeaf* boundingsphere;
00038     // access to the dispenser class
00039     EdgeArray* edgearray_p;
00040     
00041     Node* splitNode[2];
00042     
00043 public:
00044         Point3D force;  // The force from the 1st to 2nd node.  Public for quick access.
00045 
00046 public:
00047     Edge();
00048     ~Edge();
00049     static const char* rcsid;
00050     static int debug;
00051     
00052     // initialization
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     // handy functions
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     // links to other arrays
00078     Node* getOtherNode(Node *n);
00079     Node* getNodeLink(int which);       // 0,1
00080     void replaceNodeLink(Node* old_node, Node* new_node);
00081     int hasNodeLink(Node* n);
00082     
00083     Face* getFaceLink(int which);       // 0,1
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     // simulation functions
00109     double getAngle(void);    // gets current angle between faces
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     // graphics functions
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     // collision functions
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 // This function returns the current length of this Edge 
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 // restLengthScale is to scale the constant inversely with the restLength
00190 // in order to get homogeneous behavior regardless of restLength
00191 // eg. if F = -k(x/x0 - 1) then k is Young's modulus, a tissue constant, but
00192 // we express F = -k(x - x0) so our k must be divided by x0 to get Young's mod.
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 // this is called with a Node, and will return the other Node that this Edge
00245 // is connected to, or NULL if this Edge is not connected to Node argument 
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 // this returns 1 if this is adjacent to e via a node, 0 else
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 // make a label containing the face num
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

Generated on Thu Aug 30 11:03:13 2007 for SPRING Mac by  doxygen 1.5.3