rony.stackoverflow
rony.stackoverflow

Reputation: 31

Vector of double to save distance of every sides in a polygon

everyone I want to do a function in a class Polygon who will be save the size of every sides of the polygon in a vector of double. My polygon is build thanks to the class Point. So I success to know how many point I have in my polygon and to print the drawing of the polygon to the screen. But the function to get the sides of every sides of the polygon thanks to the point, I still have not succeeded

This is my class Point :

 Point::Point(double x, double y)
 {
  _x = x;
  _y = y;
 }
 Point::Point(const Point& other) 
 {
  _x = other._x;
  _y = other._y;
 }
 double Point::getX() const
 {
  return _x;
 }
double Point::getY() const
{
  return _y;
}
double Point::distance(const Point& other)
{
 return sqrt((getX() - other._x) * (getX() - other._x) + (getY() - other._y) *(getY() - other._y));
}

This is my header of class Polygon :

 class Polygon
 {
  public:
   Polygon();
   ~Polygon();
   int numOfPoints() const;
   vector<Point> getPoints() const;
   vector<double> getSides() const;
  protected:
   std::vector<Point> _points;
  };

and the cpp of Polygon :

 Polygon::Polygon(){}
 Polygon::~Polygon(){}
 int Polygon::numOfPoints() const
 {
  return _points.size();
 }
 vector<Point> Polygon::getPoints() const
 {
  return _points;
 }
 vector<double> Polygon::getSides() const
 {
  vector<double> sides;
 }

So I dont know how can I get the size of every sides thanks to class Point. I think it can be do thanks to the function distance of point, but I don't know how. If you can help me. Thanks You !

Upvotes: 2

Views: 134

Answers (2)

Aconcagua
Aconcagua

Reputation: 25516

First the small point: The following avoids double calculation of the differences (though compiler might optimise, it's better not to rely on it for doing so...).

double Point::distance(const Point& other)
{
    double dx = _x - other._x;
    double dy = _y - other._y;
    return sqrt(dx * dx + dy * dy);
}

Then you have to iterate over all the points; you need at least two to have any distances at all, but two is the degenerate case (one distance only, all other numbers n result in n distances...):

vector<double> Polygon::getSides() const
{
    vector<double> sides;
    if(points.size() > 2)
    {
        sides.reserve(points.size());
        std::vector<Point>::iterator end = points.end() - 1;
        for(std::vector<Point>::iterator i = points.begin(); i != end; ++i)
            sides.push_back(i->distance(*(i + 1)));
    }
    if(points.size() >= 2)
        sides.push_back(points.front().distance(points.back()));
    return sides;
}

Explanation:

if(points.size() > 2)

Only if we have more than two points, so triangle at least, we have true polyone. We now calculate the distances of this one, e. g. for a square ABCD the distances AB, BC, CD. Note that the distance DA is yet missing...

    sides.reserve(points.size());

A polygon with n points has n sides. This prevents reallocation.

    std::vector<Point>::iterator end = points.end() - 1;

end() points one past the end. Want to calculate distances i, i+1, so last element must be skipped.

    for(std::vector<Point>::iterator i = points.begin(); i != end; ++i)
        sides.push_back(i->distance(*(i + 1)));

Now calculating the distances...

if(points.size() >= 2)
    sides.push_back(points.front().distance(points.back()));

This catches two cases: For true polygones this adds the last side closing it (in the example above: DA). Additionally, it handles the degenerate case of a single line (i = 2).

Actually, this could have been placed as well in front of the for loop. My variant calculates for points ABCD AB BC CD DA, the alternative DA, AB, BC, CD.

You might have noticed that we reserve only in the case of a true polygone. In the degenerate case, we are only inserting a single element, so it does not matter if we allocate the inner array before via reserve or at inserting the element...

Oh, and if you want to save a line of code:

for(std::vector<Point>::iterator i = points.begin() + 1; i != points.end(); ++i)
    sides.push_back(i->distance(*(i - 1)));

Effectively the same, just reverted the points (calculating BA instead of AB).

Upvotes: 1

js441
js441

Reputation: 1163

You should iterate over the points in the polygon, calculating the distance to the previous point.

Something like the following should work (untested):

vector<double> Polygon::getSides() const {
    vector<double> sides;
    for(auto it = this->_points.begin(); it != this->_points.end(); it++) {
        if(it == this->_points.begin())
            sides.push_back(it->distance(*(this->_points.end() - 1)));
        else
            sides.push_back(it->distance(*(it - 1)));
    }
    return sides;
}

This starts at the first point and calculates the distance to the last point. For each point after that it calculates the distance to the previous point. Each time adding the distance to the output vector.

Note that I have assumed that the polygon is closed, i.e. the first point is connected to the last point. If the polygon contains no points, the return vector will be empty. If it contains only one point, it will contain a single element [0]. This results from calculating the distance from a point to the same point.

See this tutorial for more info on iterating over vectors: http://www.cprogramming.com/tutorial/stl/iterators.html

Upvotes: 0

Related Questions