00001
00002
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
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
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;
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;
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
00103 void EvenStreamlinePlace::compute_tensor_at_quad(int face, double x, double y, icMatrix2x2 &ten)
00104 {
00105
00106
00107
00108 QuadCell *qc = quadmesh->quadcells[face];
00109
00110
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
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
00156
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
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
00178
00179
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
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
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
00207 m_tfCore->cal_eigen_vector_sym(ten, ev);
00208
00209 if(g_type == 1)
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
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
00223 }
00224 normalize(ev[0]);
00225 vec[0] = ev[0].entry[0];
00226 vec[1] = ev[0].entry[1];
00227 }
00228
00229
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
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
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
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
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
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
00327 evenstreamlines->trajs[evenstreamlines->ntrajs]->linked_degpt_id=i;
00328
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);
00385
00386 vert->visited = true;
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)
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
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;
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);
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
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
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
00543
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
00595 if(get_nextpt_RK23_ten_quad(pre_point, globalp, face_id, type))
00596
00597 {
00598
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
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
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
00665
00666
00667
00668
00669 if(PassVertornot>0)
00670 {
00671
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;
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
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
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
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
00785 {
00786
00787 tenline_dir_global.entry[0] = globalp[0] - pre_point[0];
00788 tenline_dir_global.entry[1] = globalp[1] - pre_point[1];
00789
00790
00791
00792
00794 if(close_to_cur_samplePt(globalp, face_id, samplepts[evenstreamlines->ntrajs]->samples,
00795 samplepts[evenstreamlines->ntrajs]->nsamples, loopsep, discsize, sample_interval))
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;
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
00857
00858
00859
00860
00861 if(PassVertornot>0)
00862 {
00863
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;
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
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
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
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
00992
00993
00994
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
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
01012
01013
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
01028 if(fabs(cur[1]-pre[1])<1e-8)
01029 {
01030 if(cur[0]>pre[0] && cur[0]<=quadmesh->xend-1.e-8)
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)
01038 {
01039 face_id=-1;
01040 return;
01041 }
01042
01043 else if(cur[0]<pre[0] && cur[0]>=quadmesh->xstart+1.e-8)
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)
01051 {
01052 face_id=-1;
01053 return;
01054 }
01055 }
01056
01057
01058 if(fabs(cur[0]-pre[0])<1e-8)
01059 {
01060 if(cur[1]>pre[1] && cur[1]<=quadmesh->yend-1.e-8)
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)
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)
01098 {
01099
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
01108 cur[0]=C[0]+t[1]*(D[0]-C[0]);
01109
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)
01116 {
01117
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
01127 cur[0]=C[0]+t[1]*(D[0]-C[0]);
01128
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)
01137 {
01138
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
01148 cur[0]=C[0]+t[1]*(D[0]-C[0]);
01149 cur[1]=C[1]+t[1]*(D[1]-C[1]);
01150
01151
01152 return;
01153 }
01154 }
01155 else if(cur[1]>f->y_start_coord+quadmesh->yinterval)
01156 {
01157
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
01167 cur[0]=C[0]+t[1]*(D[0]-C[0]);
01168 cur[1]=C[1]+t[1]*(D[1]-C[1]);
01169
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
01198
01199
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
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
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
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
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
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)
01411 ev[0] = ev[1];
01412 if(dot(direction,ev[0])>0){
01413 tenline_dir_global = startdir = ev[0];
01414 }else{
01415 tenline_dir_global = startdir = -ev[0];
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
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
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
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
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)
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
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
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 }