polygon.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //
00028 // *****************************************************************************
00029 
00030 #include <swri_geometry_util/polygon.h>
00031 
00032 namespace swri_geometry_util
00033 {
00034   //Constructor - create and undefined polygon
00035   Polygon::Polygon(){
00036     this->_nvert = 0;
00037     this->_shape.x = NULL;
00038     this->_shape.y = NULL;
00039   }
00040 
00041   //Constructor - create a duplicate polygon
00042   Polygon::Polygon(const Polygon & other)
00043   {
00044     this->_shape.x = new double[other._nvert];
00045     this->_shape.y = new double[other._nvert];
00046     this->_nvert = other._nvert;
00047 
00048     for(int i=0; i<other._nvert; i++){
00049       this->_shape.x[i] = other._shape.x[i];
00050       this->_shape.y[i] = other._shape.y[i];
00051     }
00052   }
00053 
00054   //Operate overload for assign a polygon
00055   Polygon & Polygon::operator =(const Polygon & other)
00056   {
00057     if(this != &other) // protect against invalid self-assignment
00058     {
00059       if (this->_nvert > 0)
00060       {
00061         delete[] this->_shape.x;
00062         this->_shape.x = NULL;
00063         delete[] this->_shape.y;
00064         this->_shape.y = NULL;
00065       }
00066       this->_shape.x = new double[other._nvert];
00067       this->_shape.y = new double[other._nvert];
00068       this->_nvert = other._nvert;
00069 
00070       for(int i=0; i<other._nvert; i++){
00071         this->_shape.x[i] = other._shape.x[i];
00072         this->_shape.y[i] = other._shape.y[i];
00073       }
00074     }
00075     return *this;
00076   }
00077 
00078   //Constructor - create a polygon using a list of vertices
00079   //Assumptions - vertices are in CW order
00080   Polygon::Polygon(double Xs[], double Ys[], int numVertx){
00081 
00082     this->_shape.x = new double[numVertx];
00083     this->_shape.y = new double[numVertx];
00084     this->_nvert = numVertx;
00085 
00086     for(int i=0;i<numVertx;i++)
00087     {
00088       this->_shape.x[i] = Xs[i];
00089       this->_shape.y[i] = Ys[i];
00090     }
00091   }
00092 
00093   //Determine if a given vertex lies within this polygon
00094   //Returns:  True if "vertex" is within this polygon, False otherwise
00095   bool Polygon::VertexInPolygon(Vertex vertex)
00096   {
00097     int i, j, c = 0;
00098     for (i = 0, j = _nvert-1; i < _nvert; j = i++)
00099     {
00100         if (((_shape.y[i]>vertex.y) != (_shape.y[j]>vertex.y)) && (vertex.x <
00101             (_shape.x[j]-_shape.x[i]) * (vertex.y-_shape.y[i]) /
00102             (_shape.y[j]-_shape.y[i]) + _shape.x[i]))
00103             c = !c;
00104     }
00105     return c;
00106   }
00107 
00108   //Determine if a given line segment intersects with or lies within this polygon
00109   //Returns:  True if line segment defined by "start" and "end" intersects or
00110   //          lies within this polygon, False otherwise
00111   bool Polygon::LineOverlapsPolygon(Vertex start, Vertex end)
00112   {
00113     Vertex pStart,pEnd, intersect;
00114 
00115     //check if either end point is within the polygon
00116     if (VertexInPolygon(start) || VertexInPolygon(end))
00117     {
00118       return true;
00119     }
00120 
00121     //check for line intersection with the polygon
00122     for(int i=0;i < _nvert;i++)
00123     {
00124       pStart.x = _shape.x[i];
00125       pStart.y = _shape.y[i];
00126       pEnd.x = _shape.x[(i+1)%_nvert];
00127       pEnd.y = _shape.y[(i+1)%_nvert];
00128 
00129       intersect = FindLineIntersectLine(pStart,pEnd,start,end);
00130       if(intersect.x != -999.0 && intersect.y != -999.0)//intersection found
00131       {
00132         return true;
00133       }
00134     }
00135 
00136     return false;
00137   }
00138 
00139   //Private Function
00140   //Determines if two line segments intersect
00141   //Returns:  True if line segments intersect, False otherwise
00142   Vertex Polygon::FindLineIntersectLine(Vertex start1, Vertex end1,
00143       Vertex start2, Vertex end2)
00144   {
00145     Vertex result;
00146     result.x = -999.0;
00147     result.y = -999.0;
00148 
00149     double denom = ((end1.x - start1.x) * (end2.y - start2.y)) -
00150         ((end1.y - start1.y) * (end2.x - start2.x));
00151 
00152     //no intersection (lines are parallel)
00153     if (denom == 0)
00154             return result;
00155 
00156     double numer = ((start1.y - start2.y) * (end2.x - start2.x)) -
00157         ((start1.x - start2.x) * (end2.y - start2.y));
00158 
00159     double r = numer / denom;
00160 
00161     double numer2 = ((start1.y - start2.y) * (end1.x - start1.x)) -
00162         ((start1.x - start2.x) * (end1.y - start1.y));
00163 
00164     double s = numer2 / denom;
00165 
00166     //no intersection
00167     if ((r < 0 || r > 1) || (s < 0 || s > 1))
00168             return result;
00169 
00170     // Find intersection point
00171     result.x = start1.x + (r * (end1.x - start1.x));
00172     result.y = start1.y + (r * (end1.y - start1.y));
00173 
00174     return result;
00175   }
00176 
00177   //returns all x vertices for this polygon
00178   double* Polygon::GetXVerticies()
00179   {
00180     return this->_shape.x;
00181   }
00182 
00183   //returns all y vertices for this polygon
00184   double* Polygon::GetYVerticies()
00185   {
00186     return this->_shape.y;
00187   }
00188 
00189   //returns a specific x vertex
00190   double Polygon::GetXVerticie(int num)
00191   {
00192     return this->_shape.x[num];
00193   }
00194 
00195   //returns a specific y vertex
00196   double Polygon::GetYVerticie(int num)
00197   {
00198     return this->_shape.y[num];
00199   }
00200 
00201   int Polygon::GetNumVerticies()
00202   {
00203     return this->_nvert;
00204   }
00205 
00206   //Destructor
00207   Polygon::~Polygon() {
00208     if(_shape.x){
00209       delete[] _shape.x;
00210       _shape.x = NULL;
00211     }
00212     if(_shape.y){
00213       delete[] _shape.y;
00214       _shape.y = NULL;
00215     }
00216   }
00217 }  // end namespace swri_geometry_util


swri_geometry_util
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 20:34:40