pinside.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 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 SourceForge.net Logo, O2scl Sourceforge Project Page