RoadGeometry.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. #include "RoadGeometry.h"
  2. #define _USE_MATH_DEFINES
  3. #include <math.h>
  4. //#define PI 3.14159265358979323846264338327950288
  5. extern int fresnl( double , double *, double * );
  6. //***********************************************************************************
  7. //Road Geometry Base Class
  8. //***********************************************************************************
  9. /**
  10. * Constructor that initializes the base properties of teh record
  11. */
  12. RoadGeometry::RoadGeometry(double s, double x, double y, double hdg, double length)
  13. {
  14. mS=s; mX=x; mY=y, mHdg=hdg, mLength=length;
  15. mS2=s+length;
  16. }
  17. /**
  18. * Computes the required vars
  19. */
  20. void RoadGeometry::ComputeVars()
  21. {}
  22. /**
  23. * Clones and returns the new geometry record
  24. */
  25. RoadGeometry* RoadGeometry::Clone() const
  26. {
  27. return new RoadGeometry(mS,mX,mY, mHdg, mLength);
  28. }
  29. //-------------------------------------------------
  30. /**
  31. * Sets the type of the geometry
  32. * 0: Line, 1: Arc, 2: Spiral
  33. */
  34. void RoadGeometry::SetGeomType(short int geomType)
  35. {
  36. mGeomType = geomType;
  37. }
  38. /**
  39. * Setter for the base properties
  40. */
  41. void RoadGeometry::SetBase(double s, double x, double y, double hdg, double length, bool recalculate)
  42. {
  43. mS=s;
  44. mX=x;
  45. mY=y;
  46. mHdg=hdg;
  47. mLength=length;
  48. mS2=mS+mLength;
  49. if(recalculate) ComputeVars();
  50. }
  51. void RoadGeometry::SetS(double s)
  52. {
  53. mS=s;
  54. mS2=mS+mLength;
  55. ComputeVars();
  56. }
  57. void RoadGeometry::SetX(double x)
  58. {
  59. mX=x;
  60. }
  61. void RoadGeometry::SetY(double y)
  62. {
  63. mY=y;
  64. }
  65. void RoadGeometry::SetHdg(double hdg)
  66. {
  67. mHdg=hdg;
  68. ComputeVars();
  69. }
  70. void RoadGeometry::SetLength(double length)
  71. {
  72. mLength=length;
  73. mS2=mS+mLength;
  74. ComputeVars();
  75. }
  76. //-------------------------------------------------
  77. /**
  78. * Getter for the geometry type
  79. */
  80. short int RoadGeometry::GetGeomType()
  81. {
  82. return mGeomType;
  83. }
  84. /**
  85. * Getter for the base properties
  86. */
  87. double RoadGeometry::GetS()
  88. {
  89. return mS;
  90. }
  91. double RoadGeometry::GetS2()
  92. {
  93. return mS2;
  94. }
  95. double RoadGeometry::GetX()
  96. {
  97. return mX;
  98. }
  99. double RoadGeometry::GetY()
  100. {
  101. return mY;
  102. }
  103. double RoadGeometry::GetHdg()
  104. {
  105. return mHdg;
  106. }
  107. double RoadGeometry::GetLength()
  108. {
  109. return mLength;
  110. }
  111. //-------------------------------------------------
  112. /**
  113. * Checks if the sample S gets in the current block interval
  114. */
  115. bool RoadGeometry::CheckInterval (double s_check)
  116. {
  117. if ((s_check >= mS) && (s_check<=mS2))
  118. return true;
  119. else
  120. return false;
  121. }
  122. /**
  123. * Gets the coordinates at the sample S offset
  124. */
  125. void RoadGeometry::GetCoords(double s_check, double &retX, double &retY)
  126. {
  127. double tmp;
  128. GetCoords(s_check, retX, retY, tmp);
  129. }
  130. void RoadGeometry::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  131. {}
  132. //***********************************************************************************
  133. //Line geometry
  134. //***********************************************************************************
  135. /**
  136. * Constructor that initializes the base properties of the record
  137. */
  138. GeometryLine::GeometryLine (double s, double x, double y, double hdg, double length): RoadGeometry(s, x, y, hdg, length)
  139. {
  140. SetGeomType(0);
  141. }
  142. /**
  143. * Clones and returns the new geometry record
  144. */
  145. RoadGeometry* GeometryLine::Clone() const
  146. {
  147. GeometryLine* ret=new GeometryLine(mS,mX,mY, mHdg, mLength);
  148. return ret;
  149. }
  150. //-------------------------------------------------
  151. /**
  152. * Setter for the base properties
  153. */
  154. void GeometryLine::SetAll(double s, double x, double y, double hdg, double length)
  155. {
  156. SetBase(s,x,y,hdg,length,false);
  157. ComputeVars();
  158. }
  159. //-------------------------------------------------
  160. /**
  161. * Gets the coordinates at the sample S offset
  162. */
  163. void GeometryLine::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  164. {
  165. double newLength=s_check-mS;
  166. //find the end of the chord line
  167. retX=mX+cos(mHdg)*newLength;
  168. retY=mY+sin(mHdg)*newLength;
  169. retHDG=mHdg;
  170. }
  171. //***********************************************************************************
  172. //Arc geometry
  173. //***********************************************************************************
  174. /**
  175. * Constructor that initializes the base properties of the record
  176. */
  177. GeometryArc::GeometryArc (double s, double x, double y, double hdg, double length, double curvature): RoadGeometry(s, x, y, hdg, length)
  178. {
  179. SetGeomType(2);
  180. mCurvature=curvature;
  181. ComputeVars();
  182. }
  183. /**
  184. * Computes the required vars
  185. */
  186. void GeometryArc::ComputeVars()
  187. {
  188. double radius=0.0;
  189. //if curvature is 0, radius is also 0, otherwise, radius is 1/curvature
  190. if (fabs(mCurvature)>1.00e-15)
  191. {
  192. radius = fabs(1.0/mCurvature);
  193. }
  194. //calculate the start angle for the arc plot
  195. if (mCurvature<=0)
  196. mStartAngle=mHdg+M_PI_2;
  197. else
  198. mStartAngle=mHdg-M_PI_2;
  199. mCircleX=mX+cos(mStartAngle-M_PI)*radius;
  200. mCircleY=mY+sin(mStartAngle-M_PI)*radius;
  201. }
  202. /**
  203. * Clones and returns the new geometry record
  204. */
  205. RoadGeometry* GeometryArc::Clone() const
  206. {
  207. GeometryArc* ret=new GeometryArc(mS,mX,mY, mHdg, mLength, mCurvature);
  208. return ret;
  209. }
  210. //-------------------------------------------------
  211. /**
  212. * Setter for the base properties
  213. */
  214. void GeometryArc::SetAll(double s, double x, double y, double hdg, double length, double curvature)
  215. {
  216. SetBase(s,x,y,hdg,length,false);
  217. mCurvature=curvature;
  218. ComputeVars();
  219. }
  220. void GeometryArc::SetCurvature(double curvature)
  221. {
  222. mCurvature=curvature;
  223. ComputeVars();
  224. }
  225. //-------------------------------------------------
  226. /**
  227. * Getter for the base properties
  228. */
  229. double GeometryArc::GetCurvature()
  230. {
  231. return mCurvature;
  232. }
  233. //-------------------------------------------------
  234. /**
  235. * Gets the coordinates at the sample S offset
  236. */
  237. void GeometryArc::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  238. {
  239. //s from the beginning of the segment
  240. double currentLength = s_check - mS;
  241. double endAngle=mStartAngle;
  242. double radius=0.0;
  243. //if curvature is 0, radius is also 0, so don't add anything to the initial radius,
  244. //otherwise, radius is 1/curvature so the central angle can be calculated and added to the initial direction
  245. if (fabs(mCurvature)>1.00e-15)
  246. {
  247. endAngle+= currentLength/(1.0/mCurvature);
  248. radius = fabs(1.0/mCurvature);
  249. }
  250. //coords on the arc for given s value
  251. retX=mCircleX+cos(endAngle)*radius;
  252. retY=mCircleY+sin(endAngle)*radius;
  253. //heading at the given position
  254. if (mCurvature<=0)
  255. retHDG=endAngle-M_PI_2;
  256. else
  257. retHDG=endAngle+M_PI_2;
  258. }
  259. //***********************************************************************************
  260. //Spiral geometry
  261. //***********************************************************************************
  262. const double GeometrySpiral::sqrtPiO2=sqrt(M_PI_2);
  263. /**
  264. * Constructor that initializes the base properties of the record
  265. */
  266. GeometrySpiral::GeometrySpiral (double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd): RoadGeometry(s, x, y, hdg, length)
  267. {
  268. SetGeomType(1);
  269. mCurvatureStart=curvatureStart;
  270. mCurvatureEnd=curvatureEnd;
  271. ComputeVars();
  272. }
  273. /**
  274. * Computes the required vars
  275. */
  276. void GeometrySpiral::ComputeVars()
  277. {
  278. mA=0;
  279. //if the curvatureEnd is the non-zero curvature, then the motion is in normal direction along the spiral
  280. if ((fabs(mCurvatureEnd)>1.00e-15)&&(fabs(mCurvatureStart)<=1.00e-15))
  281. {
  282. mNormalDir=true;
  283. mCurvature=mCurvatureEnd;
  284. //Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length)
  285. mA=1.0/sqrt(2*1.0/fabs(double(mCurvature))*mLength);
  286. //Denormalization Factor
  287. mDenormalizeFactor=1.0/mA;
  288. //Calculate the sine and cosine of the heading angle used to rotate the spiral according to the heading
  289. mRotCos=cos(mHdg);
  290. mRotSin=sin(mHdg);
  291. }
  292. //else the motion is in the inverse direction along the spiral
  293. else
  294. {
  295. mNormalDir=false;
  296. mCurvature=mCurvatureStart;
  297. //Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length)
  298. mA=1.0/sqrt(2*1.0/fabs(mCurvature)*mLength);
  299. //Because we move in the inverse direction, we need to rotate the curve according to the heading
  300. //around the last point of the normalized spiral
  301. //Calculate the total length, normalize it and divide by sqrtPiO2, then, calculate the position of the final point.
  302. double L=(mS2-mS)*mA/sqrtPiO2;
  303. fresnl(L,&mEndY,&mEndX);
  304. //Invert the curve if the curvature is negative
  305. if (mCurvature<0)
  306. mEndY=-mEndY;
  307. //Denormalization factor
  308. mDenormalizeFactor=1.0/mA;
  309. //Find the x,y coords of the final point of the curve in local curve coordinates
  310. mEndX*=mDenormalizeFactor*sqrtPiO2;
  311. mEndY*=mDenormalizeFactor*sqrtPiO2;
  312. //Calculate the tangent angle
  313. differenceAngle=L*L*(sqrtPiO2*sqrtPiO2);
  314. double diffAngle;
  315. //Calculate the tangent and heading angle difference that will be used to rotate the spiral
  316. if (mCurvature<0)
  317. {
  318. diffAngle=mHdg-differenceAngle-M_PI;
  319. }
  320. else
  321. {
  322. diffAngle=mHdg+differenceAngle-M_PI;
  323. }
  324. //Calculate the sine and cosine of the difference angle
  325. mRotCos=cos(diffAngle);
  326. mRotSin=sin(diffAngle);
  327. }
  328. }
  329. /**
  330. * Clones and returns the new geometry record
  331. */
  332. RoadGeometry* GeometrySpiral::Clone() const
  333. {
  334. GeometrySpiral* ret=new GeometrySpiral(mS,mX,mY, mHdg, mLength, mCurvatureStart, mCurvatureEnd);
  335. return ret;
  336. }
  337. //-------------------------------------------------
  338. /**
  339. * Setter for the base properties
  340. */
  341. void GeometrySpiral::SetAll(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
  342. {
  343. SetBase(s,x,y,hdg,length,false);
  344. mCurvatureStart=curvatureStart;
  345. mCurvatureEnd=curvatureEnd;
  346. ComputeVars();
  347. }
  348. void GeometrySpiral::SetCurvatureStart(double curvature)
  349. {
  350. mCurvatureStart=curvature;
  351. ComputeVars();
  352. }
  353. void GeometrySpiral::SetCurvatureEnd(double curvature)
  354. {
  355. mCurvatureEnd=curvature;
  356. ComputeVars();
  357. }
  358. //-------------------------------------------------
  359. /**
  360. * Getter for the base properties
  361. */
  362. double GeometrySpiral::GetCurvatureStart()
  363. {
  364. return mCurvatureStart;
  365. }
  366. double GeometrySpiral::GetCurvatureEnd()
  367. {
  368. return mCurvatureEnd;
  369. }
  370. //-------------------------------------------------
  371. /**
  372. * Gets the coordinates at the sample S offset
  373. */
  374. void GeometrySpiral::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  375. {
  376. double l=0.0;
  377. double tmpX=0.0, tmpY=0.0;
  378. //Depending on the moving direction, calculate the length of the curve from its beginning to the current point and normalize
  379. //it by multiplying with the "a" normalization term
  380. //Cephes lib for solving Fresnel Integrals, uses cos/sin (PI/2 * X^2) format in its function.
  381. //So, in order to use the function, transform the argument (which is just L) by dividing it by the sqrt(PI/2) factor and multiply the results by it.
  382. if (mNormalDir)
  383. {
  384. l=(s_check-mS)*mA/sqrtPiO2;
  385. }
  386. else
  387. {
  388. l=(mS2-s_check)*mA/sqrtPiO2;
  389. }
  390. //Solve the Fresnel Integrals
  391. fresnl(l,&tmpY,&tmpX);
  392. //If the curvature is negative, invert the curve on the Y axis
  393. if (mCurvature<0)
  394. tmpY=-tmpY;
  395. //Denormalize the results and multiply by the sqrt(PI/2) term
  396. tmpX*=mDenormalizeFactor*sqrtPiO2;
  397. tmpY*=mDenormalizeFactor*sqrtPiO2;
  398. //Calculate the heading at the found position. Kill the sqrt(PI/2) term that was added to the L
  399. l=(s_check-mS)*mA;
  400. double tangentAngle = l*l;
  401. if (mCurvature<0)
  402. tangentAngle=-tangentAngle;
  403. retHDG=mHdg+tangentAngle;
  404. if (!mNormalDir)
  405. {
  406. //If we move in the inverse direction, translate the spiral in order to rotate around its final point
  407. tmpX-=mEndX;
  408. tmpY-=mEndY;
  409. //also invert the spiral in the y axis
  410. tmpY=-tmpY;
  411. }
  412. //Translate the curve to the required position and rotate it according to the heading
  413. retX=mX+ tmpX*mRotCos-tmpY*mRotSin;
  414. retY=mY+ tmpY*mRotCos+tmpX*mRotSin;
  415. }
  416. //***********************************************************************************
  417. //Cubic Polynom geometry. Has to be implemented
  418. //***********************************************************************************
  419. /**
  420. * Constructor that initializes the base properties of the record
  421. */
  422. GeometryPoly3::GeometryPoly3 (double s, double x, double y, double hdg, double length, double a, double b,double c, double d ): RoadGeometry(s, x, y, hdg, length)
  423. {
  424. SetGeomType(3); mA=a; mB=b; mC=c; mD=d;
  425. }
  426. /**
  427. * Clones and returns the new geometry record
  428. */
  429. RoadGeometry* GeometryPoly3::Clone() const
  430. {
  431. GeometryPoly3* ret=new GeometryPoly3(mS,mX,mY, mHdg, mLength, mA, mB, mC, mD);
  432. return ret;
  433. }
  434. //-------------------------------------------------
  435. /**
  436. * Setter for the base properties
  437. */
  438. void GeometryPoly3::SetAll(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
  439. {
  440. SetBase(s,x,y,hdg,length,false);
  441. mA=a;
  442. mB=b;
  443. mC=c;
  444. mD=d;
  445. ComputeVars();
  446. }
  447. //GetA to GetD, Added by Yuchuli
  448. double GeometryPoly3::GetA()
  449. {
  450. return mA;
  451. }
  452. double GeometryPoly3::GetB()
  453. {
  454. return mB;
  455. }
  456. double GeometryPoly3::GetC()
  457. {
  458. return mC;
  459. }
  460. double GeometryPoly3::GetD()
  461. {
  462. return mD;
  463. }
  464. #include "xodrfunc.h"
  465. void GeometryPoly3::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  466. {
  467. double currentLength = s_check - mS;
  468. double flen = 0;
  469. double u=0;
  470. double v;
  471. double x,y;
  472. double oldx,oldy;
  473. oldx = mX;
  474. oldy = mY;
  475. double du =0.1;
  476. if(currentLength<du)
  477. {
  478. retX = mX;
  479. retY = mY;
  480. retHDG = mHdg;
  481. return;
  482. }
  483. u = du;
  484. while(flen <= currentLength)
  485. {
  486. double fdis = 0;
  487. v = mA + mB*u + mC*u*u + mD*u*u*u;
  488. x = mX + u*cos(mHdg) - v*sin(mHdg);
  489. y = mY + u*sin(mHdg) + v*cos(mHdg);
  490. fdis = sqrt(pow(x- oldx,2)+pow(y-oldy,2));
  491. oldx = x;
  492. oldy = y;
  493. flen = flen + fdis;
  494. u = u + du;
  495. retHDG = xodrfunc::CalcHdg(QPointF(oldx,oldy),QPointF(x,y));
  496. }
  497. }
  498. //***********************************************************************************
  499. //Cubic Polynom geometry. Has to be implemented. Added By Yuchuli
  500. //***********************************************************************************
  501. /**
  502. * Constructor that initializes the base properties of the record
  503. */
  504. GeometryParamPoly3::GeometryParamPoly3 (double s, double x, double y, double hdg, double length,double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd ): RoadGeometry(s, x, y, hdg, length)
  505. {
  506. SetGeomType(4); muA=ua; muB=ub; muC=uc; muD=ud;mvA=va; mvB=vb; mvC=vc; mvD=vd;
  507. }
  508. /**
  509. * Clones and returns the new geometry record
  510. */
  511. RoadGeometry* GeometryParamPoly3::Clone() const
  512. {
  513. GeometryParamPoly3* ret=new GeometryParamPoly3(mS,mX,mY, mHdg, mLength, muA, muB, muC, muD,mvA,mvB,mvC,mvD);
  514. return ret;
  515. }
  516. //-------------------------------------------------
  517. /**
  518. * Setter for the base properties
  519. */
  520. void GeometryParamPoly3::SetAll(double s, double x, double y, double hdg, double length, double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd )
  521. {
  522. SetBase(s,x,y,hdg,length,false);
  523. muA=ua;
  524. muB=ub;
  525. muC=uc;
  526. muD=ud;
  527. mvA=va;
  528. mvB=vb;
  529. mvC=vc;
  530. mvD=vd;
  531. ComputeVars();
  532. }
  533. double GeometryParamPoly3::GetuA(){return muA;}
  534. double GeometryParamPoly3::GetuB(){return muB;}
  535. double GeometryParamPoly3::GetuC(){return muC;}
  536. double GeometryParamPoly3::GetuD(){return muD;}
  537. double GeometryParamPoly3::GetvA(){return mvA;}
  538. double GeometryParamPoly3::GetvB(){return mvB;}
  539. double GeometryParamPoly3::GetvC(){return mvC;}
  540. double GeometryParamPoly3::GetvD(){return mvD;}
  541. void GeometryParamPoly3::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  542. {
  543. }
  544. //***********************************************************************************
  545. //Base class for Geometry blocks
  546. //***********************************************************************************
  547. /**
  548. * Constructor
  549. */
  550. GeometryBlock::GeometryBlock()
  551. {}
  552. /**
  553. * Copy constructor
  554. */
  555. GeometryBlock::GeometryBlock(const GeometryBlock& geomBlock)
  556. {
  557. for (vector<RoadGeometry*>::const_iterator member = geomBlock.mGeometryBlockElement.begin(); member != geomBlock.mGeometryBlockElement.end(); member++)
  558. mGeometryBlockElement.push_back((*member)->Clone());
  559. }
  560. /**
  561. * Assignment operator overload
  562. */
  563. const GeometryBlock& GeometryBlock::operator=(const GeometryBlock& otherGeomBlock)
  564. {
  565. if (this!= &otherGeomBlock)
  566. {
  567. for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin(); member != mGeometryBlockElement.end(); member++)
  568. {
  569. if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
  570. {
  571. delete line;
  572. }
  573. else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
  574. {
  575. delete arc;
  576. }
  577. else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
  578. {
  579. delete spiral;
  580. }
  581. else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
  582. {
  583. delete poly;
  584. }
  585. else if(GeometryParamPoly3 * parampoly = dynamic_cast<GeometryParamPoly3 *>(*member) )
  586. {
  587. delete parampoly;
  588. }
  589. }
  590. mGeometryBlockElement.clear();
  591. for (vector<RoadGeometry*>::const_iterator member = otherGeomBlock.mGeometryBlockElement.begin(); member != otherGeomBlock.mGeometryBlockElement.end(); member++)
  592. mGeometryBlockElement.push_back((*member)->Clone());
  593. }
  594. return *this;
  595. }
  596. //-------------------------------------------------
  597. /**
  598. * Methods used to add geometry recors to the geometry record vector
  599. */
  600. void GeometryBlock::AddGeometryLine(double s, double x, double y, double hdg, double length)
  601. {
  602. mGeometryBlockElement.push_back(new GeometryLine(s, x, y, hdg, length));
  603. }
  604. void GeometryBlock::AddGeometryArc(double s, double x, double y, double hdg, double length, double curvature)
  605. {
  606. mGeometryBlockElement.push_back(new GeometryArc(s, x, y, hdg, length, curvature));
  607. }
  608. void GeometryBlock::AddGeometrySpiral(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
  609. {
  610. mGeometryBlockElement.push_back(new GeometrySpiral(s, x, y, hdg, length, curvatureStart, curvatureEnd));
  611. }
  612. void GeometryBlock::AddGeometryPoly3(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
  613. {
  614. mGeometryBlockElement.push_back(new GeometryPoly3(s, x, y, hdg, length, a, b, c, d));
  615. }
  616. void GeometryBlock::AddGeometryParamPoly3(double s, double x, double y, double hdg, double length, double ua, double ub, double uc, double ud, double va, double vb, double vc, double vd)
  617. {
  618. mGeometryBlockElement.push_back(new GeometryParamPoly3(s,x,y,hdg,length,ua,ub,uc,ud,va,vb,vc,vd));
  619. }
  620. //-------------------------------------------------
  621. /**
  622. * Getter for the geometry record at a given index position of the vector
  623. */
  624. RoadGeometry* GeometryBlock::GetGeometryAt(int index)
  625. {
  626. return mGeometryBlockElement.at(index);
  627. }
  628. /**
  629. * Getter for the overal block length (summ of geometry record lengths)
  630. */
  631. double GeometryBlock::GetBlockLength()
  632. {
  633. double lTotal=0;
  634. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  635. {
  636. lTotal+=mGeometryBlockElement.at(i)->GetLength();
  637. }
  638. return lTotal;
  639. }
  640. /**
  641. * Checks if the block is a straight line block or a turn
  642. */
  643. bool GeometryBlock::CheckIfLine()
  644. {
  645. if(mGeometryBlockElement.size()>1) return false;
  646. else return true;
  647. }
  648. //-------------------------------------------------
  649. /**
  650. * Recalculates the geometry blocks when one of the geometry records is modified
  651. * Makes sure that every geometry records starts where the previous record ends
  652. */
  653. void GeometryBlock::Recalculate(double s, double x, double y, double hdg)
  654. {
  655. double lS=s;
  656. double lX=x;
  657. double lY=y;
  658. double lHdg=hdg;
  659. if(mGeometryBlockElement.size()==1)
  660. {
  661. GeometryLine *lGeometryLine = static_cast<GeometryLine*>(mGeometryBlockElement.at(0));
  662. if(lGeometryLine!=NULL)
  663. {
  664. // Updates the line to reflect the changes of the previous block
  665. lGeometryLine->SetBase(lS,lX,lY,lHdg,lGeometryLine->GetLength());
  666. }
  667. }
  668. else if(mGeometryBlockElement.size()==3)
  669. {
  670. GeometrySpiral *lGeometrySpiral1 = static_cast<GeometrySpiral*>(mGeometryBlockElement.at(0));
  671. GeometryArc *lGeometryArc = static_cast<GeometryArc*>(mGeometryBlockElement.at(1));
  672. GeometrySpiral *lGeometrySpiral2 = static_cast<GeometrySpiral*>(mGeometryBlockElement.at(2));
  673. if(lGeometrySpiral1!=NULL && lGeometryArc!=NULL && lGeometrySpiral2!=NULL)
  674. {
  675. // Updates the first spiral to reflect the changes of the previous block
  676. lGeometrySpiral1->SetBase(lS,lX,lY,lHdg,lGeometrySpiral1->GetLength());
  677. // Reads the new coords of the spiral
  678. lS=lGeometrySpiral1->GetS2();
  679. lGeometrySpiral1->GetCoords(lS,lX,lY,lHdg);
  680. // Updates the arc to reflect the changes to the first spiral
  681. lGeometryArc->SetBase(lS,lX,lY,lHdg,lGeometryArc->GetLength());
  682. // Reads the new coords of the arc
  683. lS=lGeometryArc->GetS2();
  684. lGeometryArc->GetCoords(lS,lX,lY,lHdg);
  685. // Updates the second spiral to reflect hte changes to the arc
  686. lGeometrySpiral2->SetBase(lS,lX,lY,lHdg,lGeometrySpiral2->GetLength());
  687. }
  688. }
  689. }
  690. //-------------------------------------------------
  691. /**
  692. * Gets the S at the end of the block
  693. */
  694. double GeometryBlock::GetLastS2()
  695. {
  696. if(mGeometryBlockElement.size()>0)
  697. return mGeometryBlockElement.at(mGeometryBlockElement.size()-1)->GetS2();
  698. else
  699. return 0;
  700. }
  701. /**
  702. * Gets the last geometry in the geometry vector
  703. */
  704. RoadGeometry* GeometryBlock::GetLastGeometry()
  705. {
  706. return mGeometryBlockElement.at(mGeometryBlockElement.size()-1);
  707. }
  708. /**
  709. * Gets the coordinates at the end of the last geometry
  710. */
  711. short int GeometryBlock::GetLastCoords(double &s, double &retX, double &retY, double &retHDG)
  712. {
  713. int lSize = mGeometryBlockElement.size();
  714. if(lSize>0)
  715. {
  716. RoadGeometry* lGeometry = mGeometryBlockElement.at(lSize-1);
  717. s = lGeometry->GetS2();
  718. lGeometry->GetCoords(s, retX, retY, retHDG);
  719. }
  720. else
  721. {
  722. s=0;
  723. retX=0;
  724. retY=0;
  725. retHDG=0;
  726. }
  727. return 0;
  728. }
  729. /**
  730. * Check if sample S belongs to this block
  731. */
  732. bool GeometryBlock::CheckInterval(double s_check)
  733. {
  734. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  735. {
  736. //if the s_check belongs to one of the geometries
  737. if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
  738. return true;
  739. }
  740. return false;
  741. }
  742. /**
  743. * Gets the coordinates at the sample S offset
  744. */
  745. short int GeometryBlock::GetCoords(double s_check, double &retX, double &retY)
  746. {
  747. double tmp;
  748. return GetCoords(s_check, retX, retY, tmp);
  749. }
  750. /**
  751. * Gets the coordinates and heading at the end of the last geometry
  752. */
  753. short int GeometryBlock::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  754. {
  755. // go through all the elements
  756. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  757. {
  758. //if the s_check belongs to one of the geometries
  759. if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
  760. {
  761. //get the x,y coords and return the type of the geometry
  762. mGeometryBlockElement.at(i)->GetCoords(s_check, retX, retY, retHDG);
  763. return mGeometryBlockElement.at(i)->GetGeomType();
  764. }
  765. }
  766. //if nothing found, return -999
  767. return -999;
  768. }
  769. //-------------------------------------------------
  770. /**
  771. * Destructor
  772. */
  773. GeometryBlock::~GeometryBlock()
  774. {
  775. // Clears the geometry record vector
  776. for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin(); member != mGeometryBlockElement.end(); member++)
  777. {
  778. if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
  779. {
  780. delete line;
  781. }
  782. else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
  783. {
  784. delete arc;
  785. }
  786. else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
  787. {
  788. delete spiral;
  789. }
  790. else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
  791. {
  792. delete poly;
  793. }
  794. else if(GeometryParamPoly3 *parampoly = dynamic_cast<GeometryParamPoly3 *>(*member))
  795. {
  796. delete parampoly;
  797. }
  798. }
  799. mGeometryBlockElement.clear();
  800. }
  801. //----------------------------------------------------------------------------------