PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
Objective C | 111 lines | 98 code | 13 blank | 0 comment | 18 complexity | b7c41a8f8218dc68d7b10a01d09dcb53 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. ## Copyright (C) 2006 Frederick (Rick) A Niles, S?ren Hauberg
  2. ##
  3. ## This file is intended for use with Octave.
  4. ##
  5. ## This file can be redistriubted under the terms of the GNU General
  6. ## Public License.
  7. ## -*- texinfo -*-
  8. ## @deftypefn {Function File} {[@var{IN}, @var{ON}] = } inpolygon (@var{X}, @var{Y}, @var{xv}, @var{xy})
  9. ##
  10. ## For a polygon defined by (@var{xv},@var{yv}) points, determine if the
  11. ## points (X,Y) are inside or outside the polygon. @var{X}, @var{Y},
  12. ## @var{IN} must all have the same dimensions. The optional output @var{ON}
  13. ## will give point on the polygon.
  14. ##
  15. ## @end deftypefn
  16. ## Author: Frederick (Rick) A Niles <niles@rickniles.com>
  17. ## Created: 14 November 2006
  18. ## Vectorized by S?ren Hauberg <soren@hauberg.org>
  19. ## The method for determining if a point is in in a polygon is based on
  20. ## the algorithm shown on
  21. ## http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ and is
  22. ## credited to Randolph Franklin.
  23. function [IN, ON] = inpolygon (X, Y, xv, yv)
  24. if ( !(isreal(X) && isreal(Y) && ismatrix(Y) && ismatrix(Y) && size_equal(X,Y)) )
  25. error( "inpolygon: first two arguments must be real matrices of same size");
  26. elseif ( !(isreal(xv) && isreal(yv) && isvector(xv) && isvector(yv) && size_equal(xv,yv)) )
  27. error( "inpolygon: last two arguments must be real vectors of same size");
  28. endif
  29. npol = length(xv);
  30. do_boundary = (nargout >= 2);
  31. IN = zeros (size(X), "logical");
  32. if (do_boundary), ON = zeros (size(X), "logical"); endif
  33. j = npol;
  34. for i = 1:npol
  35. delta_xv = xv(j) - xv(i);
  36. delta_yv = yv(j) - yv(i);
  37. ## distance = [distance from (X,Y) to edge] * length(edge)
  38. distance = delta_xv.*(Y-yv(i)) - (X-xv(i)).*delta_yv;
  39. ##
  40. ## is Y between the y-values of edge i,j
  41. ## AND (X,Y) on the left of the edge ?
  42. idx1 = ( (yv(i)<=Y & Y<yv(j)) | (yv(j)<=Y & Y<yv(i)) ) & ...
  43. 0< distance.*delta_yv;
  44. IN(idx1) = !IN(idx1);
  45. ## Check if (X,Y) are actually ON the boundary of the polygon.
  46. if (do_boundary)
  47. idx2 = ( (yv(i)<=Y & Y<=yv(j)) | (yv(j)<=Y & Y<=yv(i)) ) & ...
  48. ( (xv(i)<=X & X<=xv(j)) | (xv(j)<=X & X<=xv(i)) ) & ...
  49. ( 0 == distance | !delta_xv );
  50. ON(idx2) = true;
  51. endif
  52. j = i;
  53. endfor
  54. endfunction
  55. %!demo
  56. %! xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
  57. %! 1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
  58. %! 0.05840 ];
  59. %! yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
  60. %! 0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
  61. %! 0.60628 ];
  62. %! xa=[0:0.1:2.3];
  63. %! ya=[0:0.1:1.4];
  64. %! [x,y]=meshgrid(xa,ya);
  65. %! [IN,ON]=inpolygon(x,y,xv,yv);
  66. %!
  67. %! inside=IN & !ON;
  68. %! plot(xv,yv)
  69. %! hold on
  70. %! plot(x(inside),y(inside),"@g")
  71. %! plot(x(~IN),y(~IN),"@m")
  72. %! plot(x(ON),y(ON),"@b")
  73. %! hold off
  74. %! disp("Green points are inside polygon, magenta are outside,");
  75. %! disp("and blue are on boundary.");
  76. %!demo
  77. %! xv=[ 0.05840, 0.48375, 0.69356, 1.47478, 1.32158, \
  78. %! 1.94545, 2.16477, 1.87639, 1.18218, 0.27615, \
  79. %! 0.05840, 0.73295, 1.28913, 1.74221, 1.16023, \
  80. %! 0.73295, 0.05840 ];
  81. %! yv=[ 0.60628, 0.04728, 0.50000, 0.50000, 0.02015, \
  82. %! 0.18161, 0.78850, 1.13589, 1.33781, 1.04650, \
  83. %! 0.60628, 0.82096, 0.67155, 0.96114, 1.14833, \
  84. %! 0.82096, 0.60628];
  85. %! xa=[0:0.1:2.3];
  86. %! ya=[0:0.1:1.4];
  87. %! [x,y]=meshgrid(xa,ya);
  88. %! [IN,ON]=inpolygon(x,y,xv,yv);
  89. %!
  90. %! inside=IN & ~ ON;
  91. %! plot(xv,yv)
  92. %! hold on
  93. %! plot(x(inside),y(inside),"@g")
  94. %! plot(x(~IN),y(~IN),"@m")
  95. %! plot(x(ON),y(ON),"@b")
  96. %! hold off
  97. %! disp("Green points are inside polygon, magenta are outside,");
  98. %! disp("and blue are on boundary.");