summaryrefslogtreecommitdiff
path: root/inst/inpolyeder.m
diff options
context:
space:
mode:
Diffstat (limited to 'inst/inpolyeder.m')
-rw-r--r--inst/inpolyeder.m136
1 files changed, 136 insertions, 0 deletions
diff --git a/inst/inpolyeder.m b/inst/inpolyeder.m
new file mode 100644
index 0000000..3a49fa5
--- /dev/null
+++ b/inst/inpolyeder.m
@@ -0,0 +1,136 @@
+## Copyright (C) 2014 Andreas Emch and Eduardo Hahn Paredes
+##
+## This file is part of Octave.
+##
+## Octave 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.
+##
+## Octave 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 Octave; see the file COPYING. If not, see
+## <http://www.gnu.org/licenses/>.
+
+% -*- texinfo -*-
+% @deftypefn {Function File} {[@var{in}, @var{on}] =} inpolyeder (@var{x}, @var{y}, @var{z}, @var{xv}, @var{yv}, @var{zv}, @var{doPlot}, @var{doPlotHelpers})
+% For a polyeder defined by vertex points @code{(@var{xv}, @var{yv}, @var{zv})},
+% determine if the points @code{(@var{x}, @var{y}), @var{z})} are inside or
+% outside the polyeder.
+% The variables @var{x}, @var{y}, @var{z} must have the same dimension. The optional
+% output @var{on} gives the points that are on the polyeder.
+% @seealso{inpolygon}
+% @end deftypefn
+
+% Author: Andreas Emch, Eduardo Hahn Paredes
+% Created: December 2012
+
+function [in, on] = inpolyeder (x, y, z, xv, yv, zv, doPlot, doPlotHelpers)
+
+ if (nargin < 6)
+ print_usage ();
+ endif
+
+ if (!(isreal(x) && isreal(y) && isreal(z)
+ && ismatrix(y) && ismatrix(y) && ismatrix(z)
+ && size_equal(x, y, z)))
+ error("inpolyeder: The first 3 vectors need to have the same size (test points)");
+ elseif (! (isreal(xv) && isreal(yv) && isreal(zv)
+ && isvector(xv) && isvector(yv) && isvector(zv)
+ && size_equal(xv, yv, zv)))
+ error("inpolyeder: The last 3 vectors need to have the same size (polyeder corners)");
+ endif
+
+ if (!isbool(doPlot))
+ error("inpolyeder: doPlot has to be a boolean value");
+ endif
+
+ if (!isbool(doPlotHelpers))
+ error("inpolyeder: doPlotHelpers has to be a boolean value");
+ endif
+
+ starttTime = cputime;
+
+ X = [xv, yv, zv];
+ K = convhulln(X);
+
+ P = [x y z];
+
+ on = zeros(size(x), "logical")';
+ in = zeros(size(x), "logical")';
+
+ if (doPlot == true)
+ clf
+ hold on
+ t = trisurf(K, X(:,1), X(:,2), X(:,3));
+ set(t,'facealpha',0.5)
+ m=unique(K);
+ plot3(X(m,1), X(m,2), X(m,3), 'ko', 'markerfacecolor', 'b');
+ endif
+
+ counter = 0;
+
+ for p1 = P'
+ counter++;
+
+ left = 0;
+ right = 0;
+
+ do
+ p2 = p1 + rand(3,1);
+ until (p1 != p2)
+
+ if (doPlotHelpers)
+ point1 = p1 + (-20 .* (p2-p1));
+ point2 = p1 + (20 .* (p2-p1));
+
+ plot3([point1(1,1); point2(1,1)], [point1(2,1); point2(2,1)], [point1(3,1); point2(3,1)], 'k-');
+ endif
+
+ for poly = K'
+ a = X(poly(1,1),:)';
+ b = X(poly(2,1),:)';
+ c = X(poly(3,1),:)';
+ [pointIn pointDistance point] = isIntersectionInPolygon3D(p1, p2, a, b, c);
+ if (pointIn)
+ if (pointDistance > 0)
+ left += 1;
+ elseif (pointDistance < 0)
+ right += 1;
+ elseif (pointDistance == 0)
+ on(1,counter) = true;
+ endif
+ endif
+ if (doPlotHelpers && !isnan(point))
+ if (pointIn)
+ plot3(point(1,1), point(2,1), point(3,1), 'ko', 'markerfacecolor', 'y');
+ else
+ plot3(point(1,1), point(2,1), point(3,1), 'k*', 'markerfacecolor', 'y');
+ endif
+ endif
+ endfor
+ if (mod(left,2) == 1 && mod(right,2) == 1)
+ in(1,counter) = true;
+ endif
+ endfor
+
+ if (doPlot == true)
+ plot3(x(in'), y(in'), z(in'),'ko', 'markerfacecolor', 'g',
+ x(~in'), y(~in'), z(~in'),'ko', 'markerfacecolor', 'r',
+ x(on'), y(on'), z(on'),'ko', 'markerfacecolor', 'k')
+
+ x_max = max(max(X(:,1)), max(P(:,1))) + 0.5;
+ x_min = min(min(X(:,1)), min(P(:,1))) - 0.5;
+ y_max = max(max(X(:,2)), max(P(:,2))) + 0.5;
+ y_min = min(min(X(:,2)), min(P(:,2))) - 0.5;
+ z_max = max(max(X(:,3)), max(P(:,3))) + 0.5;
+ z_min = min(min(X(:,3)), min(P(:,3))) - 0.5;
+ axis ([x_min x_max y_min y_max z_min z_max]);
+ hold off
+ endif
+ printf('Total cpu time for checking %d points in a polyeder of %d polygons: %f seconds\n', size(x)(1,1), size(K)(1,1), cputime-starttTime);
+endfunction