Guest User

Untitled

a guest
Oct 16th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.76 KB | None | 0 0
  1. /*
  2.  
  3. *******************************************************************************
  4. PointCloudNav.h
  5. *******************************************************************************
  6.  
  7. */
  8.  
  9. #pragma once
  10. #include <iostream>
  11. #include <cstdlib>
  12. #include <list>
  13. #include <sstream>
  14. #include <iomanip>
  15. using std::cerr;
  16. using std::cout;
  17. using std::endl;
  18. using std::rand;
  19. using std::list;
  20. using std::allocator;
  21. using std::string;
  22. using std::stringstream;
  23. using std::ostream;
  24.  
  25.  
  26. namespace pcn
  27. {
  28. int ERROR_CODE_INIT_VOXEL_POSITION = 1;
  29. int ERROR_CODE_INIT_VOXEL_DENSITY = 2;
  30. int ERROR_CODE_INIT_OCTREE_VOXELS = 3;
  31. int ERROR_CODE_INVALID_LOWER_LIMIT = 4;
  32. int ERROR_CODE_INVALIT_UPPER_LIMIT = 5;
  33.  
  34. class PCVoxel
  35. {
  36. private:
  37. double position[3];
  38. double density;
  39. void init(const double x, const double y, const double z, const double d)
  40. {
  41. // cout << x << ", " << y << ", " << z << endl;
  42.  
  43. if (d < 0.0 || d > 1.0)
  44. {
  45. cerr << "Incorrect value for density of Voxel";
  46. exit(ERROR_CODE_INIT_VOXEL_DENSITY);
  47. }
  48.  
  49. position[0] = x;
  50. position[1] = y;
  51. position[2] = z;
  52.  
  53. density = d;
  54. }
  55. public:
  56. PCVoxel()
  57. {
  58. init(0.0, 0.0, 0.0, 1.0);
  59. }
  60.  
  61. PCVoxel(const double x, const double y, const double z)
  62. {
  63. readDensity();
  64. init(x, y, z, this->getDensity());
  65. //cout << this->getXPosition() << ", " << this->getYPosition() << ", " << this->getZPosition() << endl;
  66. }
  67.  
  68. PCVoxel(const double x, const double y, const double z, const double d)
  69. {
  70.  
  71. init(x, y, z, d);
  72. }
  73.  
  74. PCVoxel(double pos[], double d)
  75. {
  76. if (d < 0.0 || d > 1.0)
  77. {
  78. cerr << "Incorrect array size for position of Voxel";
  79. exit(ERROR_CODE_INIT_VOXEL_POSITION);
  80. }
  81.  
  82. init(pos[0], pos[1], pos[2], d);
  83. }
  84.  
  85. PCVoxel(PCVoxel* rhs)
  86. {
  87. init((*rhs).position[0], (*rhs).position[1],
  88. (*rhs).position[2], (*rhs).density);
  89. }
  90.  
  91. ~PCVoxel() { delete [] position; }
  92.  
  93. PCVoxel& operator=(PCVoxel const& rhs);
  94.  
  95. bool operator==(PCVoxel const& rhs);
  96.  
  97. bool operator<(const PCVoxel& rhs);
  98.  
  99. void setXPosition (const double x) { position[0] = x; }
  100. void setYPosition (const double y) { position[1] = y; }
  101. void setZPosition (const double z) { position[2] = z; }
  102. void setDensity (const double d) { density = d; }
  103.  
  104. double getXPosition() const { return position[0]; }
  105. double getYPosition() const { return position[1]; }
  106. double getZPosition() const { return position[2]; }
  107. double getDensity() const { return density; }
  108.  
  109. void readDensity() {
  110. // TO DO: implement proper method for reading the density of the voxel
  111. density = (double)(rand() % 100) / 100;
  112. }
  113.  
  114. inline string getObjectAsString() const;
  115.  
  116. static PCVoxel* interpolate(const PCVoxel& first, const PCVoxel& second);
  117.  
  118. };
  119.  
  120. inline ostream& operator<<(ostream& lhs, const PCVoxel& rhs)
  121. {
  122. lhs << rhs.getObjectAsString();
  123. return lhs;
  124. }
  125.  
  126. typedef list<PCVoxel, allocator<PCVoxel> > LISTVOXELS;
  127. typedef PCVoxel ARRAYVOXELS[8];
  128.  
  129. class PCOctree
  130. {
  131. private:
  132. PCVoxel **borderPoints;
  133. double repel;
  134. public:
  135. PCOctree();
  136. PCOctree(ARRAYVOXELS &voxels);
  137. ~PCOctree() { delete [] borderPoints; }
  138. PCVoxel** getBorderPoints() const;
  139. double getRepel() const;
  140. PCOctree* breakDown () const;
  141. };
  142.  
  143. ostream& operator<<(ostream& lhs, const PCOctree& rhs)
  144. {
  145. stringstream toString;
  146. PCVoxel **borderPoints = rhs.getBorderPoints();
  147. for (int i = 0; i < 8; i++)
  148. {
  149. cout << *(borderPoints[i]) << endl;
  150. toString << *(borderPoints[i]) << endl;
  151. }
  152. return lhs << toString;
  153. }
  154.  
  155.  
  156. class PCGrid
  157. {
  158. friend std::ostream& operator<<(std::ostream& lhs, const PCGrid& rhs);
  159. private:
  160. int sizeX, sizeY, sizeZ;
  161. PCVoxel **grid;
  162. void init(const double xMin, const double yMin, const double zMin,
  163. const double xMax, const double yMax, const double zMax,
  164. const int divX, const int divY, const int divZ);
  165. public:
  166. PCGrid();
  167. PCGrid(const double xMin, const double yMin, const double zMin,
  168. const double xMax, const double yMax, const double zMax,
  169. const int divX, const int divY, const int divZ);
  170. ~PCGrid() { delete [] grid; }
  171. int getSizeOfX() const;
  172. int getSizeOfY() const;
  173. int getSizeOfZ() const;
  174. PCVoxel& getVoxelAt(int posX, int posY, int posZ) const;
  175. double* readDensities();
  176. };
  177.  
  178.  
  179. ostream& operator<<(ostream& lhs, const PCGrid& rhs)
  180. {
  181. stringstream toString;
  182. int sizeX = rhs.getSizeOfX(), sizeY = rhs.getSizeOfY(),
  183. sizeZ = rhs.getSizeOfZ();
  184. PCVoxel current;
  185. for (int x = 0; x < sizeX; x++)
  186. {
  187. for (int y = 0; y < sizeY; y++)
  188. {
  189. for (int z = 0; z < sizeZ; z++)
  190. {
  191. toString << rhs.getVoxelAt(x, y, z) << endl;
  192. }
  193. }
  194. }
  195. return lhs << toString;
  196. }
  197.  
  198. class PointCloudNavigation
  199. {
  200. private:
  201. PCGrid *grid;
  202. LISTVOXELS getSurface( const PCOctree &oct, double rMin, double rMax );
  203. public:
  204. PointCloudNavigation(
  205. double xMin, double yMin, double zMin,
  206. double xMax, double yMax, double zMax,
  207. int divX, int divY, int divZ);
  208. ~PointCloudNavigation() { delete grid; }
  209. PCGrid* accessGrid ();
  210. LISTVOXELS findPathMesh( double tolFloor, double tolCeiling );
  211.  
  212. };
  213. };
  214.  
  215.  
  216. /*
  217.  
  218. *******************************************************************************
  219. PointCloudNav.cpp
  220. *******************************************************************************
  221.  
  222. */
  223.  
  224. #include <iostream>
  225. #include <cstdlib>
  226. #include "PointCloudNav.h"
  227.  
  228. using namespace pcn;
  229. using std::cerr;
  230. using std::cout;
  231. using std::cin;
  232. using std::endl;
  233. using std::rand;
  234.  
  235. /*
  236.  
  237. *******************************************************************************
  238. VOXEL
  239. *******************************************************************************
  240.  
  241. */
  242.  
  243. PCVoxel& PCVoxel::operator=(const PCVoxel& rhs)
  244. {
  245. delete [] position;
  246. init(rhs.position[0],rhs.position[1],
  247. rhs.position[2], rhs.density);
  248. return *this;
  249. }
  250.  
  251. bool PCVoxel::operator==(const PCVoxel& rhs)
  252. {
  253. bool equalX = this->getXPosition() == rhs.getXPosition(),
  254. equalY = this->getYPosition() == rhs.getYPosition(),
  255. equalZ = this->getZPosition() == rhs.getZPosition(),
  256. equalD = this->getDensity() == rhs.getDensity();
  257. return equalX && equalY && equalZ && equalD;
  258. }
  259.  
  260. bool PCVoxel::operator<(const PCVoxel& rhs)
  261. {
  262. if (this->getXPosition() == rhs.getXPosition())
  263. {
  264. if (this->getYPosition() == rhs.getYPosition())
  265. {
  266. if (this->getZPosition() < rhs.getZPosition())
  267. {
  268. return true;
  269. }
  270. else { return false; }
  271. }
  272. else if (this->getYPosition() < rhs.getYPosition())
  273. {
  274. return true;
  275. }
  276. else { return false; }
  277. }
  278. else if (this->getXPosition() < rhs.getXPosition())
  279. {
  280. return true;
  281. }
  282. else
  283. {
  284. return false;
  285. }
  286. }
  287.  
  288. PCVoxel* PCVoxel::interpolate(const PCVoxel& first, const PCVoxel& second)
  289. {
  290. double meanX, meanY, meanZ, meanD;
  291. meanX = (first.getXPosition() + second.getXPosition()) / 2;
  292. meanY = (first.getYPosition() + second.getYPosition()) / 2;
  293. meanZ = (first.getZPosition() + second.getZPosition()) / 2;
  294. meanD = ((double)(rand() % 100) / 100) * (second.getDensity() - first.getDensity()) + first.getDensity();
  295. //cout << "Density: " << meanD << endl;
  296.  
  297. return new PCVoxel(meanX, meanY, meanZ, meanD);
  298. }
  299.  
  300. string PCVoxel::getObjectAsString() const
  301. {
  302. stringstream toString;
  303. toString << "( " << position[0] << ", " << position[1] << ", "
  304. << position[2] << ") \ndensity of point cloud: " << getDensity() << endl;
  305. return toString.str();
  306. }
  307.  
  308. /*
  309.  
  310. *******************************************************************************
  311. OCTREE
  312. *******************************************************************************
  313.  
  314. */
  315.  
  316. PCOctree::PCOctree() {}
  317.  
  318. PCOctree::PCOctree(ARRAYVOXELS &voxels)
  319. {
  320.  
  321. cout << "DEBUG: size of voxels: " << sizeof(voxels) / sizeof(PCVoxel) << endl;
  322.  
  323. if ((sizeof(voxels) / sizeof(PCVoxel)) != 8)
  324. {
  325. cerr << "Invalid number of Voxels given" << endl;
  326. exit(ERROR_CODE_INIT_OCTREE_VOXELS);
  327. }
  328. else
  329. {
  330. borderPoints = new PCVoxel*[8];
  331. for (int i = 0; i < 8; i++)
  332. borderPoints[i] = &(voxels[i]);
  333. }
  334. }
  335.  
  336. PCVoxel** PCOctree::getBorderPoints() const
  337. {
  338. return borderPoints;
  339. }
  340.  
  341. double PCOctree::getRepel () const
  342. {
  343. double densityTotal = 0;
  344. PCVoxel** borderPoints = getBorderPoints();
  345. for ( int pos = 0; pos < 8; pos++)
  346. {
  347. PCVoxel* current = borderPoints[pos];
  348. cout << *current << endl;
  349. densityTotal += current->getDensity();
  350. //cout << "cumulative total: " << densityTotal << endl;
  351. }
  352. return densityTotal / 8;
  353. }
  354.  
  355. PCOctree* PCOctree::breakDown () const
  356. {
  357. PCVoxel *helper = new PCVoxel[19];
  358.  
  359. const int H01 = 0, H02 = 1, H04 = 2, H13 = 3, H15 = 4, H23 = 5,
  360. H26 = 6, H37 = 7, H45 = 8, H46 = 9, H57 = 10, H67 = 11,
  361. H_TOP = 12, H_BOTTOM = 13, H_SOUTH = 14, H_NORTH = 15,
  362. H_EAST = 16, H_WEST = 17, H_CENTER = 18;
  363.  
  364. helper[H01] = PCVoxel::interpolate(*borderPoints[0], *borderPoints[1]);
  365. helper[H02] = PCVoxel::interpolate(*borderPoints[0], *borderPoints[2]);
  366. helper[H04] = PCVoxel::interpolate(*borderPoints[0], *borderPoints[4]);
  367. helper[H13] = PCVoxel::interpolate(*borderPoints[1], *borderPoints[3]);
  368. helper[H15] = PCVoxel::interpolate(*borderPoints[1], *borderPoints[5]);
  369. helper[H23] = PCVoxel::interpolate(*borderPoints[2], *borderPoints[3]);
  370. helper[H26] = PCVoxel::interpolate(*borderPoints[2], *borderPoints[6]);
  371. helper[H37] = PCVoxel::interpolate(*borderPoints[3], *borderPoints[7]);
  372. helper[H45] = PCVoxel::interpolate(*borderPoints[4], *borderPoints[5]);
  373. helper[H46] = PCVoxel::interpolate(*borderPoints[4], *borderPoints[6]);
  374. helper[H57] = PCVoxel::interpolate(*borderPoints[5], *borderPoints[7]);
  375. helper[H67] = PCVoxel::interpolate(*borderPoints[6], *borderPoints[7]);
  376.  
  377. helper[H_BOTTOM] = PCVoxel::interpolate(
  378. *PCVoxel::interpolate(helper[H01], helper[H45]),
  379. *PCVoxel::interpolate(helper[H04], helper[H15]));
  380.  
  381. helper[H_TOP] = PCVoxel::interpolate(
  382. *PCVoxel::interpolate(helper[H23], helper[H67]),
  383. *PCVoxel::interpolate(helper[H26], helper[H37]));
  384.  
  385. helper[H_NORTH] = PCVoxel::interpolate(
  386. *PCVoxel::interpolate(helper[H13], helper[H57]),
  387. *PCVoxel::interpolate(helper[H15], helper[H37]));
  388.  
  389. helper[H_SOUTH] = PCVoxel::interpolate(
  390. *PCVoxel::interpolate(helper[H02], helper[H46]),
  391. *PCVoxel::interpolate(helper[H04], helper[H26]));
  392.  
  393. helper[H_WEST] = PCVoxel::interpolate(
  394. *PCVoxel::interpolate(helper[H02], helper[H13]),
  395. *PCVoxel::interpolate(helper[H01], helper[H23]));
  396.  
  397. helper[H_EAST] = PCVoxel::interpolate(
  398. *PCVoxel::interpolate(helper[H46], helper[H57]),
  399. *PCVoxel::interpolate(helper[H45], helper[H67]));
  400.  
  401. helper[H_CENTER] = PCVoxel::interpolate(
  402. *PCVoxel::interpolate(
  403. *PCVoxel::interpolate(helper[H_TOP], helper[H_BOTTOM]),
  404. *PCVoxel::interpolate(helper[H_SOUTH], helper[H_NORTH])
  405. ), *PCVoxel::interpolate(helper[H_EAST], helper[H_WEST]));
  406.  
  407. /*
  408.  
  409.  
  410. 3-----37-----7
  411. /| /|
  412. 23 | 67 |
  413. / 13 / 57
  414. 2---+-26-----6 |
  415. | | | |
  416. | 1-----15-+---5
  417. 02 / 46 /
  418. | 01 | 45 y z
  419. |/ |/ |/
  420. 0-----04-----4 0--x
  421.  
  422. */
  423.  
  424. PCVoxel relevant[8][8] = {
  425. // 1st Subtree
  426. { borderPoints[0], helper[H01], helper[H02], helper[H_WEST],
  427. helper[H04], helper[H_BOTTOM], helper[H_SOUTH], helper[H_CENTER] },
  428. // 2nd Subtree
  429. { helper[H01], borderPoints[1], helper[H_WEST], helper[H13],
  430. helper[H_BOTTOM], helper[H15], helper[H_CENTER], helper[H_NORTH] },
  431. // 3rd Subtree
  432. { helper[H02], helper[H_WEST], borderPoints[2], helper[H23],
  433. helper[H_SOUTH], helper[H_CENTER], helper[H26], helper[H_TOP] },
  434. // 4th Subtree
  435. { helper[H_WEST], helper[H13], helper[H23], borderPoints[3],
  436. helper[H_CENTER], helper[H_NORTH], helper[H_TOP], helper[H37] },
  437. // 5th Subtree
  438. { helper[H04], helper[H_BOTTOM], helper[H_SOUTH], helper[H_CENTER],
  439. borderPoints[4], helper[H45], helper[H46], helper[H_EAST] },
  440. // 6th Subtree
  441. { helper[H_BOTTOM], helper[H15], helper[H_CENTER], helper[H_NORTH],
  442. helper[H45], borderPoints[5], helper[H_EAST], helper[H57] },
  443. // 7th Subtree
  444. { helper[H_SOUTH], helper[H_CENTER], helper[H26], helper[H_TOP],
  445. helper[H46], helper[H_EAST], borderPoints[6], helper[H67] },
  446. // 8th Subtree
  447. { helper[H_CENTER], helper[H_NORTH], helper[H_TOP], helper[H37],
  448. helper[H_EAST], helper[H57], helper[H67], borderPoints[7] },
  449. };
  450.  
  451. PCOctree *solution_depot[8];
  452.  
  453. for (int i = 0; i < 8; i++)
  454. solution_depot[i] = new PCOctree(relevant[i]);
  455.  
  456. PCOctree solution[8] = { *solution_depot[0], *solution_depot[1],
  457. *solution_depot[2], *solution_depot[3], *solution_depot[4],
  458. *solution_depot[5], *solution_depot[6], *solution_depot[7] };
  459.  
  460. return solution;
  461. }
  462.  
  463. /*
  464.  
  465. *******************************************************************************
  466. GRID
  467. *******************************************************************************
  468.  
  469. */
  470.  
  471. void PCGrid::init(const double xMin, const double yMin, const double zMin,
  472. const double xMax, const double yMax, const double zMax,
  473. const int divX, const int divY, const int divZ)
  474. {
  475. int index = 0;
  476.  
  477. double xStep = (xMax - xMin)/divX, yStep = (yMax - yMin)/divY,
  478. zStep = (zMax - zMin)/divZ;
  479.  
  480. grid = new PCVoxel *[sizeX * sizeY * sizeZ];
  481. for (double posX = xMin; posX <= xMax; posX += xStep)
  482. {
  483. for (double posY = yMin; posY <= yMax; posY += yStep)
  484. {
  485. for (double posZ = zMin; posZ <= zMax; posZ += zStep)
  486. {
  487. grid[index] = new PCVoxel(posX, posY, posZ);
  488. //cout << *(grid[index]) << endl;
  489. index++;
  490. }
  491. }
  492. }
  493. }
  494.  
  495. PCGrid::PCGrid(const double xMin, const double yMin, const double zMin,
  496. const double xMax, const double yMax, const double zMax,
  497. const int divX, const int divY, const int divZ)
  498. {
  499.  
  500. this->sizeX = divX + 1;
  501. this->sizeY = divY + 1;
  502. this->sizeZ = divZ + 1;
  503. init(xMin, yMin, zMin, xMax, yMax, zMax, divX, divY, divZ);
  504. }
  505.  
  506. int PCGrid::getSizeOfX() const { return sizeX; }
  507. int PCGrid::getSizeOfY() const { return sizeY; }
  508. int PCGrid::getSizeOfZ() const { return sizeZ; }
  509.  
  510. PCVoxel& PCGrid::getVoxelAt(int posX, int posY, int posZ) const
  511. {
  512. return *grid[posZ + posY * sizeY + posX * sizeX];
  513. }
  514.  
  515.  
  516. /*
  517.  
  518. *******************************************************************************
  519. POINT CLOUD NAVIGATION
  520. *******************************************************************************
  521.  
  522. */
  523.  
  524. PointCloudNavigation::PointCloudNavigation(
  525. double xMin, double yMin, double zMin,
  526. double xMax, double yMax, double zMax,
  527. int divX, int divY, int divZ)
  528. {
  529. grid = new PCGrid( xMin, yMin, zMin,
  530. xMax, yMax, zMax,
  531. divX, divY, divZ);
  532. }
  533.  
  534. PCGrid* PointCloudNavigation::accessGrid ()
  535. {
  536. return grid;
  537. }
  538.  
  539.  
  540. LISTVOXELS PointCloudNavigation::findPathMesh( double tolFloor, double tolCeiling )
  541. {
  542. if ( tolFloor < 0.0 || tolFloor > 1.0 )
  543. {
  544. cerr << "Invalid Value for lower tolerance level" << endl;
  545. exit(ERROR_CODE_INVALID_LOWER_LIMIT);
  546. }
  547.  
  548. if ( tolCeiling < 0.0 || tolCeiling > 1.0 )
  549. {
  550. cerr << "Invalid Value for upper tolerance level" << endl;
  551. exit(ERROR_CODE_INVALIT_UPPER_LIMIT);
  552. }
  553.  
  554. LISTVOXELS solution;
  555.  
  556. for (int posX = 1; posX < (*grid).getSizeOfX(); posX++)
  557. {
  558. for (int posY = 1; posY < (*grid).getSizeOfY(); posY++)
  559. {
  560. for (int posZ = 1; posZ < (*grid).getSizeOfZ(); posZ++)
  561. {
  562. PCVoxel relevant[8] = {
  563. (*grid).getVoxelAt(posX-1, posY-1, posZ-1),
  564. (*grid).getVoxelAt(posX-1, posY-1, posZ ),
  565. (*grid).getVoxelAt(posX-1, posY , posZ-1),
  566. (*grid).getVoxelAt(posX-1, posY , posZ ),
  567. (*grid).getVoxelAt(posX , posY-1, posZ-1),
  568. (*grid).getVoxelAt(posX , posY-1, posZ ),
  569. (*grid).getVoxelAt(posX , posY , posZ-1),
  570. (*grid).getVoxelAt(posX , posY , posZ )
  571. };
  572.  
  573. // cout << "DEBUG: size of voxels: " << sizeof(relevant) / sizeof(PCVoxel*) << endl;
  574.  
  575. PCOctree examine(relevant);
  576. cout << "\nImpending insertion:" << endl;
  577. cout << "size of solution set before: " << solution.size() << endl;
  578.  
  579. LISTVOXELS tmp_solution = getSurface(examine, tolFloor, tolCeiling);
  580.  
  581. if (tmp_solution.empty())
  582. {
  583. cout << "no Voxels added to solution" << endl;
  584. continue;
  585. }
  586.  
  587. solution.merge(tmp_solution);
  588. solution.unique();
  589. cout << "size of soulution set after: " << solution.size() << endl;
  590. delete [] relevant;
  591.  
  592. }
  593. }
  594. }
  595. return solution;
  596. }
  597.  
  598. LISTVOXELS PointCloudNavigation::getSurface( const PCOctree &oct, double rMin, double rMax )
  599. {
  600. LISTVOXELS solution;
  601. //PCOctree v_oct = oct;
  602. list<PCVoxel>::iterator iter;
  603. iter = solution.begin();
  604. double repel = oct.getRepel(); // v_oct.getRepel();
  605. //cout << "\nRepel of Octree: " << repel << endl;
  606. if ( repel > rMax )
  607. {
  608. PCVoxel** borderPoints = oct.getBorderPoints(); // v_oct.getBorderPoints();
  609. for (int i = 0; i < 8; i++)
  610. {
  611. cout << "Punkt: " << *borderPoints[i];
  612. solution.insert(iter, *borderPoints[i]);
  613. ++iter;
  614. }
  615. }
  616. else if ( repel > rMin && repel < rMax)
  617. {
  618.  
  619. PCOctree *breakDown = oct.breakDown(); // v_oct.breakDown();
  620.  
  621. for (int i = 0; i < 8; i++)
  622. {
  623. PCOctree current;
  624. cout << current << endl;
  625. LISTVOXELS tmp_solution = getSurface(current, rMin, rMax);
  626. if (!tmp_solution.empty())
  627. solution.merge(tmp_solution);
  628. }
  629. }
  630. return solution;
  631. }
  632.  
  633. int main(int argc, int argv[])
  634. {
  635. cout << "Building Grid..." << endl; // << pcn->accessGrid() << endl;
  636. PointCloudNavigation pcn(0, 0, 0, 100, 100, 10, 100, 100, 10);
  637. cout << "Grid built!" << endl;
  638.  
  639. cout << endl << "Processing solution..." << endl;
  640. LISTVOXELS solution = pcn.findPathMesh(0.40, 0.55);
  641. LISTVOXELS::const_iterator iter;
  642.  
  643. for (iter = solution.begin(); iter != solution.end(); iter++)
  644. cout << "Lösung: " << endl << *iter << endl;
  645.  
  646. char c;
  647. cin >> c;
  648.  
  649. return 0;
  650. }
Add Comment
Please, Sign In to add comment