EvenStreamlinePlace.cpp
Go to the documentation of this file.
00001 /***
00002  Implementation of streamline class for path advection and separatrice generation
00003  ***/
00004 
00005 #include "tensor_field_nav_core/EvenStreamlinePlace.h"
00006 #include "tensor_field_nav_core/TfCore.h"
00007 EvenStreamlinePlace::EvenStreamlinePlace( int initsize=300)
00008 {
00009     evenstreamlines = new TrajectoryList(initsize);
00010     samplepts = (SamplePtList **)malloc(sizeof(SamplePtList*)*evenstreamlines->curMaxNumTrajs);
00011 
00012 
00013     if(samplepts == NULL)
00014     {
00015         exit(-1);
00016     }
00017 
00018     for(int i = 0; i < evenstreamlines->curMaxNumTrajs; i++)
00019     {
00020         samplepts[i] = new SamplePtList(100);
00021 
00022         if(samplepts[i] == NULL)
00023         {
00024             exit(-1);
00025         }
00026     }
00027     isAdd_push=false;
00028     push_rank=0.0;
00029     trianglelist = NULL;
00030     majorDensity = 13.5;
00031     mintenline_length=5.9;
00032     outside_push=icVector2(1,1);
00033 }
00034 
00035 EvenStreamlinePlace::~EvenStreamlinePlace()
00036 {
00037         delete evenstreamlines;
00038 
00039         if(samplepts != NULL)
00040         {
00041                 for(int i = 0; i < evenstreamlines->curMaxNumTrajs; i++)
00042                 {
00043                         if(samplepts[i] != NULL)
00044                                 free(samplepts[i]);
00045                 }
00046                 free(samplepts);
00047         }
00048 
00049 }
00050 void EvenStreamlinePlace::init()
00051 {
00052         int i, j;
00053         for(i = 0; i < evenstreamlines->curMaxNumTrajs; i++)
00054         {
00055                 //evenstreamlines->trajs[i] = (Trajectory*)malloc(sizeof(Trajectory));
00056                 evenstreamlines->trajs[i] = new Trajectory(i,200);
00057 
00058                 if(evenstreamlines->trajs[i] == NULL)
00059                 {
00060                         exit(-1);
00061                 }
00062         }
00063         for(i = 0; i < evenstreamlines->curMaxNumTrajs; i++)
00064         {
00065                 for(j = 0; j < samplepts[i]->curMaxNumSamplePts; j++)
00066                 {
00067                         //samplepts[i]->samples[j] = new SamplePt[1];
00068                         samplepts[i]->samples[j] = (SamplePt *)malloc(sizeof(SamplePt));
00069                         if(samplepts[i]->samples[j] == NULL)
00070                         {
00071                                 exit(-1);
00072                         }
00073                 }
00074         }
00075 }
00076 void EvenStreamlinePlace::set_default_parameters()
00077 {
00078         dsep = majorDensity*quadmesh->xinterval;    //using the radius of the object instead of the edge
00079         percentage_dsep = 0.5;
00080 
00081         discsize = 2.;
00082         sample_interval = std::min(0.05*dsep, quadmesh->xinterval/2.);
00083 
00084         every_nsample = 4;
00085         loopdsep = 0.4*quadmesh->xinterval; /*we now allow the loops to be closed*/
00086         dist2sing = 0.1*quadmesh->xinterval;
00087 
00088         streamlinelength = mintenline_length*quadmesh->xinterval;
00089         seeddist = 0.9*dsep;
00090         minstartdist = 0.9*dsep;
00091 
00092         euler_stepsize = quadmesh->xinterval/5.;
00093         predict_stepsize = quadmesh->xinterval;
00094 
00095 }
00096 
00097 void EvenStreamlinePlace::setTfCore(TfCore *tfCore){
00098     m_tfCore=tfCore;
00099     quadmesh=m_tfCore->quadmesh;
00100 }
00101 
00102 // compute the tensor inside a quad by binear interpolation
00103 void EvenStreamlinePlace::compute_tensor_at_quad(int face, double x, double y, icMatrix2x2 &ten)
00104 {
00105         //double xstart, xend, ystart, yend;
00106         //get_x_y_ranges(face, xstart, xend, ystart, yend);
00107 
00108         QuadCell *qc = quadmesh->quadcells[face];
00109 
00110         /*get the x coeff and y coeff*/
00111         double a = (x-qc->x_start_coord)/quadmesh->xinterval;
00112         double b = (y-qc->y_start_coord)/quadmesh->yinterval;
00113 
00114         if(fabs(a)<1e-6)
00115                 a = 0;
00116         if(fabs(b)<1e-6)
00117                 b = 0;
00118 
00119         QuadVertex *v00 = quadmesh->quad_verts[qc->verts[0]];
00120         QuadVertex *v01 = quadmesh->quad_verts[qc->verts[3]];
00121         QuadVertex *v10 = quadmesh->quad_verts[qc->verts[1]];
00122         QuadVertex *v11 = quadmesh->quad_verts[qc->verts[2]];
00123 
00124         /*the all the components of the interpolated tensor, respectively*/
00125         ten.entry[0][0] = bilinear_interpolate(a, b, v00->Jacobian.entry[0][0], v01->Jacobian.entry[0][0],
00126                 v10->Jacobian.entry[0][0], v11->Jacobian.entry[0][0]);
00127         ten.entry[0][1] = bilinear_interpolate(a, b, v00->Jacobian.entry[0][1], v01->Jacobian.entry[0][1],
00128                 v10->Jacobian.entry[0][1], v11->Jacobian.entry[0][1]);
00129         ten.entry[1][0] = bilinear_interpolate(a, b, v00->Jacobian.entry[1][0], v01->Jacobian.entry[1][0],
00130                 v10->Jacobian.entry[1][0], v11->Jacobian.entry[1][0]);
00131         ten.entry[1][1] = bilinear_interpolate(a, b, v00->Jacobian.entry[1][1], v01->Jacobian.entry[1][1],
00132                 v10->Jacobian.entry[1][1], v11->Jacobian.entry[1][1]);
00133 
00134 }
00135 bool EvenStreamlinePlace::is_in_cell(int id, double x, double y)
00136 {
00137         if(id<0) return false;
00138 
00139         QuadCell *q = quadmesh->quadcells[id];
00140         double xleft=q->x_start_coord-1.e-8;
00141         double xright=q->x_start_coord+quadmesh->xinterval+1.e-8;
00142         double ybuttom=q->y_start_coord-1.e-8;
00143         double yupper=q->y_start_coord+quadmesh->yinterval+1.e-8;
00144         if((x>=xleft && x<=xright)
00145                 &&(y>=ybuttom && y<=yupper))
00146                 return true;
00147         return false;
00148 
00149 }
00150 int  EvenStreamlinePlace::get_cellID_givencoords(double x, double y)
00151 {
00152         int i=(x-quadmesh->xstart)/quadmesh->xinterval;
00153         int j=(y-quadmesh->ystart)/quadmesh->yinterval;
00154 
00155         //if(i<0) i=0;
00156         //if(j<0) j=0;
00157 
00158         if(i==quadmesh->XDIM-1) i=quadmesh->XDIM-2;
00159         if(j==quadmesh->YDIM-1) j=quadmesh->YDIM-2;
00160 
00161         return (j*(quadmesh->XDIM-1)+i);
00162 }
00163 void EvenStreamlinePlace::compute_phi_in_quad(int face, double x, double y, double &phi)
00164 {
00165 
00166         QuadCell *qc = quadmesh->quadcells[face];
00167 
00168         /*get the x coeff and y coeff*/
00169         double a = (x-qc->x_start_coord)/quadmesh->xinterval;
00170         double b = (y-qc->y_start_coord)/quadmesh->yinterval;
00171 
00172         if(fabs(a)<1e-6)
00173                 a = 0;
00174         if(fabs(b)<1e-6)
00175                 b = 0;
00176 
00177         /*obtain the vertices of this cell in the order of
00178           v00 v01
00179           v10 v11
00180         */
00181         QuadVertex *v00 = quadmesh->quad_verts[qc->verts[0]];
00182         QuadVertex *v01 = quadmesh->quad_verts[qc->verts[3]];
00183         QuadVertex *v10 = quadmesh->quad_verts[qc->verts[1]];
00184         QuadVertex *v11 = quadmesh->quad_verts[qc->verts[2]];
00185 
00186         /*the all the components of the interpolated tensor, respectively*/
00187         phi = bilinear_interpolate(a, b, v00->phi, v01->phi,
00188                 v10->phi, v11->phi);
00189 
00190 }
00191 void  EvenStreamlinePlace::reset(){
00192     evenstreamlines->reset();
00193     (*samplepts)->reset();
00194 }
00195 
00196 //locally convert tensor field into vector field based on robot forward direction
00197 void EvenStreamlinePlace::get_tenvec_quad(double cur_p[2], double vec[2])
00198 {
00199         double t[4];
00200         icMatrix2x2 ten;
00201         icVector2 ev[2];
00202         double re;
00203 
00204         compute_tensor_at_quad(g_face, cur_p[0], cur_p[1], ten);
00205 
00206                 /*  need to obtain the interpolated phi  */
00207     m_tfCore->cal_eigen_vector_sym(ten, ev);
00208 
00209         if(g_type == 1) /*use minor eigen vector field*/
00210                 ev[0] = ev[1];
00211 
00212         re = dot(tenline_dir_global, ev[0]);
00213         if(re<0) 
00214                 ev[0] = -ev[0];
00215 
00216     //a simple way for avoding collision, keep the robot a distance to obstacles
00217     if(isAdd_push){
00218         if(push_rank<0.1)
00219             ev[0]=outside_push;
00220         else
00221             ev[0]=ev[0]+push_rank*outside_push;
00222    //     isAdd_push=false;
00223     }
00224     normalize(ev[0]);
00225         vec[0] = ev[0].entry[0];
00226         vec[1] = ev[0].entry[1];
00227 }
00228 
00229 // Runge-kutta iteration for path generation
00230 void EvenStreamlinePlace::RK23_2d(double pre_p[2], double next_p[2], double &hstep_loc, double &hnext,
00231                          double eps, double &eps_did)
00232 {
00233         double dp0[2], dp1[2];
00234         double temp[2] = {0.};
00235         double t_vec[2];
00236 
00237         /*compute dp0*/
00238         get_tenvec_quad(pre_p, t_vec);
00239         dp0[0] = hstep_loc*t_vec[0];
00240         dp0[1] = hstep_loc*t_vec[1];
00241 
00242         /*compute dp1*/
00243         temp[0]=pre_p[0]+dp0[0];
00244         temp[1]=pre_p[1]+dp0[1];
00245         get_tenvec_quad(temp, t_vec);
00246         dp1[0] = hstep_loc*t_vec[0];
00247         dp1[1] = hstep_loc*t_vec[1];
00248 
00249 
00250         /*compute the next position using dp0, dp1, dp2 and dp3*/
00251         next_p[0]=pre_p[0]+dp0[0]/2+dp1[0]/2;
00252         next_p[1]=pre_p[1]+dp0[1]/2+dp1[1]/2;
00253 
00254         /*evaluate the error*/
00255         get_tenvec_quad(next_p, t_vec);
00256 
00257         icVector2 ep;
00258         ep.entry[0]=(dp1[0]-hstep_loc*t_vec[0])/3;
00259         ep.entry[1]=(dp1[1]-hstep_loc*t_vec[1])/3;
00260 
00261         double error = length(ep);
00262 
00263         /*adjust the step size accordingly*/
00264         hnext = hstep_loc;
00265         if(error<eps/10.) hnext = 2*hstep_loc;
00266         if(error>eps*5) hnext = hstep_loc/2;
00267 
00268         eps_did = error;
00269 }
00270 
00271 bool EvenStreamlinePlace::get_nextpt_RK23_ten_quad(double first[2], double second[2], int &face_id, int type)
00272 {
00273         g_face = face_id;
00274         g_type = type;
00275 
00276         double t_vec[2] = {0.};
00277         get_tenvec_quad(first, t_vec);
00278         icVector2 vec;
00279         vec.entry[0] = t_vec[0];
00280         vec.entry[1] = t_vec[1];
00281     if(length(vec) < 1.e-10){
00282        evenstreamlines->trajs[evenstreamlines->ntrajs]->is_reach_degpt=true;
00283        return false;
00284     }
00285 
00286         double eps_did, eps = 1.e-9;
00287         int i;
00288         double hstep_loc, hnext;
00289 
00290         hstep_loc = predict_stepsize;
00291         if(hstep_loc > quadmesh->xinterval/2.)
00292         {
00293                 hstep_loc = quadmesh->xinterval/2.;
00294                 predict_stepsize = hstep_loc;
00295         }
00296 
00297 
00298         for(i=0; i<5; i++)
00299         {
00300                 hstep_loc = predict_stepsize;
00301                 RK23_2d(first, second, hstep_loc, hnext, eps, eps_did);
00302                 predict_stepsize = hnext;
00303                 if(eps_did<eps)
00304                         break;
00305         }
00306     isAdd_push=false;
00307         return true;
00308 }
00309 
00310 int EvenStreamlinePlace::get_nextpt_RK23_ten_quad(double first[2], double second[2], int &face_id, int type,int index,int sep_index)
00311 {
00312     g_face = face_id;
00313     g_type = type;
00314 
00315     double t_vec[2] = {0.};
00316     get_tenvec_quad(first, t_vec);
00317     icVector2 vec;
00318     vec.entry[0] = t_vec[0];
00319     vec.entry[1] = t_vec[1];
00320     if(length(vec) < 1.e-10) return -2;
00321 
00322     for(int i=0; i< m_tfCore->validDegpts.size(); i++){
00323         if(i==index)continue;
00324         double dist=sqrt(pow(first[0]-m_tfCore->validDegpts[i].gcx,2)+pow(first[1]-m_tfCore->validDegpts[i].gcy,2));
00325         if(dist < 2.5*1.e-2) {
00326          // m_tfCore->insertLinks(index,i);
00327           evenstreamlines->trajs[evenstreamlines->ntrajs]->linked_degpt_id=i;
00328           //m_tfCore->validDegpts[index].links_index[sep_index]=i;
00329           return i;
00330         }
00331     }
00332 
00333     double eps_did, eps = 1.e-9;
00334     int i;
00335     double hstep_loc, hnext;
00336 
00337     hstep_loc = predict_stepsize;
00338     if(hstep_loc > quadmesh->xinterval/2.)
00339     {
00340         hstep_loc = quadmesh->xinterval/2.;
00341         predict_stepsize = hstep_loc;
00342     }
00343 
00344 
00345     for(i=0; i<5; i++)
00346     {
00347         hstep_loc = predict_stepsize;
00348         RK23_2d(first, second, hstep_loc, hnext, eps, eps_did);
00349         predict_stepsize = hnext;
00350         if(eps_did<eps)
00351             break;
00352     }
00353     return -1;
00354 }
00355 void EvenStreamlinePlace::cal_euclidean_dist_2(int triangle, double p[3], double dsep, double discsize, 
00356                                                                                            DynList_Int *trianglelist)
00357 {
00359         QuadCell *face = quadmesh->quadcells[triangle];
00360         QuadVertex *vert;
00361         QuadEdge *cur_edge;
00362         icVector3 dis;
00363 
00365         trianglelist->nelems = 0;
00366         trianglelist->add_New(triangle);
00367         int cur_id = 0;
00368         int i, j;
00369 
00370         while(cur_id < trianglelist->nelems)
00371         {
00372                 face = quadmesh->quadcells[trianglelist->elems[cur_id]];
00373 
00374                 for(i = 0; i < face->nverts; i++)
00375                 {
00376                         vert = quadmesh->quad_verts[face->verts[i]];
00377 
00378                         if(vert->visited)
00379                                 continue;
00380 
00381                         dis.entry[0] = vert->x - p[0];
00382                         dis.entry[1] = vert->y - p[1];
00383 
00384                         vert->distance = length(dis); /*compute the Euclidean distance*/
00385 
00386                         vert->visited = true; //set the visited flag
00387                         if(vert->distance > discsize*dsep)
00388                                 continue;
00389 
00392                         for(j = 0; j < vert->ncells; j++)
00393                         {
00394                                 QuadCell *c = vert->cells[j];
00395 
00396                                 if(c->index < 0) //reach the boundary!
00397                                         continue;
00398                                 trianglelist->add_New(c->index);
00399                         }
00400                 }
00401 
00402                 cur_id++;
00403         }
00404 
00405         for(i=0; i<trianglelist->nelems; i++)
00406         {
00407                 face = quadmesh->quadcells[trianglelist->elems[i]];
00408                 face->visited = false;
00409                 for(j=0; j<face->nverts; j++)
00410                 {
00411                         vert = quadmesh->quad_verts[face->verts[j]];
00412                         vert->visited = false;
00413                 }
00414         }
00415 }
00416 
00417 void EvenStreamlinePlace::reset_dist(DynList_Int *trianglelist)
00418 {
00419         int i, j;
00420         QuadCell *face;
00421         QuadVertex *v;
00422         for(i = 0; i < trianglelist->nelems; i++)
00423         {
00424                 face = quadmesh->quadcells[trianglelist->elems[i]];
00425                 face->visited = false;
00426                 for(j = 0; j < 3; j++)
00427                 {
00428                         v = quadmesh->quad_verts[face->verts[j]];
00429                         v->distance = 1e50;
00430                 }
00431         }
00432 }
00433 
00434 //compare the current point with the sampling point on itself!
00435 bool EvenStreamlinePlace::close_to_cur_samplePt(double p[2], int triangle, SamplePt **samples, int num_samples,
00436                                                                                                 double separate_dist, double discsize, double sample_interval)
00437 {
00438         int i;
00439         double dist/*, alpha[3], a, b*/;
00440         int stop_locate = floor(separate_dist/sample_interval)+3;
00441         QuadCell *face;
00442         QuadVertex *v;
00443         icVector2 VP;
00444 
00445         int *NearbyTriangles = NULL;
00446         int num_triangles = 0;
00447 
00448 
00450         trianglelist = new DynList_Int();
00451 
00452         trianglelist->nelems = 0;
00453         cal_euclidean_dist_2(triangle, p, separate_dist, discsize, trianglelist);
00454         NearbyTriangles = trianglelist->elems;
00455         num_triangles = trianglelist->nelems;
00456 
00457 
00458         for(i = 0 ; i < num_samples-stop_locate; i++)
00459         {
00460                 if(!is_repeated_elem(NearbyTriangles, samples[i]->triangle, num_triangles))
00461                         continue;
00462 
00463                 face = quadmesh->quadcells[samples[i]->triangle];
00464 
00465                 VP.entry[0] = p[0]-samples[i]->gpt[0];
00466                 VP.entry[1] = p[1]-samples[i]->gpt[1];
00467 
00468                 dist = length(VP);  /*calculate the Euclidean distance*/
00469 
00470                 if(dist < separate_dist)
00471                 {
00472 
00473                         reset_dist(trianglelist);
00474                         delete trianglelist;
00475 
00476                         return true;
00477                 }
00478         }
00479 
00480         reset_dist(trianglelist);
00481         delete trianglelist;
00482         return false;
00483 }
00484 
00485 //robot path generation
00486 int EvenStreamlinePlace::trace_majRoad_in_quad(int &face_id, double globalp[2], int type, 
00487                                         double dtest, double loopsep, double dist2sing, 
00488                                         double sample_interval, double discsize, int &flag)
00489 {
00490 
00491         int i;
00492         double pre_point[2];
00493 
00494         double origin_dtest=dtest;
00495         double origin_dist2sing=dist2sing;
00496         double origin_loopsep=loopsep;
00497         
00498         if(!is_in_cell(face_id, globalp[0], globalp[1]))
00499         {
00500                 face_id = get_cellID_givencoords(globalp[0], globalp[1]);
00501         }
00502 
00503         if(face_id < 0 || face_id>=quadmesh->nfaces)
00504                 return -1;
00505 
00506         QuadCell *face = quadmesh->quadcells[face_id];
00507         QuadCell *pre_f = face;
00508 
00509         
00511 
00512         CurvePoints *temp_point_list = (CurvePoints*) malloc(sizeof(CurvePoints) * 200);
00513 
00514         if(temp_point_list == NULL)
00515         {
00516                 exit(-1);
00517         }
00518 
00519         int NumPoints = 0;
00520         
00521         /*the tracing will be performed under the global frame*/
00522         globalface = face_id;
00523 
00524         pre_point[0] = globalp[0];
00525         pre_point[1] = globalp[1];
00526 
00528     for(i = 0; i < 200; i++)
00529         {
00531                 if(is_in_cell(face_id, globalp[0], globalp[1]))
00532                 {
00534 
00535                         temp_point_list[NumPoints].gpx = globalp[0];
00536                         temp_point_list[NumPoints].gpy = globalp[1];
00537                         temp_point_list[NumPoints].triangleid = face->index;  
00538                         NumPoints++;
00539 
00540                         pre_point[0] = globalp[0];
00541                         pre_point[1] = globalp[1];
00542             //if robot' path was cut by obstacles, then recompute the path to ensure robot safety.
00543             //Detecting the close contour of obstacles and adding a perpendicular force
00544             if(m_tfCore->reGenPath){
00545                 double min_dist=std::numeric_limits<double>::max();
00546                 double target_x_dist,target_y_dist;
00547                 int target_j,target_i;
00548                 for(int i=0;i<m_tfCore->contours2Field.size();i++)
00549                 {
00550                     for (int j=0;j<m_tfCore->contours2Field[i].size();j++)
00551                     {
00552                         double x_dist=pre_point[0]-m_tfCore->contours2Field[i][j].x;
00553                         double y_dist=pre_point[1]-m_tfCore->contours2Field[i][j].y;
00554                         double cur_dist=sqrt(x_dist*x_dist+y_dist*y_dist);
00555                         if(min_dist>cur_dist)
00556                         {
00557                             min_dist=cur_dist;
00558                             target_i=i;
00559                             target_j=j;
00560                             target_x_dist=x_dist;
00561                             target_y_dist=y_dist;
00562                         }
00563                     }
00564                 }
00565                 min_dist=min_dist*m_tfCore->realWorld_to_field_scale;
00566                 if (min_dist<DANGERDIST)
00567                 {
00568                     if (min_dist<DANGERDIST/3)
00569                         push_rank=0;
00570                     else
00571                         push_rank=(DANGERDIST-min_dist)/DANGERDIST*1.5+0.5;
00572                     icVector2 tmp_dir(target_x_dist,target_y_dist);
00573                     //
00574                     std::vector<cv::Point2f> points;
00575                     if(target_j<3){
00576                        for(int k=0;k<5;k++)
00577                            points.push_back(cv::Point2f(m_tfCore->contours2Field[target_i][k].x,m_tfCore->contours2Field[target_i][k].y));
00578                     }else if(target_j>m_tfCore->contours2Field[target_i].size()-6){
00579                        for(int k=m_tfCore->contours2Field[target_i].size()-5;k<m_tfCore->contours2Field[target_i].size();k++)
00580                            points.push_back(cv::Point2f(m_tfCore->contours2Field[target_i][k].x,m_tfCore->contours2Field[target_i][k].y));
00581                     }else{
00582                        for(int k=target_j-2;k<target_j+3;k++)
00583                            points.push_back(cv::Point2f(m_tfCore->contours2Field[target_i][k].x,m_tfCore->contours2Field[target_i][k].y));
00584                     }
00585                     cv::Vec4f line;
00586                     cv::fitLine(cv::Mat(points), line, CV_DIST_L2, 0, 0.01, 0.01);
00587                     icVector2 tmp_vec(-line[1],line[0]);
00588                     if(dot(tmp_vec,tmp_dir)<0) tmp_vec=-tmp_vec;
00589                     isAdd_push=true;
00590                     outside_push=tmp_vec;
00591                 }
00592             }
00593             //
00594             /*change to use other integration scheme */
00595                         if(get_nextpt_RK23_ten_quad(pre_point, globalp, face_id, type))
00596                         //if(get_nextpt_2ndeuler_ten_quad(pre_point, globalp, face_id, type))
00597                         {
00598                 /*obtain the global direction of current tensor line */
00599                                 tenline_dir_global.entry[0] = globalp[0] - pre_point[0];
00600                                 tenline_dir_global.entry[1] = globalp[1] - pre_point[1];
00601 
00602                 if (evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs+NumPoints-1!=0){
00603                     if (evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs+NumPoints-1<m_tfCore->interFrameNum*NLIENSPERFRAME+1){
00604                         if ((evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs+NumPoints-1)%NLIENSPERFRAME==0)
00605                         {
00606                             m_tfCore->update_tensor_field();
00607                         }
00608                     }
00609 
00610                 }
00611 //                              ////We may also need to compare the current point with the sampling point on itself!
00612 //                              if(close_to_cur_samplePt(globalp, face_id, samplepts[evenstreamlines->ntrajs]->samples,
00613 //                                      samplepts[evenstreamlines->ntrajs]->nsamples, loopsep, discsize, sample_interval)) //scale the separate distance
00614 //                              {
00615 //                                      if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00616 //                                              (temp_point_list, NumPoints))
00617 //                                      {
00618 //                                              ////Not enough memory
00619 //                                              flag = 4;
00620 //                                              free(temp_point_list);
00621 //                                              return face_id;
00622 //                                      }
00623 
00624 //                    flag = 3;
00625 //                                      free(temp_point_list);
00626 //                                      return face_id;
00627 //                              }
00628 //                if(evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs+NumPoints-1>1000){
00629 //                    free(temp_point_list);
00630 //                    flag=3;
00631 //                    return face_id;
00632 //                }
00633                         }
00634 
00635                         else{  
00636                                 flag = 1;
00637 
00639                 
00640                                 if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00641                                         (temp_point_list, NumPoints))
00642                                 {
00644                                         flag = 4;
00645                                         free(temp_point_list);
00646                                         return face_id;
00647                                 }
00648 
00649                                 free(temp_point_list);
00650 
00651                                 return face_id;
00652                         }
00653                 }
00654 
00655 
00656 
00658                 else{
00659 
00661                         int PassVertornot = 0;
00662                         get_next_cell_2(face_id, pre_point, globalp, PassVertornot, type);
00663 
00664                         //if(face_id==pre_f->index)
00665                         //{
00666                         //      int test=0;
00667                         //}
00668                         
00669                         if(PassVertornot>0)  /*cross a vertex*/
00670                         {
00671                 /*obtain the global direction of current tensor line*/
00672                                 tenline_dir_global.entry[0] = pre_point[0] - globalp[0];
00673                                 tenline_dir_global.entry[1] = pre_point[1] - globalp[1];
00674 
00675                                 
00676                                 temp_point_list[NumPoints].gpx = globalp[0];
00677                                 temp_point_list[NumPoints].gpy = globalp[1];
00678                 temp_point_list[NumPoints].triangleid = face_id/*face->index*/;  //
00679                                 NumPoints++;
00680 
00681                                 temp_point_list[NumPoints].gpx = pre_point[0];
00682                                 temp_point_list[NumPoints].gpy = pre_point[1];
00683                 temp_point_list[NumPoints].triangleid = face_id;  //
00684                                 NumPoints++;
00685                         }
00686                         else{
00687                 /*obtain the global direction of current tensor line */
00688                                 tenline_dir_global.entry[0] = globalp[0] - pre_point[0];
00689                                 tenline_dir_global.entry[1] = globalp[1] - pre_point[1];
00690 
00692                                 temp_point_list[NumPoints].gpx = globalp[0];
00693                                 temp_point_list[NumPoints].gpy = globalp[1];
00694                 temp_point_list[NumPoints].triangleid = face->index;  //
00695                                 NumPoints++;
00696                         }
00697 
00698 
00699                         if(NumPoints > 1){
00701                                 if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00702                                         (temp_point_list, NumPoints))
00703                            {   
00704                                    flag = 4;
00705                                    free(temp_point_list);
00706                                    return face_id;
00707                            }
00708                         }
00709 
00710                         free(temp_point_list);
00711                         return face_id;
00712                 }
00713         
00714         }
00715 
00716         if(NumPoints > 0)
00717                 if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00718                                                 (temp_point_list, NumPoints))
00719                                                 flag=4;
00720 
00721         free(temp_point_list);
00722         return face_id;
00723 }
00724 
00725 //separatix generation, a little differrence with path generation
00726 int EvenStreamlinePlace::trace_separatrix_in_quad(int &face_id, double globalp[2], int type,
00727     double dtest, double loopsep, double dist2sing,
00728     double sample_interval, double discsize, int &flag,int index,int sep_index){
00729 
00730     int i;
00731     double pre_point[2];
00732 
00733     double origin_dtest=dtest;
00734     double origin_dist2sing=dist2sing;
00735     double origin_loopsep=loopsep;
00736 
00737     if(!is_in_cell(face_id, globalp[0], globalp[1]))
00738     {
00739         face_id = get_cellID_givencoords(globalp[0], globalp[1]);
00740     }
00741 
00742     if(face_id < 0 || face_id>=quadmesh->nfaces)
00743         return -1;
00744 
00745     QuadCell *face = quadmesh->quadcells[face_id];
00746     QuadCell *pre_f = face;
00747 
00748 
00750 
00751     CurvePoints *temp_point_list = (CurvePoints*) malloc(sizeof(CurvePoints) * 200);
00752 
00753     if(temp_point_list == NULL)
00754     {
00755         exit(-1);
00756     }
00757 
00758     int NumPoints = 0;
00759 
00760     /*the tracing will be performed under the global frame*/
00761     globalface = face_id;
00762 
00763     pre_point[0] = globalp[0];
00764     pre_point[1] = globalp[1];
00765 
00767     for(i = 0; i < 200; i++)
00768     {
00770         if(is_in_cell(face_id, globalp[0], globalp[1]))
00771         {
00773 
00774             temp_point_list[NumPoints].gpx = globalp[0];
00775             temp_point_list[NumPoints].gpy = globalp[1];
00776             temp_point_list[NumPoints].triangleid = face->index;
00777             NumPoints++;
00778 
00779             pre_point[0] = globalp[0];
00780             pre_point[1] = globalp[1];
00781 
00782             int tmp_index=get_nextpt_RK23_ten_quad(pre_point, globalp, face_id, type,index,sep_index);
00783             if(tmp_index==-1)
00784             //if(get_nextpt_2ndeuler_ten_quad(pre_point, globalp, face_id, type))
00785             {
00786                 /*obtain the global direction of current tensor line */
00787                 tenline_dir_global.entry[0] = globalp[0] - pre_point[0];
00788                 tenline_dir_global.entry[1] = globalp[1] - pre_point[1];
00789 
00790                 /*      we need to combine the density map to change
00791                         the separation distance automatically
00792                 */
00794                 if(close_to_cur_samplePt(globalp, face_id, samplepts[evenstreamlines->ntrajs]->samples,
00795                     samplepts[evenstreamlines->ntrajs]->nsamples, loopsep, discsize, sample_interval)) //scale the separate distance
00796                 {
00797                     if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00798                         (temp_point_list, NumPoints))
00799                     {
00801                         flag = 4;
00802                         free(temp_point_list);
00803                         return face_id;
00804                     }
00805 
00806                     flag = 3; //form a loop!
00807 
00808                     free(temp_point_list);
00809                     return face_id;
00810                 }
00811                 if(globalp[0]<m_tfCore->leftBottom[0] || globalp[0]>m_tfCore->rightTop[0] || globalp[1]<m_tfCore->leftBottom[1] || globalp[1]>m_tfCore->rightTop[1])
00812                 {
00813                     flag=5;
00814                     evenstreamlines->trajs[evenstreamlines->ntrajs]->is_reach_unknown=true;
00815                     return face_id;
00816                 }
00817 
00818             }
00819 
00820             else{  
00821                 if(tmp_index!=-2){
00822                     temp_point_list[NumPoints].gpx = m_tfCore->validDegpts[tmp_index].gcx;
00823                     temp_point_list[NumPoints].gpy = m_tfCore->validDegpts[tmp_index].gcy;
00824                     temp_point_list[NumPoints].triangleid = face->index;
00825                     NumPoints++;
00826                 }
00827                 flag = 1;
00828 
00830 
00831                 if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00832                     (temp_point_list, NumPoints))
00833                 {
00835                     ROS_ERROR("Not enough memory");
00836                     flag = 4;
00837                     free(temp_point_list);
00838                     return face_id;
00839                 }
00840 
00841                 free(temp_point_list);
00842 
00843                 return face_id;
00844             }
00845         }
00846 
00847 
00848 
00850         else{
00851 
00853             int PassVertornot = 0;
00854             get_next_cell_2(face_id, pre_point, globalp, PassVertornot, type);
00855 
00856             //if(face_id==pre_f->index)
00857             //{
00858             //  int test=0;
00859             //}
00860 
00861             if(PassVertornot>0)  /*cross a vertex*/
00862             {
00863                 /*obtain the global direction of current tensor line */
00864                 tenline_dir_global.entry[0] = pre_point[0] - globalp[0];
00865                 tenline_dir_global.entry[1] = pre_point[1] - globalp[1];
00866 
00867                 
00868                 temp_point_list[NumPoints].gpx = globalp[0];
00869                 temp_point_list[NumPoints].gpy = globalp[1];
00870                 temp_point_list[NumPoints].triangleid = face_id/*face->index*/;  //
00871                 NumPoints++;
00872 
00873                 temp_point_list[NumPoints].gpx = pre_point[0];
00874                 temp_point_list[NumPoints].gpy = pre_point[1];
00875                 temp_point_list[NumPoints].triangleid = face_id;  //
00876                 NumPoints++;
00877             }
00878             else{
00879                 /*obtain the global direction of current tensor line*/
00880                 tenline_dir_global.entry[0] = globalp[0] - pre_point[0];
00881                 tenline_dir_global.entry[1] = globalp[1] - pre_point[1];
00882 
00884                 temp_point_list[NumPoints].gpx = globalp[0];
00885                 temp_point_list[NumPoints].gpy = globalp[1];
00886                 temp_point_list[NumPoints].triangleid = face->index;  //
00887                 NumPoints++;
00888             }
00889 
00890 
00891             if(NumPoints > 1){
00893                 if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00894                     (temp_point_list, NumPoints))
00895                {   
00896                    flag = 4;
00897                    free(temp_point_list);
00898                    return face_id;
00899                }
00900             }
00901 
00902             free(temp_point_list);
00903             return face_id;
00904         }
00905 
00906     }
00907 
00908     if(NumPoints > 0)
00909         if(!evenstreamlines->trajs[evenstreamlines->ntrajs]->store_to_global_line_segs
00910                         (temp_point_list, NumPoints))
00911                         flag=4;
00912 
00913     free(temp_point_list);
00914     return face_id;
00915 
00916 }
00917 
00918 void  EvenStreamlinePlace::get_cell_through_ver(int vertid, int &cell, int type)
00919 {
00920         QuadVertex *v = quadmesh->quad_verts[vertid];
00921         icVector2 vec; 
00922         if(type == 0)
00923                 vec = v->major;
00924         else
00925                 vec = v->minor;
00926 
00927         double re=dot(vec, tenline_dir_global);
00928         if(re<0) vec=-vec;
00929         normalize(vec);
00930 
00931         //double x, y;
00932 
00933         double x = v->x+0.02*quadmesh->xinterval*vec.entry[0];
00934         double y = v->y+0.02*quadmesh->xinterval*vec.entry[1];
00935         cell = get_cellID_givencoords(x, y);
00936 }
00937 bool EvenStreamlinePlace::cross_vertex_ten_quad(int &face_id, double cur_p[2], double pre_p[2], int &passornot, int type)
00938 {
00939         int i;
00940         double vert[2];
00941         double max_alpha ;
00942         int newtriangleid = 0;
00943         int crossVert;
00944         QuadCell *face = quadmesh->quadcells[face_id];
00945         QuadVertex *v;
00946 
00947         double A, B, C, pending;
00948         A = pre_p[1] - cur_p[1];
00949         B = cur_p[0] - pre_p[0];
00950         C = (pre_p[0]*cur_p[1] - cur_p[0]*pre_p[1]);
00951 
00952         for(i = 0; i < face->nverts; i++)
00953         {
00954                 v = quadmesh->quad_verts[face->verts[i]];
00955                 vert[0] = v->x;
00956                 vert[1] = v->y;
00957                 pending = A*vert[0] + B*vert[1] + C;
00959                 //if(fabs(pending) == 0.0) ////passing the vertex
00960                 if(fabs(pending) <=1.e-8) 
00961                 {
00963                         double t;
00964                         if(pre_p[0] != cur_p[0])
00965                         {
00966                                 t = (vert[0] - pre_p[0])/(cur_p[0] - pre_p[0]);
00967 
00968                         }
00969                         else{
00970                                 t = (vert[1] - pre_p[1])/(cur_p[1] - pre_p[1]);
00971                         }
00972 
00973                         if(t < 0 || t > 1)
00974                         {
00975                                 passornot = 0;
00976                                 continue;
00977                         }
00978 
00979                         crossVert = face->verts[i];
00980 
00982                         newtriangleid = face_id;
00983 
00984                         get_cell_through_ver(crossVert, newtriangleid, type);
00985                         if(newtriangleid <0 || newtriangleid>=quadmesh->nfaces) 
00986                                 return false;
00987                         face_id = newtriangleid;
00988                         passornot = i+1;
00989                         cur_p[0] = quadmesh->quad_verts[crossVert]->x;
00990                         cur_p[1] = quadmesh->quad_verts[crossVert]->y;
00991                         //pre_p[0] = quadmesh->quad_verts[crossVert]->x;
00992                         //pre_p[1] = quadmesh->quad_verts[crossVert]->y;
00993 
00994             /*make it off the vertex a little bit */
00995                         icVector2 tvec;
00996                         QuadVertex *tv = quadmesh->quad_verts[crossVert];
00997                         if(type==0)
00998                                 tvec=tv->major;
00999                         else
01000                                 tvec=tv->minor;
01001                         normalize(tvec);
01002                         double re=dot(tvec, tenline_dir_global);
01003                         if(re<0) tvec=-tvec;
01004 
01005                         /*  try to avoid the vertex  */
01006                         pre_p[0] = tv->x+0.01*quadmesh->xinterval*tvec.entry[0];
01007                         pre_p[1] = tv->y+0.01*quadmesh->xinterval*tvec.entry[1];
01008 
01009                         int test_cell=get_cellID_givencoords(pre_p[0], pre_p[1]);
01010 
01011                         //if(test_cell != newtriangleid)
01012                         //{
01013                         //      int test=0;
01014                         //}
01015 
01016                         return true;
01017                 }
01018         }
01019 
01020         passornot = 0;
01021         return false;
01022 }
01023 void EvenStreamlinePlace::get_next_cell_2(int &face_id, double pre[2], double cur[2], 
01024                                          int &PassVertornot, int type)
01025 {
01026 
01027         /*for horizontal cases*/
01028         if(fabs(cur[1]-pre[1])<1e-8)
01029         {
01030                 if(cur[0]>pre[0] && cur[0]<=quadmesh->xend-1.e-8) /*move to the right cell*/
01031                 {
01032                         cur[0]=quadmesh->quadcells[face_id]->x_start_coord+quadmesh->xinterval+1.1e-8;
01033                         face_id++;
01034                         return;
01035                 }
01036 
01037                 else if(cur[0]>pre[0] && cur[0]>quadmesh->xend-1.e-8) /*out of mesh*/
01038                 {
01039                         face_id=-1;
01040                         return;
01041                 }
01042 
01043                 else if(cur[0]<pre[0] && cur[0]>=quadmesh->xstart+1.e-8)/*move to the left cell*/
01044                 {
01045                         cur[0]=quadmesh->quadcells[face_id]->x_start_coord-1.1e-8;
01046                         face_id--;
01047                         return;
01048                 }
01049 
01050                 else if(cur[0]<pre[0] && cur[0]<quadmesh->xstart+1.e-8)/*out of mesh*/
01051                 {
01052                         face_id=-1;
01053                         return;
01054                 }
01055         }
01056 
01057         /*for vertical cases*/
01058         if(fabs(cur[0]-pre[0])<1e-8)
01059         {
01060                 if(cur[1]>pre[1] && cur[1]<=quadmesh->yend-1.e-8) /*move to the upper cell*/
01061                 {
01062                         cur[1]=quadmesh->quadcells[face_id]->y_start_coord+quadmesh->yinterval+1.1e-8;
01063                         face_id+=(quadmesh->XDIM-1);
01064                         return;
01065                 }
01066 
01067                 else if(cur[1]>pre[1] && cur[1]>quadmesh->yend-1.e-8)
01068                 {
01069                         face_id = -1;
01070                         return;
01071                 }
01072 
01073                 else if(cur[1]<pre[1] && cur[1]>=quadmesh->ystart+1.e-8) /*move to the lower cell*/
01074                 {
01075                         cur[1]=quadmesh->quadcells[face_id]->y_start_coord-1.1e-8;
01076                         face_id-=(quadmesh->XDIM-1);
01077                         return;
01078                 }
01079 
01080                 else if(cur[1]<pre[1] && cur[1]<quadmesh->ystart+1.e-8)
01081                 {
01082                         face_id = -1;
01083                         return;
01084                 }
01085         }
01086 
01087         int pre_f = face_id;
01088         if(cross_vertex_ten_quad(face_id, cur, pre, PassVertornot, type))
01089                 return;
01090 
01091         face_id = pre_f;
01092 
01093         double t[2];
01094         double C[2], D[2];
01095         QuadCell *f = quadmesh->quadcells[face_id];
01096 
01097         if(cur[0]<f->x_start_coord) /*left */
01098         {
01099                 /*calculate the intersection between edge e3 and L*/
01100                 C[0] = quadmesh->quad_verts[f->verts[0]]->x;
01101                 C[1] = quadmesh->quad_verts[f->verts[0]]->y;
01102                 D[0] = quadmesh->quad_verts[f->verts[3]]->x;
01103                 D[1] = quadmesh->quad_verts[f->verts[3]]->y;
01104                 if(GetIntersection2(pre, cur, C, D, t)==1)
01105                 {
01106                         face_id = face_id-1;
01107                         /*calculate the intersection*/
01108                         cur[0]=C[0]+t[1]*(D[0]-C[0]);
01109                         //cur[0]=f->x_start_coord-1.e-8;
01110                         cur[1]=C[1]+t[1]*(D[1]-C[1]);
01111 
01112                         return;
01113                 }
01114         }
01115         else if(cur[0]>f->x_start_coord+quadmesh->xinterval)  /*right*/
01116         {
01117                 /*calculate the intersection between edge e2 and L*/
01118                 C[0] = quadmesh->quad_verts[f->verts[1]]->x;
01119                 C[1] = quadmesh->quad_verts[f->verts[1]]->y;
01120                 D[0] = quadmesh->quad_verts[f->verts[2]]->x;
01121                 D[1] = quadmesh->quad_verts[f->verts[2]]->y;
01122 
01123                 if(GetIntersection2(pre, cur, C, D, t)==1)
01124                 {
01125                         face_id = face_id+1;
01126                         /*calculate the intersection*/
01127                         cur[0]=C[0]+t[1]*(D[0]-C[0]);
01128                         //cur[0]=f->x_start_coord+quadmesh->xinterval+1.e-8;
01129                         cur[1]=C[1]+t[1]*(D[1]-C[1]);
01130 
01131                         return;
01132                 }
01133         }
01134 
01135 
01136         if(cur[1]<f->y_start_coord) /*bottom */
01137         {
01138                 /*calculate the intersection between edge e0 and L*/
01139                 C[0] = quadmesh->quad_verts[f->verts[0]]->x;
01140                 C[1] = quadmesh->quad_verts[f->verts[0]]->y;
01141                 D[0] = quadmesh->quad_verts[f->verts[1]]->x;
01142                 D[1] = quadmesh->quad_verts[f->verts[1]]->y;
01143 
01144                 if(GetIntersection2(pre, cur, C, D, t)==1)
01145                 {
01146                         face_id = face_id-quadmesh->XDIM+1;
01147                         /*calculate the intersection*/
01148                         cur[0]=C[0]+t[1]*(D[0]-C[0]);
01149                         cur[1]=C[1]+t[1]*(D[1]-C[1]);
01150                         //cur[1]=f->y_start_coord-1.e-8;
01151 
01152                         return;
01153                 }
01154         }
01155         else if(cur[1]>f->y_start_coord+quadmesh->yinterval)  /*upper*/
01156         {
01157                 /*calculate the intersection between edge e2 and L*/
01158                 C[0] = quadmesh->quad_verts[f->verts[2]]->x;
01159                 C[1] = quadmesh->quad_verts[f->verts[2]]->y;
01160                 D[0] = quadmesh->quad_verts[f->verts[3]]->x;
01161                 D[1] = quadmesh->quad_verts[f->verts[3]]->y;
01162 
01163                 if(GetIntersection2(pre, cur, C, D, t)==1)
01164                 {
01165                         face_id = face_id+quadmesh->XDIM-1;
01166                         /*calculate the intersection*/
01167                         cur[0]=C[0]+t[1]*(D[0]-C[0]);
01168                         cur[1]=C[1]+t[1]*(D[1]-C[1]);
01169                         //cur[1]=f->y_start_coord+quadmesh->yinterval+1.e-8;
01170 
01171                         return;
01172                 }
01173         }
01174 
01175         face_id = -1;
01176 }
01177 
01178 bool EvenStreamlinePlace::cal_a_sample_of_streamline(int traj, int &cur_lineindex, int &movetonext,
01179                                                                                                          double curpt[2], double interval, double &cur_length)
01180 {
01181         int i;
01182         icVector2 len_vec;
01183         double alpha;
01184 
01185         int num_lines = evenstreamlines->trajs[traj]->nlinesegs;
01186 
01187         curpt[0] = curpt[1] = -1;
01188 
01189         if(cur_length >= interval)
01190         {
01191                 alpha = (cur_length-interval)/evenstreamlines->trajs[traj]->linesegs[cur_lineindex].length;
01192                 curpt[0] = alpha*evenstreamlines->trajs[traj]->linesegs[cur_lineindex].gstart[0] 
01193                 + (1-alpha)*evenstreamlines->trajs[traj]->linesegs[cur_lineindex].gend[0];
01194                 curpt[1] = alpha*evenstreamlines->trajs[traj]->linesegs[cur_lineindex].gstart[1] 
01195                 + (1-alpha)*evenstreamlines->trajs[traj]->linesegs[cur_lineindex].gend[1];
01196 
01197                 //if(alpha>1 || alpha<0)
01198                 //{
01199                 //      int test =0;
01200                 //}
01201 
01202                 cur_length -= interval;
01203                 return true;
01204         }
01205 
01206         else{
01207                 cur_lineindex++;
01208                 if(cur_lineindex >= num_lines)
01209                 {
01210                         return false;
01211                 }
01212                 cur_length += evenstreamlines->trajs[traj]->linesegs[cur_lineindex].length;
01213                 return false;
01214         }
01215 }
01216 bool EvenStreamlinePlace::is_in_reg_cell(int id, double x, double y)
01217 {
01218         if(id<0) return false;
01219         int i=(x-quadmesh->xstart)/quadmesh->xinterval;
01220         int j=(y-quadmesh->ystart)/quadmesh->yinterval;
01221 
01222         if(id==(j*(quadmesh->XDIM-1)+i))
01223                 return true;
01224         return false;
01225 }
01226 SamplePt **EvenStreamlinePlace::cal_samplepts_when_tracing(int traj, double interval, int &cur_line, int &movetonext, double &cur_length, 
01227                                                                                                                    SamplePt **samples, int &num_samples)
01228 {
01229         double cur_p[2] = {0.};
01230         QuadCell *face;
01231 
01232         while(cur_line < evenstreamlines->trajs[traj]->nlinesegs)
01233         {
01234                 if(cal_a_sample_of_streamline(traj, cur_line, movetonext,
01235                         cur_p, interval, cur_length))
01236                 {
01237                         if(evenstreamlines->trajs[traj]->linesegs[cur_line].Triangle_ID<0
01238                                 ||evenstreamlines->trajs[traj]->linesegs[cur_line].Triangle_ID>=quadmesh->nfaces)
01239                                 return samplepts[traj]->samples;
01240 
01241                         face = quadmesh->quadcells[evenstreamlines->trajs[traj]->linesegs[cur_line].Triangle_ID];
01242                         /*since we use global frame here, we need not convert to global frame here*/
01243                         samplepts[traj]->samples[num_samples]->gpt[0] = cur_p[0];
01244                         samplepts[traj]->samples[num_samples]->gpt[1] = cur_p[1];
01245 
01246                         samplepts[traj]->samples[num_samples]->triangle = face->index;
01247 
01248                         if(!is_in_reg_cell(face->index, cur_p[0], cur_p[1]))
01249                         {
01250                                 int test = 0;
01251 
01252                                 samplepts[traj]->samples[num_samples]->triangle = 
01253                                         get_cellID_givencoords(cur_p[0], cur_p[1]);
01254                         }
01255 
01256                         if(samplepts[traj]->samples[num_samples]->triangle < 0 
01257                                 || samplepts[traj]->samples[num_samples]->triangle >= quadmesh->nfaces)
01258                         {
01259                                 continue;
01260                         }
01261 
01262                         num_samples++;
01263 
01264                         if(num_samples >= samplepts[traj]->curMaxNumSamplePts)
01265                         {
01266 
01267                                 int oldnum = samplepts[traj]->curMaxNumSamplePts;
01268 
01269                                 if(!samplepts[traj]->extend(200))
01270                                 {
01271                                         return NULL;
01272                                 }
01273 
01274                                 /*allocate memory for the elements*/
01275                                 for(int i = oldnum ; i < samplepts[traj]->curMaxNumSamplePts; i++)
01276                                 {
01277                                         samplepts[traj]->samples[i] = (SamplePt *)malloc(sizeof(SamplePt));
01278                                 }
01279 
01280                         }
01281                 }
01282         }
01283 
01284         cur_line--;
01285 
01286         if(cur_line < 0)
01287                 cur_line = 0;
01288 
01289         return samplepts[traj]->samples;
01290 }
01291 void EvenStreamlinePlace::reverse_streamline(int streamlineid)
01292 {
01294         int i;
01295         int num_lines = evenstreamlines->trajs[streamlineid]->nlinesegs;
01296         Trajectory *traj = evenstreamlines->trajs[streamlineid];
01297 
01298         LineSeg *temp = (LineSeg *)malloc(sizeof(LineSeg)*(num_lines+1));
01299 
01300         if(temp == NULL)
01301         {
01302                 return;
01303         }
01304 
01305 
01306         int newnum_lines = 0;
01307 
01309 
01310         for(i = num_lines-1; i >= 0; i--)
01311         {
01312                 if(traj->linesegs[i].Triangle_ID < 0
01313                         || traj->linesegs[i].Triangle_ID >= quadmesh->nfaces  
01314                         || traj->linesegs[i].length < 0)
01315                 {
01316                         continue;
01317                 }
01318 
01319                 temp[newnum_lines].gstart[0] = traj->linesegs[i].gend[0];
01320                 temp[newnum_lines].gstart[1] = traj->linesegs[i].gend[1];
01321 
01322                 temp[newnum_lines].gend[0] = traj->linesegs[i].gstart[0];
01323                 temp[newnum_lines].gend[1] = traj->linesegs[i].gstart[1];
01324 
01325                 temp[newnum_lines].start[0] = traj->linesegs[i].end[0];
01326                 temp[newnum_lines].start[1] = traj->linesegs[i].end[1];
01327 
01328                 temp[newnum_lines].end[0] = traj->linesegs[i].start[0];
01329                 temp[newnum_lines].end[1] = traj->linesegs[i].start[1];
01330 
01331                 temp[newnum_lines].length = traj->linesegs[i].length;
01332                 temp[newnum_lines].Triangle_ID = traj->linesegs[i].Triangle_ID;
01333 
01334 
01335                 newnum_lines++;
01336         }
01337 
01339         for(i = 0; i < newnum_lines; i++)
01340         {
01341                 traj->linesegs[i].gstart[0] = temp[i].gstart[0];
01342                 traj->linesegs[i].gstart[1] = temp[i].gstart[1];
01343 
01344                 traj->linesegs[i].gend[0] = temp[i].gend[0];
01345                 traj->linesegs[i].gend[1] = temp[i].gend[1];
01346 
01347                 traj->linesegs[i].start[0] = temp[i].start[0];
01348                 traj->linesegs[i].start[1] = temp[i].start[1];
01349 
01350                 traj->linesegs[i].end[0] = temp[i].end[0];
01351                 traj->linesegs[i].end[1] = temp[i].end[1];
01352 
01353                 traj->linesegs[i].length = temp[i].length;
01354                 traj->linesegs[i].Triangle_ID = temp[i].Triangle_ID;
01355         }
01356 
01357         traj->nlinesegs = newnum_lines;
01358 
01359         free(temp);
01360 }
01361 
01362 //path advection
01363 bool EvenStreamlinePlace::grow_a_majRoad(double seed_p[2], int triangle, double dtest, 
01364                                         double discsize, double Sample_interval, 
01365                                         double loopdsep, double dist2sing, 
01366                                         double streamlinelength, 
01367                     int type, icVector2 &direction)
01368 {
01369     isAdd_push=false;
01370         int i;
01371         int flag = -1;
01372 
01373         int pre_face, cur_face;
01374         double globalp[3] = {0.};
01375         int cur_line = 0;
01376         double cur_length = 0;
01377         int movetonext = 0;
01378 
01379         /*  variables for pixel level judgement of "inland" or not  */
01380         double xstart=quadmesh->xstart;
01381         double ystart=quadmesh->ystart;
01382         double xrang=quadmesh->xend-quadmesh->xstart;
01383         double yrang=quadmesh->yend-quadmesh->ystart;
01384     double dx=xrang/(NPIX-1);
01385     double dy=yrang/(NPIX-1);
01386         double dist_did;
01387 
01388 
01389         pre_face = cur_face = triangle;
01390         globalp[0] = seed_p[0];
01391         globalp[1] = seed_p[1];
01392 
01393         icMatrix2x2 ten;
01394         //double t[4]={0.};
01395 
01396         if(!is_in_cell(triangle, seed_p[0], seed_p[1]))
01397         {
01398                 triangle = get_cellID_givencoords(seed_p[0], seed_p[1]);
01399         }
01400 
01401         if(triangle < 0 || triangle >= quadmesh->nfaces)
01402                 return false;
01403 
01404         compute_tensor_at_quad(triangle, seed_p[0], seed_p[1], ten);
01405 
01406         double evalues[2] = {0.};
01407         icVector2 ev[2], startdir;
01408     m_tfCore->cal_eigen_vector_sym(ten, ev);
01409 
01410         if(type == 1) /*use minor eigen vector field*/
01411                 ev[0] = ev[1];
01412     if(dot(direction,ev[0])>0){
01413        tenline_dir_global = startdir = ev[0];  /*obtain the major eigen vector*/
01414     }else{
01415        tenline_dir_global = startdir = -ev[0];  /*obtain the major eigen vector*/
01416     }
01417 
01418         evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs = 0;
01419         evenstreamlines->trajs[evenstreamlines->ntrajs]->closed=false;
01420 
01421 
01422         samplepts[evenstreamlines->ntrajs]->samples[0]->gpt[0] = seed_p[0];
01423         samplepts[evenstreamlines->ntrajs]->samples[0]->gpt[1] = seed_p[1];
01424         samplepts[evenstreamlines->ntrajs]->samples[0]->triangle = triangle;
01425         samplepts[evenstreamlines->ntrajs]->nsamples=1;
01426 
01427 
01428         hstep = quadmesh->xinterval/2.;
01429         predict_stepsize = quadmesh->xinterval/2.;
01430         euler_stepsize = quadmesh->xinterval/10.;
01431 
01432 
01433         cur_line = 0;
01434         cur_length = 0;
01435 
01437 
01439         int NUMTRACETRIS = (int)sqrt((double)quadmesh->nfaces);
01440 
01441     for(i = 0; i < 3*NUMTRACETRIS; i++)
01442         {
01443 
01445                 if(cur_face < 0 || cur_face >= quadmesh->nfaces)
01446                         break;
01447 
01448 
01449                 /*it reaches any boundary, we should stop as well*/
01450                 if(globalp[0]>=quadmesh->xend-1.e-8||globalp[0]<=quadmesh->xstart+1.e-8
01451                         ||globalp[1]>=quadmesh->yend-1.e-8||globalp[1]<=quadmesh->ystart+1.e-8)
01452                 {
01453                         if(globalp[0]>=quadmesh->xend-1.e-8) globalp[0]=quadmesh->xend;
01454                         else if(globalp[0]<=quadmesh->xstart+1.e-8) globalp[0]=quadmesh->xstart;
01455                         if(globalp[1]>=quadmesh->yend-1.e-8) globalp[1]=quadmesh->yend;
01456                         else if(globalp[1]<=quadmesh->ystart+1.e-8) globalp[1]=quadmesh->ystart;
01457                         break;
01458                 }
01459 
01460                 pre_face = cur_face;
01461                 cur_face = trace_majRoad_in_quad(cur_face, globalp, type, dtest, loopdsep, dist2sing,
01462                         Sample_interval, discsize, flag);
01463         if(flag==1 || flag==3 || flag==4)
01464             break;
01466                 if(pre_face == triangle && evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs>0)
01467                 {
01468                         cur_length = evenstreamlines->trajs[evenstreamlines->ntrajs]->linesegs[0].length;
01469                 }
01470                 cal_samplepts_when_tracing(evenstreamlines->ntrajs, Sample_interval, cur_line, movetonext, cur_length,
01471                         samplepts[evenstreamlines->ntrajs]->samples, samplepts[evenstreamlines->ntrajs]->nsamples);
01472         if(evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs>5){
01473             if (evenstreamlines->trajs[evenstreamlines->ntrajs]->get_length()>m_tfCore->interFrameNum*LIEN_LENGTH_PER_FRAME){
01474                  break;
01475              }
01476         }
01477         }
01478     evenstreamlines->trajs[evenstreamlines->ntrajs]->traj_len=
01479         evenstreamlines->trajs[evenstreamlines->ntrajs]->get_length();
01480 
01481     evenstreamlines->ntrajs ++;
01482 
01483         return true;
01484 }
01485 
01486 // separatrix generation
01487 bool EvenStreamlinePlace::grow_a_separatrix(double degpt_loc[2],double seed_p[2], int triangle, double dtest,
01488                                          double discsize, double Sample_interval,
01489                                          double loopdsep, double dist2sing,
01490                                          double streamlinelength,
01491                                          int type, icVector2 direction,int index,int sep_index)
01492 {
01493     int i;
01494     int flag = -1;
01495 
01496     int pre_face, cur_face;
01497     double globalp[3] = {0.};
01498     int cur_line = 0;
01499     double cur_length = 0;
01500     int movetonext = 0;
01501 
01502     /*  variables for pixel level judgement of "inland" or not  */
01503     double xstart=quadmesh->xstart;
01504     double ystart=quadmesh->ystart;
01505     double xrang=quadmesh->xend-quadmesh->xstart;
01506     double yrang=quadmesh->yend-quadmesh->ystart;
01507     double dx=xrang/(NPIX-1);
01508     double dy=yrang/(NPIX-1);
01509     double dist_did;
01510 
01511 
01512     pre_face = cur_face = triangle;
01513     globalp[0] = seed_p[0];
01514     globalp[1] = seed_p[1];
01515 
01516     icMatrix2x2 ten;
01517     //double t[4]={0.};
01518 
01519     if(!is_in_cell(triangle, seed_p[0], seed_p[1]))
01520     {
01521         triangle = get_cellID_givencoords(seed_p[0], seed_p[1]);
01522     }
01523 
01524     if(triangle < 0 || triangle >= quadmesh->nfaces)
01525         return false;
01526 
01527     compute_tensor_at_quad(triangle, seed_p[0], seed_p[1], ten);
01528 
01529     double evalues[2] = {0.};
01530     icVector2 ev[2], startdir;
01531     m_tfCore->cal_eigen_vector_sym(ten, ev);
01532 
01533     if(type == 1) /*use minor eigen vector field*/
01534         ev[0] = ev[1];
01535 
01536     tenline_dir_global = startdir = direction;
01537     evenstreamlines->trajs[evenstreamlines->ntrajs]->degpt_id=index;
01538     evenstreamlines->trajs[evenstreamlines->ntrajs]->degpt_sep_index=sep_index;
01539     evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs = 1;
01540     evenstreamlines->trajs[evenstreamlines->ntrajs]->linesegs[0].gstart[0]=degpt_loc[0];
01541     evenstreamlines->trajs[evenstreamlines->ntrajs]->linesegs[0].gstart[1]=degpt_loc[1];
01542     evenstreamlines->trajs[evenstreamlines->ntrajs]->linesegs[0].gend[0]=seed_p[0];
01543     evenstreamlines->trajs[evenstreamlines->ntrajs]->linesegs[0].gend[1]=seed_p[1];
01544 
01545     evenstreamlines->trajs[evenstreamlines->ntrajs]->closed=false;
01546 
01547 
01548     samplepts[evenstreamlines->ntrajs]->samples[0]->gpt[0] = seed_p[0];
01549     samplepts[evenstreamlines->ntrajs]->samples[0]->gpt[1] = seed_p[1];
01550     samplepts[evenstreamlines->ntrajs]->samples[0]->triangle = triangle;
01551     samplepts[evenstreamlines->ntrajs]->nsamples=1;
01552 
01553 
01554     hstep = quadmesh->xinterval/2.;
01555     predict_stepsize = quadmesh->xinterval/2.;
01556     euler_stepsize = quadmesh->xinterval/10.;
01557 
01558 
01559     cur_line = 0;
01560     cur_length = 0;
01561 
01562 
01563 
01565 
01567     int NUMTRACETRIS = (int)sqrt((double)quadmesh->nfaces);
01568 
01569     for(i = 0; i < 3*NUMTRACETRIS; i++)
01570     {
01571 
01573 
01574         if(cur_face < 0 || cur_face >= quadmesh->nfaces)
01575             break;
01576 
01577 
01578         /*it reaches any boundary, we should stop as well*/
01579         if(globalp[0]>=quadmesh->xend-1.e-8||globalp[0]<=quadmesh->xstart+1.e-8
01580             ||globalp[1]>=quadmesh->yend-1.e-8||globalp[1]<=quadmesh->ystart+1.e-8)
01581         {
01582             if(globalp[0]>=quadmesh->xend-1.e-8) globalp[0]=quadmesh->xend;
01583             else if(globalp[0]<=quadmesh->xstart+1.e-8) globalp[0]=quadmesh->xstart;
01584             if(globalp[1]>=quadmesh->yend-1.e-8) globalp[1]=quadmesh->yend;
01585             else if(globalp[1]<=quadmesh->ystart+1.e-8) globalp[1]=quadmesh->ystart;
01586             break;
01587         }
01588 
01589         pre_face = cur_face;
01590         cur_face = trace_separatrix_in_quad(cur_face, globalp, type, dtest, loopdsep, dist2sing,
01591             Sample_interval, discsize, flag,index,sep_index);
01592 
01593         cal_samplepts_when_tracing(evenstreamlines->ntrajs, Sample_interval, cur_line, movetonext, cur_length,
01594             samplepts[evenstreamlines->ntrajs]->samples, samplepts[evenstreamlines->ntrajs]->nsamples);
01595 
01596         if(flag==1 || flag==3 || flag==4 || flag==5)
01597             break;
01598         //if(evenstreamlines->trajs[evenstreamlines->ntrajs]->nlinesegs>2000) break;
01599 
01600     }
01601 
01602     evenstreamlines->ntrajs ++;
01603     return true;
01604 }
01605 
01606 void EvenStreamlinePlace::init_major_line_info()
01607 {
01608         int i;
01609         QuadCell *face;
01610         for(i=0; i<quadmesh->nfaces; i++)
01611         {
01612                 face = quadmesh->quadcells[i];
01613         if(face->majorlines != NULL)
01614         {
01615             delete face->majorlines;
01616             face->majorlines = NULL;
01617         }
01618         face->hasmajor = false;
01619         }
01620 }


tensor_field_nav_core
Author(s): Lintao Zheng, Kai Xu
autogenerated on Thu Jun 6 2019 19:50:56