File: ispolycw.m

package info (click to toggle)
octave-geometry 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 720 kB
  • sloc: cpp: 5,358; python: 379; objc: 328; makefile: 25
file content (89 lines) | stat: -rw-r--r-- 2,894 bytes parent folder | download
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
## Copyright (C) 2016 - Juan Pablo Carbajal
## Copyright (C) 2017 - Piyush Jain
## Copyright (C) 2022 - Nir Krakauer 
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {} {@var{ccw} =} ispolycw (@var{p})
## @deftypefnx {} {@var{ccw} =} ispolycw (@var{px}, @var{py})
## Returns true if the polygon @var{p} are oriented clockwise.
##
## @var{p} is a N-by-2 array containing coordinates of vertices. The coordinates
## of the vertices of the polygon can also be given as two N-by-1 arrays
## @var{px}, @var{py}.
##
## If polygon is self-crossing, the result is undefined.
##
## If @var{px}, @var{py} contain multiple contours, either in NaN-separated vector form or in cell array form, ispolycw returns a logical array containing one true or false value per contour.
##
## If a contour contains two or fewer vertices, ispolycw returns true.
##
## If @var{p} (or @var{px}, @var{py}) is a cell, each element is considered a polygon, the
## resulting @var{cw} array has the same shape as the cell.
##
## @seealso{polygonArea}
## @end deftypefn

function cw = ispolycw (px, py)

  if iscell (px)
    if nargin == 2
      cw = cellfun (@ispolycw, px, py);
    else
      cw = cellfun (@ispolycw, px);
    endif
  else
    
    if nargin == 2;
      px = [px py];
    end
    
    px = reshape(px, numel(px)/2, 2);

    px = splitPolygons (px);
    for i=1:size(px)(1)
      pol = px{i};
      ## if contour contains two or fewer vertices
      if size(pol)(1) < 3
        cw(i,1) = true;
      else
        cw(i,1) = polygonArea (pol) < 0;
      endif
    endfor

  end
end

%!shared pccw, pcw, ph
%! pccw = pcw = [0 0; 1 0; 1 1; 0 1];
%! pcw([2 4],:) = pcw([4 2], :);
%! ph = [pccw; nan(1,2); 0.5*pcw+[0.25 0.25]];

%!assert (~ispolycw (pccw));
%!assert (ispolycw (pcw));
%!assert (ispolycw ({pccw;pcw}), [false;true]);
%!assert (ispolycw ({pccw,pcw}), [false,true]);
%!assert (ispolycw ({pccw(:, 1);pcw(:, 1)}, {pccw(:, 2);pcw(:, 2)}), [false;true]);
%!assert (ispolycw ({pccw(:, 1),pcw(:, 1)}, {pccw(:, 2),pcw(:, 2)}), [false,true]);
%!assert (ispolycw(ph),[false;true]);

%!test
%! phcw = [pcw; nan(1,2); 0.5*pccw+[0.25 0.25]];
%! assert (ispolycw(phcw),[true;false]);

%!test
%! x=[0 0 2 2 NaN 0 2 0]; y=[0 2 2 0 NaN 0 0 3];
%! assert(ispolycw(x,y),[true;false]);