Guest User

Untitled

a guest
Oct 23rd, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. /*
  2. hm.cpp - a homework assgnment
  3. Write a program that:
  4. - reads segments from a file,
  5. - moves them to the origin,
  6. - sorts them by angle and distance,
  7. - computes the points in the convex hull,
  8. - computes the area of the convex hull;
  9.  
  10. author: Krasimir Georgiev (comco), FN. 80512.
  11. date: Jun, 2011.
  12. */
  13.  
  14. #include <iostream>
  15. #include <fstream>
  16. #include <vector>
  17. #include <algorithm>
  18. #include <complex>
  19. #include <cmath>
  20. #include <cassert>
  21. using namespace std;
  22.  
  23. typedef double scalar;
  24. typedef complex<scalar> point;
  25. typedef pair<point, point> segment;
  26. vector<segment> read_segments(istream& input) {
  27. unsigned n; input >> n;
  28. vector<segment> segments(n);
  29. for (unsigned i = 0; i < n; ++i) {
  30. scalar ax, ay, bx, by;
  31. input >> ax >> ay >> bx >> by;
  32. point a(ax, ay), b(bx, by);
  33. segments[i] = segment(a, b);
  34. }
  35.  
  36. return segments;
  37. }
  38.  
  39. vector<point> translate_to_origin(vector<segment> const& segments) {
  40. unsigned n = segments.size();
  41. vector<point> vectors(n);
  42. for (unsigned i = 0; i < n; ++i) {
  43. vectors[i] = segments[i].second - segments[i].first;
  44. }
  45.  
  46. return vectors;
  47. }
  48.  
  49. class point_comparator {
  50. vector<point> const& vectors;
  51.  
  52. public:
  53. point_comparator(vector<point> const& vectors)
  54. : vectors(vectors) { }
  55.  
  56. bool operator()(int id_a, int id_b) const {
  57. point const& a = vectors[id_a];
  58. point const& b = vectors[id_b];
  59. scalar angle_a = arg(a);
  60. scalar angle_b = arg(b);
  61. if (angle_a < angle_b) {
  62. return true;
  63. }
  64. else if (angle_a > angle_b) {
  65. return false;
  66. }
  67. else {
  68. return norm(a) < norm(b);
  69. }
  70. }
  71. };
  72.  
  73. void sort_vectors(vector<point> const& vectors, vector<int>& indices) {
  74. point_comparator by_angle_length(vectors);
  75. sort(indices.begin(), indices.end(), by_angle_length);
  76. }
  77.  
  78. inline scalar det(point const& a, point const& b) {
  79. return real(a)*imag(b) - imag(a)*real(b);
  80. }
  81.  
  82. inline bool left(point const& a, point const& b, point const& c) {
  83. return det(b - a, c - a) > 0;
  84. }
  85. // Graham scan
  86. vector<int> convex_hull(vector<point> const& vectors, vector<int> const& indices) {
  87. unsigned n = vectors.size();
  88. if (n < 3) {
  89. return indices;
  90. }
  91.  
  92. vector<int> hull_vectors;
  93. hull_vectors.push_back(indices[0]);
  94. hull_vectors.push_back(indices[1]);
  95. for (unsigned i = 2; i < n; ++i) {
  96. point p = vectors[indices[i]];
  97. while (hull_vectors.size() > 2 &&
  98. !left(vectors[hull_vectors[hull_vectors.size() - 2]],
  99. vectors[hull_vectors[hull_vectors.size() - 1]], p)) {
  100. hull_vectors.pop_back();
  101. }
  102.  
  103. hull_vectors.push_back(indices[i]);
  104. }
  105.  
  106. return hull_vectors;
  107. }
  108.  
  109. void write_points_at_indices(ostream& output, vector<point> const& points, vector<int> const& indices) {
  110. unsigned n = indices.size();
  111. for (int i = 0; i < n; ++i) {
  112. output << indices[i] << " : " << real(points[i]) << ", " << imag(points[i]) << endl;
  113. }
  114. }
  115.  
  116. scalar polygon_area(vector<point> const& points, vector<int> const& indices) {
  117. unsigned n = indices.size();
  118. scalar result = 0.0;
  119.  
  120. for(unsigned i = 0; i < n; ++i) {
  121. unsigned j = (i + 1) % n;
  122. result += det(points[indices[i]], points[indices[j]]);
  123. }
  124.  
  125. result *= 0.5;
  126. return result;
  127. }
  128.  
  129. int main() {
  130. cout << "Format of the input data: " << endl;
  131. cout << "First line: n - the number of segments; " << endl;
  132. cout << "Next n lines: 4 double numbers, representing the coordinates of " << endl;
  133. cout << "two points, describing a segment" << endl;
  134. cout << "Enter a filename containing point pairs: ";
  135. char filename[64];
  136. cin >> filename;
  137. ifstream input(filename);
  138. assert(input.good());
  139.  
  140. vector<segment> segments = read_segments(input);
  141. input.close();
  142. unsigned n = segments.size();
  143. vector<point> points = translate_to_origin(segments);
  144. vector<int> indices(n);
  145. for (int i = 0; i < n; ++i) {
  146. indices[i] = i;
  147. }
  148.  
  149. cout << "Segments translated to the origin: " << endl;
  150. write_points_at_indices(cout, points, indices);
  151. // could support writing the result to a file by
  152. // changing the first argument to an ofstream
  153.  
  154. sort_vectors(points, indices);
  155. cout << "Sorted segments (angle, then distance to the origin): " << endl;
  156. write_points_at_indices(cout, points, indices);
  157.  
  158. vector<int> hull_points = convex_hull(points, indices);
  159. cout << "Points on the convex hull: " << endl;
  160. write_points_at_indices(cout, points, hull_points);
  161.  
  162. // Always non-negative - the convex hull is generated ccw
  163. scalar area = polygon_area(points, hull_points);
  164. cout << "Area of the convex hull: " << area << endl;
  165.  
  166. return 0;
  167. }
Add Comment
Please, Sign In to add comment