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 class pinside { 00046 00047 protected: 00048 00049 /// Internal point definition 00050 struct point { 00051 double x; 00052 double y; 00053 }; 00054 00055 /// Internal line definition 00056 struct line { 00057 point p1; 00058 point p2; 00059 }; 00060 00061 /// Test if line segments \c P and \c Q intersect 00062 int intersect(line P, line Q); 00063 00064 /// Test if point \c t is inside polygon \c p of size \c N 00065 int inside(point t, point p[], int N); 00066 00067 public: 00068 00069 /** 00070 \brief Determine if two line segments intersect 00071 00072 The function returns 1 if the line segment 00073 determined by the endpoints \f$ (x_1,y_1) \f$ 00074 and \f$ (x_2,y_2) \f$ and the line segment 00075 determined by the endpoints \f$ (x_3,y_3) \f$ 00076 and \f$ (x_4,y_4) \f$ intersect, and 0 otherwise. 00077 */ 00078 int intersect(double x1, double y1, double x2, double y2, 00079 double x3, double y3, double x4, double y4) { 00080 line P={{x1,y1},{x2,y2}}; 00081 line Q={{x3,y3},{x4,y4}}; 00082 return intersect(P,Q); 00083 } 00084 00085 /** 00086 \brief Determine if point (x,y) is inside a polygon 00087 00088 This returns 1 if the point (x,y) is inside the polygon 00089 defined by \c xa and \c ya, and 0 otherwise. 00090 00091 Note that if the point (x,y) is exactly on the polygon, 00092 then the result of this function is not well-defined 00093 and it will return either 0 or 1. 00094 */ 00095 int inside(double x, double y, const o2scl::ovector_view &xa, 00096 const o2scl::ovector_view &ya); 00097 00098 /// Perform some simple testing 00099 int test(test_mgr &t) { 00100 line tx1={{0,0},{2,2}}; 00101 line ty1={{0,1},{1,0}}; 00102 t.test_gen(intersect(tx1,ty1)==1,"i1"); 00103 line tx2={{0,0},{0.49,0.49}}; 00104 line ty2={{0,1},{1,0}}; 00105 t.test_gen(intersect(tx2,ty2)==0,"i2"); 00106 line tx3={{0,0},{-1,-1}}; 00107 line ty3={{0,1},{1,0}}; 00108 t.test_gen(intersect(tx3,ty3)==0,"i3"); 00109 00110 ovector x, y; 00111 x.push_back(1); y.push_back(0); 00112 x.push_back(2); y.push_back(0); 00113 x.push_back(2); y.push_back(1); 00114 x.push_back(3); y.push_back(1); 00115 x.push_back(3); y.push_back(2); 00116 x.push_back(2); y.push_back(2); 00117 x.push_back(2); y.push_back(3); 00118 x.push_back(1); y.push_back(3); 00119 x.push_back(1); y.push_back(2); 00120 x.push_back(0); y.push_back(2); 00121 x.push_back(0); y.push_back(1); 00122 x.push_back(1); y.push_back(1); 00123 00124 t.test_gen(inside(1.5,1.5,x,y)==1,"in1"); 00125 t.test_gen(inside(2.01,1.99,x,y)==1,"in2"); 00126 t.test_gen(inside(1.99,2.01,x,y)==1,"in3"); 00127 t.test_gen(inside(1.99,1.99,x,y)==1,"in4"); 00128 00129 t.test_gen(inside(2.01,2.01,x,y)==0,"out1"); 00130 t.test_gen(inside(0.5,0.5,x,y)==0,"out2"); 00131 t.test_gen(inside(2.5,2.5,x,y)==0,"out3"); 00132 00133 t.test_gen(inside(0.5,1.5,x,y)==1,"c1"); 00134 t.test_gen(inside(0.5,2.5,x,y)==0,"c2"); 00135 t.test_gen(inside(1.5,0.5,x,y)==1,"c3"); 00136 t.test_gen(inside(1.5,2.5,x,y)==1,"c4"); 00137 t.test_gen(inside(2.5,0.5,x,y)==0,"c5"); 00138 t.test_gen(inside(2.5,1.5,x,y)==1,"c6"); 00139 00140 return 0; 00141 } 00142 00143 }; 00144 00145 #ifndef DOXYGENP 00146 } 00147 #endif 00148 00149 #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