C++ program to find the number of triangles amongst horizontal and vertical line segments

C++Server Side ProgrammingProgramming

In this article, we will be discussing a program to find the number of triangles that can be formed by joining the intersection points of the given horizontal and vertical line segments.

For example, let us say we had been given the following line segments. In this we have 3 intersection points. So the number of triangles that can be formed using these points will be 3C2.

   |
---|--------|--
   |        |
   |  --|---|
   |        |

We will be following the Sweep Line Algorithm. We will be storing all the values of the line segments and then checking if the points inside one of the line also compares with the internal points of any other line. This way we can have all the intersection points for the given line segments and then we can easily find the number of possible triangles using the different possible combinations.

Example

 Live Demo

#include<bits/stdc++.h>
#define maxy 1000005
#define maxn 10005
using namespace std;
//to store intersection points
struct i_point {
   int x, y;
   i_point(int a, int b) {
      x = a, y = b;
   }
};
int bit[maxy];
vector < pair <i_point, int> > events;
//to sort the given points
bool com_points(pair<i_point, int> &a, pair<i_point, int> &b) {
   if ( a.first.x != b.first.x )
      return a.first.x < b.first.x;
   else {
      if (a.second == 3 && b.second == 3) {
         return true;
      }
      else if (a.second == 1 && b.second == 3) {
         return true;
      }
      else if (a.second == 3 && b.second == 1) {
         return false;
      }
      else if (a.second == 2 && b.second == 3) {
         return false;
      }
      return true;
   }
}
void topdate_line(int index, int value) {
   while (index < maxn) {
      bit[index] += value;
      index += index & (-index);
   }
}
int query(int index) {
   int res = 0;
   while (index > 0) {
      res += bit[index];
      index -= index & (-index);
   }
   return res;
}
//to insert a line segment
void insertLine(i_point a, i_point b) {
   //in case of horizontal line
   if (a.y == b.y) {
      int begin = min(a.x, b.x);
      int end = max(a.x, b.x);
      events.push_back(make_pair(i_point(begin, a.y), 1));
      events.push_back(make_pair(i_point(end, a.y), 2));
   }
   //in case of vertical line
   else {
      int top = max(b.y, a.y);
      int bottom = min(b.y, a.y);
      events.push_back(make_pair(i_point(a.x, top), 3));
      events.push_back(make_pair(i_point(a.x, bottom), 3));
   }
}
//to calculate number of intersection points
int calc_i_points() {
   int i_points = 0;
   for (int i = 0 ; i < events.size() ; i++) {
      if (events[i].second == 1) {
         topdate_line(events[i].first.y, 1);
      }
      else if (events[i].second == 2) {
         topdate_line(events[i].first.y, -1);
      }
      else {
         int bottom = events[i++].first.y;
         int top = events[i].first.y;
         i_points += query(top) - query(bottom);
      }
   }
   return i_points;
}
int calc_triangles() {
   int points = calc_i_points();
   if ( points >= 3 )
      return ( points * (points - 1) * (points - 2) ) / 6;
   else
      return 0;
}
int main() {
   insertLine(i_point(3, 2), i_point(3, 13));
   insertLine(i_point(1, 5), i_point(3, 5));
   insertLine(i_point(8, 2), i_point(8, 8));
   insertLine(i_point(3, 4), i_point(6, 4));
   insertLine(i_point(4, 3), i_point(4, 5));
   sort(events.begin(), events.end(), com_points);
   cout << "Possible number of triangles : " << calc_triangles() << endl;
   return 0;
}

Output

Possible number of triangles : 1
raja
Published on 03-Oct-2019 12:05:32
Advertisements