The program takes in a set of coordinates that defines the polygon. It then takes in a set of points. The idea is to find out how many of these points lie strictly inside the convex polygon (not on the edge or outside). First the program checks if the first set of points form a convex polygon or not. If yes, the program proceeds. Then each point is checked to see if it is strictly inside the convex polygon. If yes, count
variable is increased. Here is the code:
#include <iostream>
#include <vector>
// Calculate perpendicular dot product
int perdot(const std::pair<int, int> a, const std::pair<int, int> b, const std::pair<int, int> c)
{
int ab_x = b.first - a.first;
int ab_y = b.second - a.second;
int ac_x = c.first - a.first;
int ac_y = c.second - a.second;
int per_dot = ab_x * ac_y - ab_y * ac_x;
if(per_dot < 0)
{
return -1;
}
else if(per_dot > 0)
{
return 1;
}
else
{
return 0;
}
}
// Check if given set of points form a convex polygon
bool is_convex(const std::vector<std::pair<int, int>>& convex_polygon)
{
int n = convex_polygon.size();
int sense = perdot(convex_polygon[n - 1], convex_polygon[0], convex_polygon[1]);
for(int i = 0; i < n - 1; i++)
{
int new_sense;
if(i == (n - 2))
{
new_sense = perdot(convex_polygon[i], convex_polygon[i + 1], convex_polygon[0]);
}
else
{
new_sense = perdot(convex_polygon[i], convex_polygon[i + 1], convex_polygon[i + 2]);
}
if(sense == 0)
{
sense = new_sense;
}
if(new_sense == (-sense) && sense != 0)
{
return false;
}
}
return true;
}
// Check if a point is STRICTLY inside the convex polygon
bool is_inside(const std::vector<std::pair<int, int>>& convex_polygon, const std::pair<int, int> point)
{
int n = convex_polygon.size();
int sense = perdot(convex_polygon[n - 1], point, convex_polygon[0]);
if(sense == 0)
{
return false;
}
for(int i = 0; i < n - 1; i++)
{
int new_sense;
new_sense = perdot(convex_polygon[i], point, convex_polygon[i + 1]);
if(new_sense == (-sense) || new_sense == 0)
{
return false;
}
}
return true;
}
// Count the number of points STRICTLY inside the convex polygon
int p_inside(const std::vector<std::pair<int, int>>& convex_polygon, const std::vector<std::pair<int, int>>& points)
{
int count = 0;
for(auto point : points)
{
bool inside = is_inside(convex_polygon, point);
if(inside)
{
count++;
}
}
return count;
}
// Main
int main()
{
int k, n;
std::cin >> k >> n;
std::vector<std::pair<int, int>> convex_polygon(k);
std::vector<std::pair<int, int>> points(n);
for(size_t i = 0; i < convex_polygon.size(); i++)
{
int x, y;
std::cin >> x >> y;
convex_polygon[i] = {x, y};
}
bool convex = is_convex(convex_polygon);
if(!convex)
{
std::cout << "Input not convex...Exiting" << std::endl;
return 0;
}
for(size_t i = 0; i < points.size(); i++)
{
int x, y;
std::cin >> x >> y;
points[i] = {x, y};
}
int count = p_inside(convex_polygon, points);
std::cout << "Points inside: " << count << std::endl;
return 0;
}
1) Should std::pair
be passed as reference? Is there an exact criteria to see if a given object is large enough to be passed as reference?
2) Is the use of const
correct?
3) What other improvements can be made?
4) I am planning to test it extensively using Catch2
framework. I am learning this framework myself. What suggestions do you have to maintain professional test quality?