#include <euler.h>
Definition at line 139 of file euler.h.
Public Member Functions | |
| Point2D< double > | compute_end_pt (double k0, double gamma, double L, bool bNormalized=false) |
| Point2D< double > | compute_end_pt (double arclength, bool bNormalized=false) |
| double | compute_error (double k0, double L) |
| void | compute_es_params () |
| Point2D< double > | compute_es_point (EulerSpiralParams &es_params, double arclength, bool bNormalized=false) |
| void | computeSpiral (std::vector< Point2D< double > > &spiral, double ds=0, int NPts=0) |
| EulerSpiral (Point2D< double > start_pt, double start_angle, double k0, double gamma, double L) | |
| EulerSpiral (Point2D< double > start_pt, double start_angle, Point2D< double > end_pt, double end_angle) | |
| EulerSpiral () | |
| Point2D< double > | get_fresnel_integral (double value) |
| void | set_end_params (Point2D< double > end_pt, double end_angle) |
| void | set_params (Point2D< double > start_pt, double start_angle, Point2D< double > end_pt, double end_angle) |
| void | set_start_params (Point2D< double > start_pt, double start_angle) |
Data Fields | |
| EulerSpiralParams | params |
| std::vector< Point2D< double > > | pts |
Private Attributes | |
| BiArc | _bi_arc_estimate |
| EulerSpiral::EulerSpiral | ( | Point2D< double > | start_pt, | |
| double | start_angle, | |||
| Point2D< double > | end_pt, | |||
| double | end_angle | |||
| ) | [inline] |
Definition at line 151 of file euler.h.
References angle0To2Pi(), compute_es_params(), EulerSpiralParams::end_angle, EulerSpiralParams::end_pt, params, EulerSpiralParams::start_angle, and EulerSpiralParams::start_pt.
00152 { 00153 params.start_pt = start_pt; 00154 params.start_angle = angle0To2Pi(start_angle); 00155 00156 params.end_pt = end_pt; 00157 params.end_angle = angle0To2Pi(end_angle); 00158 00159 //since we have all the parameters, we might as well compute it 00160 compute_es_params(); 00161 }
| EulerSpiral::EulerSpiral | ( | Point2D< double > | start_pt, | |
| double | start_angle, | |||
| double | k0, | |||
| double | gamma, | |||
| double | L | |||
| ) | [inline] |
Definition at line 164 of file euler.h.
References angle0To2Pi(), compute_end_pt(), compute_es_params(), EulerSpiralParams::end_angle, EulerSpiralParams::end_pt, params, EulerSpiralParams::start_angle, and EulerSpiralParams::start_pt.
00165 { 00166 params.start_pt = start_pt; 00167 params.start_angle = angle0To2Pi(start_angle); 00168 params.end_pt = compute_end_pt(k0, gamma, L); 00169 params.end_angle = start_angle + 0.5*gamma*L*L + k0*L; 00170 00171 //since we have all the parameters, we might as well compute it 00172 compute_es_params(); 00173 }
| Point2D< double > EulerSpiral::compute_end_pt | ( | double | k0, | |
| double | gamma, | |||
| double | L, | |||
| bool | bNormalized = false | |||
| ) |
Definition at line 400 of file euler.cpp.
References CCW(), eGamma, eK, get_fresnel_integral(), Point2D< coord_type >::getX(), Point2D< coord_type >::getY(), M_PI, params, EulerSpiralParams::psi, Point2D< coord_type >::setX(), Point2D< coord_type >::setY(), EulerSpiralParams::start_angle, and EulerSpiralParams::start_pt.
00401 { 00402 Point2D<double> start_pt; 00403 Point2D<double> end_pt; 00404 00405 double theta; 00406 00407 if (bNormalized){ 00408 start_pt = Point2D<double>(0,0); 00409 theta = CCW(params.psi, params.start_angle); 00410 } 00411 else { 00412 start_pt = params.start_pt; 00413 theta = params.start_angle; 00414 } 00415 00416 if (L==0) 00417 return start_pt; 00418 00419 if (fabs(gamma)<eGamma) 00420 { 00421 if (fabs(k0)<eK) 00422 { 00423 //straight line 00424 end_pt.setX(start_pt.getX()+L*cos(theta)); 00425 end_pt.setY(start_pt.getY()+L*sin(theta)); 00426 } 00427 else 00428 { 00429 //circle 00430 double const_term = 1.0/k0; 00431 end_pt.setX(start_pt.getX()+const_term*(sin(k0*L+theta)-sin(theta))); 00432 end_pt.setY(start_pt.getY()-const_term*(cos(k0*L+theta)-cos(theta))); 00433 } 00434 return end_pt; 00435 } 00436 00437 double const1 = sqrt(M_PI*fabs(gamma)); 00438 double const2 = sqrt(M_PI/fabs(gamma)); 00439 00440 Point2D<double> fresnel1 = get_fresnel_integral((k0+gamma*L)/const1); 00441 Point2D<double> fresnel2 = get_fresnel_integral(k0/const1); 00442 00443 double C = (fresnel1.getX() - fresnel2.getX()); 00444 if(gamma<0) { 00445 C *= -1.; 00446 } 00447 double S = fresnel1.getY() - fresnel2.getY(); 00448 00449 double cos_term = cos(theta-((k0*k0)/(2.0*gamma))); 00450 double sin_term = sin(theta-((k0*k0)/(2.0*gamma))); 00451 00452 end_pt.setX(start_pt.getX() + const2*(C*cos_term - S*sin_term)); 00453 end_pt.setY(start_pt.getY() + const2*(C*sin_term + S*cos_term)); 00454 00455 return end_pt; 00456 }
Definition at line 395 of file euler.cpp.
References EulerSpiralParams::gamma, EulerSpiralParams::K0, and params.
Referenced by compute_error(), compute_es_point(), computeSpiral(), and EulerSpiral().
00396 { 00397 return compute_end_pt(params.K0, params.gamma, arclength, bNormalized); 00398 }
| double EulerSpiral::compute_error | ( | double | k0, | |
| double | L | |||
| ) | [inline] |
Definition at line 458 of file euler.cpp.
References compute_end_pt(), euc_distance(), params, and EulerSpiralParams::turningAngle.
Referenced by compute_es_params().
00459 { 00460 //assumes normalized parameters 00461 00462 //compute the endpoint of the Euler spiral with the given intrinsic parameters 00463 double gamma = 2*(params.turningAngle - k0*L)/(L*L); 00464 Point2D<double> cur_end_pt = compute_end_pt(k0, gamma, L, true); 00465 00466 //the error is the distance between the current end point and the desired end point 00467 return euc_distance(Point2D<double>(1,0), cur_end_pt); 00468 }
| void EulerSpiral::compute_es_params | ( | ) |
Definition at line 288 of file euler.cpp.
References _bi_arc_estimate, angle0To2Pi(), BiArc::compute_biarc_params(), compute_error(), eError, EulerSpiralParams::end_angle, EulerSpiralParams::end_pt, EulerSpiralParams::error, euc_distance(), EulerSpiralParams::gamma, EulerSpiralParams::K0, BiArcParams::K1, EulerSpiralParams::K2, BiArcParams::K2, EulerSpiralParams::L, BiArcParams::L(), BiArcParams::L1, BiArcParams::L2, MAX_NUM_ITERATIONS, MIN2(), BiArc::params, params, EulerSpiralParams::psi, BiArc::set_end_params(), BiArc::set_start_params(), EulerSpiralParams::start_angle, EulerSpiralParams::start_pt, EulerSpiralParams::turningAngle, Point2D< coord_type >::x(), and Point2D< coord_type >::y().
Referenced by EulerSpiral().
00289 { 00290 //compute scaling distance 00291 double d = euc_distance(params.start_pt, params.end_pt); 00292 params.psi = angle0To2Pi(atan2(params.end_pt.y()-params.start_pt.y(),params.end_pt.x()-params.start_pt.x())); 00293 00294 //degeneracy check 00295 if (d<eError) 00296 return; 00297 00298 //first compute a biarc estimate 00299 _bi_arc_estimate.set_start_params(params.start_pt, params.start_angle); 00300 _bi_arc_estimate.set_end_params(params.end_pt, params.end_angle); 00301 _bi_arc_estimate.compute_biarc_params(); 00302 00303 //get the total turning angle::This is an important parameter because 00304 //it defines the one solution out of many possible solutions 00305 params.turningAngle = _bi_arc_estimate.params.K1*_bi_arc_estimate.params.L1 + 00306 _bi_arc_estimate.params.K2*_bi_arc_estimate.params.L2; 00307 00308 //From here on, normlize the parameters and use these to perform the optimization 00309 00310 double k0_init_est = _bi_arc_estimate.params.K1*d; 00311 double L_init_est = _bi_arc_estimate.params.L()/d; 00312 double dstep = 0.1; 00313 00314 //Alternately, we can get the initial values from the lookup table and perform 00315 //the optimization from there 00316 //double k0_init_est = globalEulerSpiralLookupTable->get_globalEulerSpiralLookupTable()->k0(CCW(params.psi, params.start_angle), CCW(params.psi, params.end_angle)); 00317 //double L_init_est = globalEulerSpiralLookupTable->get_globalEulerSpiralLookupTable()->L(CCW(params.psi, params.start_angle), CCW(params.psi, params.end_angle)); 00318 //double dstep = globalEulerSpiralLookupTable->get_globalEulerSpiralLookupTable()->dt()/4; 00319 00320 //then perform a simple gradient descent to find the real solution 00321 double error = compute_error(k0_init_est, L_init_est); 00322 double prev_error = error; 00323 00324 double k0 = k0_init_est; 00325 double L = L_init_est; 00326 00327 double e1, e2, e3, e4; 00328 00329 for (int i=0;i<MAX_NUM_ITERATIONS;i++) 00330 { 00331 if (error<eError) 00332 break; 00333 00334 e1 = compute_error(k0 + dstep, L); 00335 e2 = compute_error(k0 - dstep, L); 00336 e3 = compute_error(k0, L + dstep); 00337 if (L>dstep) e4 = compute_error(k0, L - dstep); 00338 00339 error = MIN2(MIN2(e1,e2),MIN2(e3,e4)); 00340 00341 if (error>prev_error) 00342 { 00343 dstep = dstep/2; 00344 continue; 00345 } 00346 00347 if (error==e1) k0 = k0 + dstep; 00348 else if (error==e2) k0 = k0 - dstep; 00349 else if (error==e3) L = L + dstep; 00350 else if (error==e4) L = L - dstep; 00351 00352 prev_error = error; 00353 } 00354 00355 //store the parameters 00356 params.K0 = k0/d; 00357 params.L = L*d; 00358 params.gamma = 2*(params.turningAngle - k0*L)/(L*L)/(d*d); 00359 params.K2 = (k0 + params.gamma*L)/d; 00360 params.error = error; 00361 }
| Point2D< double > EulerSpiral::compute_es_point | ( | EulerSpiralParams & | es_params, | |
| double | arclength, | |||
| bool | bNormalized = false | |||
| ) |
Definition at line 389 of file euler.cpp.
References compute_end_pt(), EulerSpiralParams::gamma, EulerSpiralParams::K0, and params.
00390 { 00391 params = es_params; 00392 return compute_end_pt(params.K0, params.gamma, arclength, bNormalized); 00393 }
| void EulerSpiral::computeSpiral | ( | std::vector< Point2D< double > > & | spiral, | |
| double | ds = 0, |
|||
| int | NPts = 0 | |||
| ) |
Definition at line 364 of file euler.cpp.
References compute_end_pt(), EulerSpiralParams::end_pt, EulerSpiralParams::L, params, and EulerSpiralParams::start_pt.
Referenced by NIImporter_OpenDrive::geomFromSpiral().
00365 { 00366 if (ds==0 && NPts==0){ 00367 //use default values 00368 NPts = 100; 00369 ds = params.L/NPts; 00370 } 00371 00372 spiral.clear(); 00373 spiral.push_back(params.start_pt); 00374 00375 double s=ds; 00376 if (NPts == 0) 00377 NPts = (int) (params.L / ds); 00378 for (int i=1; i<NPts; i++,s+=ds){ 00379 Point2D<double> cur_pt = compute_end_pt(s); 00380 spiral.push_back(cur_pt); 00381 } 00382 spiral.push_back(params.end_pt); 00383 }
| Point2D< double > EulerSpiral::get_fresnel_integral | ( | double | value | ) |
Definition at line 482 of file euler.cpp.
References EPS, FPMIN, M_PI, MAXIT, Point2D< coord_type >::setX(), Point2D< coord_type >::setY(), sign, and XMIN.
Referenced by compute_end_pt().
00483 { 00484 bool odd; 00485 int k,n; 00486 double a,ax,fact,pix2,sign,sum,sumc,sums,term,test; 00487 00488 std::complex<double> b,cc,d,h,del,cs; 00489 Point2D<double> result; 00490 00491 ax=fabs(x); 00492 if (ax < sqrt(FPMIN)) 00493 { 00494 //Special case: avoid failure of convergence test because of undeflow. 00495 result.setY(0.0); 00496 result.setX(ax); 00497 } 00498 else { 00499 if (ax <= XMIN) 00500 { 00501 // Evaluate both series simultaneously. 00502 sum=sums=0.0; 00503 sumc=ax; 00504 sign=1.0; 00505 fact=(M_PI/2.0)*ax*ax; 00506 odd=true; 00507 term=ax; 00508 n=3; 00509 00510 for (k=1;k<=MAXIT;k++) 00511 { 00512 term *= fact/k; 00513 sum += sign*term/n; 00514 test=fabs(sum)*EPS; 00515 if (odd) 00516 { 00517 sign = -sign; 00518 sums=sum; 00519 sum=sumc; 00520 } 00521 else { 00522 sumc=sum; 00523 sum=sums; 00524 } 00525 00526 if (term < test) break; 00527 odd=!odd; 00528 n +=2; 00529 } 00530 00531 if (k > MAXIT) 00532 std::cout << "series failed in fresnel" << std::endl; 00533 00534 result.setY(sums); 00535 result.setX(sumc); 00536 } 00537 else { 00538 // Evaluate continued fraction by modified Lentz's method 00539 pix2=M_PI*ax*ax; 00540 b = std::complex<double>(1.0,-pix2); 00541 cc = std::complex<double>(1.0/FPMIN,0.0); 00542 d=h = std::complex<double>(1.0,0.0)/b; 00543 n = -1; 00544 00545 for (k=2;k<=MAXIT;k++) 00546 { 00547 n +=2; 00548 a = -n*(n+1); 00549 b= b+std::complex<double>(4.0,0.0); 00550 d=(std::complex<double>(1.0,0.0)/((a*d)+b)); 00551 00552 //Denominators cannot be zero 00553 cc=(b+(std::complex<double>(a,0.0)/cc)); 00554 00555 del=(cc*d); 00556 h=h*del; 00557 if ((fabs(del.real()-1.0)+fabs(del.imag())) < EPS) 00558 break; 00559 } 00560 if (k > MAXIT) 00561 std::cout << "cf failed in frenel" << std::endl; 00562 00563 h=std::complex<double>(ax,-ax)*h; 00564 cs=std::complex<double>(0.5,0.5)*(std::complex<double>(1.0,0.0) - std::complex<double>(cos(0.5*pix2),sin(0.5*pix2))*h ); 00565 00566 result.setX(cs.real()); 00567 result.setY(cs.imag()); 00568 } 00569 } 00570 00571 if (x<0){ //use antisymmetry 00572 result = -1*result; 00573 } 00574 00575 return result; 00576 }
| void EulerSpiral::set_end_params | ( | Point2D< double > | end_pt, | |
| double | end_angle | |||
| ) | [inline] |
Definition at line 181 of file euler.h.
References angle0To2Pi(), EulerSpiralParams::end_angle, EulerSpiralParams::end_pt, and params.
00182 { 00183 params.end_pt = end_pt; 00184 params.end_angle = angle0To2Pi(end_angle); 00185 }
| void EulerSpiral::set_params | ( | Point2D< double > | start_pt, | |
| double | start_angle, | |||
| Point2D< double > | end_pt, | |||
| double | end_angle | |||
| ) | [inline] |
Definition at line 187 of file euler.h.
References angle0To2Pi(), EulerSpiralParams::end_angle, EulerSpiralParams::end_pt, params, EulerSpiralParams::start_angle, and EulerSpiralParams::start_pt.
00188 { 00189 params.start_pt = start_pt; 00190 params.start_angle = angle0To2Pi(start_angle); 00191 00192 params.end_pt = end_pt; 00193 params.end_angle = angle0To2Pi(end_angle); 00194 }
| void EulerSpiral::set_start_params | ( | Point2D< double > | start_pt, | |
| double | start_angle | |||
| ) | [inline] |
Definition at line 175 of file euler.h.
References angle0To2Pi(), params, EulerSpiralParams::start_angle, and EulerSpiralParams::start_pt.
00176 { 00177 params.start_pt = start_pt; 00178 params.start_angle = angle0To2Pi(start_angle); 00179 }
BiArc EulerSpiral::_bi_arc_estimate [private] |
Definition at line 145 of file euler.h.
Referenced by compute_end_pt(), compute_error(), compute_es_params(), compute_es_point(), computeSpiral(), EulerSpiral(), set_end_params(), set_params(), and set_start_params().
| std::vector<Point2D<double> > EulerSpiral::pts |
1.5.6