123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /**
- * \file Polygon.cpp
- * \brief a polygon class
- * \author Gapchich Vladislav, Sven Sickert
- * \date 23/10/2011 (07/10/2015)
- */
- #include "vislearning/cbaselib/Polygon.h"
- using namespace OBJREC;
- using namespace std;
- using namespace NICE;
- //! A constructor
- Polygon::Polygon()
- {
- points_.clear();
- id_ = -1;
- unique_id_ = -1;
- }
- // A copy-constructor
- Polygon::Polygon(const Polygon ©)
- {
- points_ = PointsList(*(copy.points()));
- id_ = copy.id();
- unique_id_ = copy.unique_id_;
- }
- //! A desctructor
- Polygon::~Polygon()
- {
-
- }
- //! appends aPoint coordinate to the end of the point list
- void
- Polygon::push(const CoordT< int > &aPoint)
- {
- if (aPoint.x < 0 || aPoint.y < 0) {
- return;
- /* NOTREACHED */
- }
-
- points_.push_back(aPoint);
- }
- //! overloaded
- /*!
- * \see push(const CoordT< int > &aPoint)
- */
- void
- Polygon::push(const int &x, const int &y)
- {
- if (x < 0 || y < 0) {
- return;
- /* NOTREACHED */
- }
- CoordT< int > point;
- point.x = x;
- point.y = y;
- points_.push_back(point);
- }
- //! Sets a category ID(label ID) for the polygon
- /*!
- * /param[in] anID should not be less than zero
- */
- void
- Polygon::setID(const int &anID)
- {
- if (anID < 0) {
- return;
- /* NOTREACHED */
- }
- this->id_ = anID;
- }
- //! returns a constant pointer to the list of polygon points(coordinates)
- const PointsList *
- Polygon::points() const
- {
- return &points_;
- }
- //! deletes last added point of the polygon and returns it
- CoordT< int >
- Polygon::pop()
- {
- CoordT< int > ret = points_.back();
- points_.pop_back();
- return ret;
- }
- //! returns a category ID of the polygon
- int
- Polygon::id() const
- {
- return id_;
- }
-
- // check whether point is inside polygon or not
- bool
- Polygon::handleEdge ( const int px, const int py,
- const int x1, const int y1,
- const int x2, const int y2,
- int & lastdir, int & c )
- {
- if (py == y1)
- {
- if (px == x1) return true;
- if (y1 > y2)
- {
- if (lastdir == -1) // decreasing (cont.)
- if (x1 < px) c++;
- }
- if (y1 < y2)
- {
- if (lastdir == 1) // increasing (cont.)
- if (x1 < px) c++;
- }
- if (y1 == y2)
- {
- if ((x1 <= px) && (x2 >= px)) return true;
- }
- }
- if ( (y1 > py && y2 < py) || (y1 < py && y2 > py) )
- {
- int xz = (int)( (py - y1) * (x2 - x1) / (y2 - y1) + x1 );
- /* is point laying on the polygon curve? */
- if (xz == px) return true;
- /* does the scanning line cut the polygon curve left of the point? */
- if (xz < px) c++;
- }
- if (y2 > y1) lastdir = 1;
- if (y2 < y1) lastdir = -1;
- return false;
- }
- bool
- Polygon::insidePolygon ( const int &px, const int &py )
- {
- int i, j, c = 0;
- int lastdir = 0;
- if ( points_.size() < 2 )
- {
- cerr << "Polygon::insidePolygon: Not a valid Polygon curve" << endl;
- return false;
- }
- for ( PointsList::const_iterator i = points_.begin();
- i != points_.end(); ++i )
- {
- PointsList::const_iterator j = i;
- j++;
- if ( j == points_.end() ) j = points_.begin();
- CoordT<int> pi = *i;
- CoordT<int> pj = *j;
- if (pj.y > pi.y) lastdir = 1;
- if (pj.y < pi.y) lastdir = -1;
- }
- if (lastdir == 0)
- {
- cerr << "Polygon::insidePolygon: Polygon is degenerated" << endl;
- return false;
- }
- for ( PointsList::const_iterator i = points_.begin();
- i != points_.end(); ++i )
- {
- PointsList::const_iterator j = i;
- j++;
- if ( j == points_.end() ) j = points_.begin();
- CoordT<int> pi = *i;
- CoordT<int> pj = *j;
- if ( handleEdge( px, py, pi.x, pi.y, pj.x, pj.y, lastdir, c ) )
- return false;
- }
- if (c & 1) return true;
- return false;
- }
- bool
- Polygon::insidePolygon ( const CoordT< int > &aPoint )
- {
- if (aPoint.x < 0 || aPoint.y < 0) {
- cerr << "Polygon::insidePolygon(): point does not have valid coordinates"
- << endl;
- return false;
- }
- return insidePolygon ( aPoint.x, aPoint.y );
- }
|