00001 #ifndef _Beh_Growing_txx
00002 #define _Beh_Growing_txx
00003
00004 #include "Beh_Growing.h"
00005 #include "vnl_cross.h"
00006 #include "vnl_math.h"
00007 #include "algo\vnl_matrix_inverse.h"
00008 #define PI 3.14159265
00009
00010 namespace mial {
00011
00012 template<class Type,class CrawlerPhysType>
00013 Beh_Growing<Type,CrawlerPhysType>::Beh_Growing()
00014 :Behavior<Type,3>("Beh_Growing"), nDims(3)
00015 {
00016
00017 }
00018 template<class Type,class CrawlerPhysType>
00019 bool Beh_Growing<Type,CrawlerPhysType>::run(typename Behavior<Type,3>::behaviorIn * i, std::stringstream *s)
00020 {
00021
00022 behaviorIn * in;
00023 if(i != NULL)
00024 in = (reinterpret_cast<behaviorIn *>(i));
00025 else
00026 {
00027 Error e;
00028 e.msg = "Stream call not supported";
00029 e.name = "Beh_Growing";
00030 throw e;
00031 }
00032
00033 MatrixType newNodes = growTo(in);
00034
00035 VectorType classes(in->vesselGeom->getNumNodesPerLayer());
00036 classes.fill(1);
00037 classes(0) = 0;
00038 in->vesselGeom->addLayer(newNodes,classes);
00039
00040
00041
00042 int springsKDef = 3;
00043 VectorType acSprings = in->vesselGeom->getActiveSprings(-1);
00044 VectorType vals = acSprings;
00045 vals.fill(springsKDef);
00046 (reinterpret_cast<CrawlerPhysType *>(physLayer))->setSpringsK(acSprings,vals);
00047
00048 acSprings = in->vesselGeom->getActiveSprings(1);
00049 vals = acSprings;
00050 vals.fill(0.5*springsKDef);
00051 (reinterpret_cast<CrawlerPhysType *>(physLayer))->setSpringsK(acSprings,vals);
00052 }
00053 template<class Type,class CrawlerPhysType>
00054 typename Beh_Growing<Type,CrawlerPhysType>::MatrixType Beh_Growing<Type,CrawlerPhysType>::growTo(behaviorIn* in)
00055 {
00056
00057
00058 int numNodesPerLayer = in->vesselGeom->getNumNodesPerLayer();
00059 int nodeNum = in->vesselGeom->getNumNodes() - numNodesPerLayer;
00060
00061 MatrixType points(numNodesPerLayer,nDims);
00062 points.fill(0);
00063 Type theta = 0;
00064 for(int i=0; i<numNodesPerLayer;i++)
00065 {
00066 theta= i*2*PI/(numNodesPerLayer-1);
00067 points(i,1) = sin(theta)*in->radius;
00068 points(i,2) = cos(theta)*in->radius;
00069
00070 }
00071
00072 VectorType finalAxis = (in->newAxis).normalize();
00073 MatrixType nodesXYZ = in->vesselGeom->getMatrixNodePositions();
00074 VectorType beta(nDims);
00075 if(nodeNum<=0)
00076 {
00077 beta(0) =0;
00078 beta(0) =1;
00079 beta(0) =0;
00080 }
00081 else
00082 {
00083
00084 beta = nodesXYZ.get_row(nodeNum+1) - nodesXYZ.get_row(nodeNum);
00085 }
00086
00087
00088
00089 beta.normalize();
00090 VectorType alpha = -vnl_cross_3d(beta,finalAxis);
00091 alpha.normalize();
00092 MatrixType Rtz(nDims,nDims);
00093 Rtz.fill(0);
00094 Rtz.set_row(0,alpha);
00095 Rtz.set_row(1,beta);
00096 Rtz.set_row(2,finalAxis);
00097
00098
00099
00100
00101 MatrixType Rtzi = vnl_matrix_inverse<Type>(Rtz) ;
00102 if(nodeNum<0)
00103 {
00104 for(int i=0; i<numNodesPerLayer;i++)
00105 points.set_row(i,Rtzi*points.get_row(i) + in->locXYZ);
00106 }
00107 else
00108 {
00109 for(int i=0; i<numNodesPerLayer;i++)
00110 points.set_row(i,Rtzi*points.get_row(i));
00111
00112
00113
00114
00115 VectorType p_norm = nodesXYZ.get_row(nodeNum) - nodesXYZ.get_row(nodeNum-numNodesPerLayer);
00116 VectorType growDirection = in->locXYZ - nodesXYZ.get_row(nodeNum);
00117 growDirection.normalize();
00118 p_norm.normalize();
00119 VectorType signVec(nDims);
00120 Type dp =0;
00121 Type maxDist =in->growDistance;
00122 Type dist =0;
00123 for(int a=0; a<numNodesPerLayer;a++)
00124 {
00125 signVec = points.get_row(a) - nodesXYZ.get_row(nodeNum);
00126 dp = dot_product(signVec,p_norm);
00127 if( dp <0)
00128 {
00129 dist = abs(dp/dot_product(p_norm,finalAxis));
00130 if(dist > maxDist)
00131 maxDist = dist;
00132 }
00133 }
00134 if(maxDist >2)
00135 maxDist = 2;
00136
00137
00138
00139
00140
00141 for(int i=0; i<numNodesPerLayer;i++)
00142 {
00143 points.set_row(i,points.get_row(i) + maxDist*growDirection);
00144 }
00145 }
00146
00147 return points;
00148 }
00149
00150 }
00151
00152 #endif