octave /tags/R2007-07-26/octave-forge/main/geometry/inst/inpolygon.m

Language MATLAB Lines 112
MD5 Hash b7c41a8f8218dc68d7b10a01d09dcb53
Repository https://octave.svn.sourceforge.net/svnroot/octave View Raw File
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
## Copyright (C) 2006 Frederick (Rick) A Niles, S?ren Hauberg
##
## This file is intended for use with Octave.
##
## This file can be redistriubted under the terms of the GNU General
## Public License.

## -*- texinfo -*-
## @deftypefn {Function File} {[@var{IN}, @var{ON}] = } inpolygon (@var{X}, @var{Y}, @var{xv}, @var{xy})
##
## For a polygon defined by (@var{xv},@var{yv}) points, determine if the
## points (X,Y) are inside or outside the polygon.  @var{X}, @var{Y},
## @var{IN} must all have the same dimensions. The optional output @var{ON}
## will give point on the polygon. 
##
## @end deftypefn

## Author: Frederick (Rick) A Niles <niles@rickniles.com>
## Created: 14 November 2006

## Vectorized by S?ren Hauberg <soren@hauberg.org>

## The method for determining if a point is in in a polygon is based on
## the algorithm shown on
## http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ and is
## credited to Randolph Franklin.

function [IN, ON] = inpolygon (X, Y, xv, yv)

  if ( !(isreal(X) && isreal(Y) && ismatrix(Y) && ismatrix(Y) && size_equal(X,Y)) )
    error( "inpolygon: first two arguments must be real matrices of same size");
  elseif ( !(isreal(xv) && isreal(yv) && isvector(xv) && isvector(yv) && size_equal(xv,yv)) )
    error( "inpolygon: last two arguments must be real vectors of same size");
  endif

  npol = length(xv);
  do_boundary = (nargout >= 2);
  
  IN = zeros (size(X), "logical");
  if (do_boundary), ON = zeros (size(X), "logical"); endif
  
  j = npol;
  for i = 1:npol
    delta_xv = xv(j) - xv(i);
    delta_yv = yv(j) - yv(i);
    ## distance = [distance from (X,Y) to edge] * length(edge)
    distance = delta_xv.*(Y-yv(i)) - (X-xv(i)).*delta_yv;
    ##
    ## is Y between the y-values of edge i,j
    ##        AND (X,Y) on the left of the edge ?
    idx1 = ( (yv(i)<=Y & Y<yv(j)) | (yv(j)<=Y & Y<yv(i)) ) & ...
           0< distance.*delta_yv;
    IN(idx1) = !IN(idx1);

    ## Check if (X,Y) are actually ON the boundary of the polygon.
    if (do_boundary)
       idx2 = ( (yv(i)<=Y & Y<=yv(j)) | (yv(j)<=Y & Y<=yv(i)) ) & ...
              ( (xv(i)<=X & X<=xv(j)) | (xv(j)<=X & X<=xv(i)) ) & ...
              ( 0 == distance | !delta_xv );
       ON(idx2) = true;
    endif
    j = i;
  endfor
endfunction

%!demo
%!  xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
%!       1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
%!       0.05840 ];
%!  yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
%!       0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
%!       0.60628 ];
%! xa=[0:0.1:2.3];
%! ya=[0:0.1:1.4];
%! [x,y]=meshgrid(xa,ya);
%! [IN,ON]=inpolygon(x,y,xv,yv);
%! 
%! inside=IN & !ON;
%! plot(xv,yv)
%! hold on
%! plot(x(inside),y(inside),"@g")
%! plot(x(~IN),y(~IN),"@m")
%! plot(x(ON),y(ON),"@b")
%! hold off
%! disp("Green points are inside polygon, magenta are outside,");
%! disp("and blue are on boundary.");

%!demo
%!  xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
%!       1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
%!       0.05840, 0.73295, 1.28913, 1.74221, 1.16023, \
%!       0.73295, 0.05840 ];
%!  yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
%!       0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
%!       0.60628, 0.82096, 0.67155, 0.96114, 1.14833, \
%!       0.82096, 0.60628];
%! xa=[0:0.1:2.3];
%! ya=[0:0.1:1.4];
%! [x,y]=meshgrid(xa,ya);
%! [IN,ON]=inpolygon(x,y,xv,yv);
%! 
%! inside=IN & ~ ON;
%! plot(xv,yv)
%! hold on
%! plot(x(inside),y(inside),"@g")
%! plot(x(~IN),y(~IN),"@m")
%! plot(x(ON),y(ON),"@b")
%! hold off
%! disp("Green points are inside polygon, magenta are outside,");
%! disp("and blue are on boundary.");
Back to Top