00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_PINSIDE_H 00024 #define O2SCL_PINSIDE_H 00025 00026 #include <o2scl/ovector_tlate.h> 00027 #include <o2scl/array.h> 00028 #include <o2scl/test_mgr.h> 00029 #include <o2scl/vec_arith.h> 00030 00031 #ifndef DOXYGENP 00032 namespace o2scl { 00033 #endif 00034 00035 /** 00036 \brief Test line intersection and point inside polygon 00037 00038 This is a fast and dirty implementation of the point inside 00039 polygon test from Jerome L. Lewis, SIGSCE Bulletin, 34 (2002) 00040 81. 00041 00042 Note that an error in that article ("count-" should have been 00043 "count--") has been corrected here. 00044 00045 \future The inside() functions actually copy the points twice. 00046 This can be made more efficient. 00047 */ 00048 class pinside { 00049 00050 protected: 00051 00052 /// Internal point definition for \ref pinside 00053 struct point { 00054 double x; 00055 double y; 00056 }; 00057 00058 /// Internal line definition for \ref pinside 00059 struct line { 00060 point p1; 00061 point p2; 00062 }; 00063 00064 /// Test if line segments \c P and \c Q intersect 00065 int intersect(line P, line Q); 00066 00067 /// Test if point \c t is inside polygon \c p of size \c N 00068 int inside(point t, point p[], int N); 00069 00070 public: 00071 00072 /** 00073 \brief Determine if two line segments intersect 00074 00075 The function returns 1 if the line segment 00076 determined by the endpoints \f$ (x_1,y_1) \f$ 00077 and \f$ (x_2,y_2) \f$ and the line segment 00078 determined by the endpoints \f$ (x_3,y_3) \f$ 00079 and \f$ (x_4,y_4) \f$ intersect, and 0 otherwise. 00080 */ 00081 int intersect(double x1, double y1, double x2, double y2, 00082 double x3, double y3, double x4, double y4) { 00083 line P={{x1,y1},{x2,y2}}; 00084 line Q={{x3,y3},{x4,y4}}; 00085 return intersect(P,Q); 00086 } 00087 00088 /** 00089 \brief Determine if point (x,y) is inside a polygon 00090 00091 This returns 1 if the point (x,y) is inside the polygon 00092 defined by \c xa and \c ya, and 0 otherwise. 00093 00094 Note that if the point (x,y) is exactly on the polygon, 00095 then the result of this function is not well-defined 00096 and it will return either 0 or 1. 00097 */ 00098 int inside(double x, double y, const o2scl::ovector_view &xa, 00099 const o2scl::ovector_view &ya); 00100 00101 /** 00102 \brief Determine if point (x,y) is inside a polygon 00103 00104 This returns 1 if the point (x,y) is inside the polygon 00105 defined by \c xa and \c ya, and 0 otherwise. 00106 00107 The parameter \c n should be the number of polygon points 00108 specified in vectors \c xa and \c ya. 00109 00110 Note that if the point (x,y) is exactly on the polygon, 00111 then the result of this function is not well-defined 00112 and it will return either 0 or 1. 00113 */ 00114 template<class vec_t> 00115 int inside(double x, double y, size_t n, const vec_t &xa, 00116 const vec_t &ya) { 00117 00118 size_t ix; 00119 point t, *p=new point[n+1]; 00120 t.x=x; 00121 t.y=y; 00122 00123 // We have to copy the vectors so we can rearrange them because 00124 // they are const 00125 o2scl::ovector xb(n), yb(n); 00126 vector_copy(n,xa,xb); 00127 vector_copy(n,ya,yb); 00128 00129 // Ensure that (yb[0],ya[0]) is the point with the smallest x 00130 // coordinate among all the points with the smallest y coordinate 00131 double xmin=xb[0]; 00132 double ymin=yb[0]; 00133 ix=0; 00134 for(size_t i=0;i<n;i++) { 00135 if (yb[i]<ymin) { 00136 ymin=yb[i]; 00137 ix=i; 00138 } 00139 } 00140 for(size_t i=0;i<n;i++) { 00141 if (yb[i]==ymin && xb[i]<xmin) { 00142 xmin=xb[i]; 00143 ix=i; 00144 } 00145 } 00146 vector_rotate<double,vec_t>(n,xb,ix); 00147 vector_rotate<double,vec_t>(n,yb,ix); 00148 00149 // Copy to p[] 00150 for(size_t i=0;i<n;i++) { 00151 p[i+1].x=xb[i]; 00152 p[i+1].y=yb[i]; 00153 } 00154 00155 int ret=inside(t,p,n); 00156 delete[] p; 00157 00158 return ret; 00159 } 00160 00161 /// Perform some simple testing 00162 int test(test_mgr &t); 00163 00164 }; 00165 00166 #ifndef DOXYGENP 00167 } 00168 #endif 00169 00170 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page