tsearch.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2002-2012 Andreas Stahel
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 // Author: Andreas Stahel <Andreas.Stahel@hta-bi.bfh.ch>
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <iostream>
00030 #include <fstream>
00031 #include <string>
00032 
00033 #include "lo-ieee.h"
00034 #include "lo-math.h"
00035 
00036 #include "defun-dld.h"
00037 #include "error.h"
00038 #include "oct-obj.h"
00039 #include "parse.h"
00040 
00041 inline double max (double a, double b, double c)
00042 {
00043   if (a < b)
00044     return (b < c ? c : b);
00045   else
00046     return (a < c ? c : a);
00047 }
00048 
00049 inline double min (double a, double b, double c)
00050 {
00051   if (a > b)
00052     return (b > c ? c : b);
00053   else
00054     return (a > c ? c : a);
00055 }
00056 
00057 #define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
00058 
00059 // for large data set the algorithm is very slow
00060 // one should presort (how?) either the elements of the points of evaluation
00061 // to cut down the time needed to decide which triangle contains the
00062 // given point
00063 
00064 // e.g., build up a neighbouring triangle structure and use a simplex-like
00065 // method to traverse it
00066 
00067 DEFUN_DLD (tsearch, args, ,
00068         "-*- texinfo -*-\n\
00069 @deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})\n\
00070 Search for the enclosing Delaunay convex hull.  For @code{@var{t} =\n\
00071 delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the\n\
00072 points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,\n\
00073 @var{idx} is NaN.\n\
00074 @seealso{delaunay, delaunayn}\n\
00075 @end deftypefn")
00076 {
00077   const double eps=1.0e-12;
00078 
00079   octave_value_list retval;
00080   const int nargin = args.length ();
00081   if (nargin != 5)
00082     {
00083       print_usage ();
00084       return retval;
00085     }
00086 
00087   const ColumnVector x (args(0).vector_value ());
00088   const ColumnVector y (args(1).vector_value ());
00089   const Matrix elem (args(2).matrix_value ());
00090   const ColumnVector xi (args(3).vector_value ());
00091   const ColumnVector yi (args(4).vector_value ());
00092 
00093   if (error_state)
00094     return retval;
00095 
00096   const octave_idx_type nelem = elem.rows ();
00097 
00098   ColumnVector minx (nelem);
00099   ColumnVector maxx (nelem);
00100   ColumnVector miny (nelem);
00101   ColumnVector maxy (nelem);
00102   for (octave_idx_type k = 0; k < nelem; k++)
00103     {
00104       minx(k) = min (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) - eps;
00105       maxx(k) = max (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) + eps;
00106       miny(k) = min (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) - eps;
00107       maxy(k) = max (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) + eps;
00108     }
00109 
00110   const octave_idx_type np = xi.length ();
00111   ColumnVector values (np);
00112 
00113   double x0 = 0.0, y0 = 0.0;
00114   double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
00115 
00116   octave_idx_type k = nelem; // k is a counter of elements
00117   for (octave_idx_type kp = 0; kp < np; kp++)
00118     {
00119       const double xt = xi(kp);
00120       const double yt = yi(kp);
00121 
00122       // check if last triangle contains the next point
00123       if (k < nelem)
00124         {
00125           const double dx1 = xt - x0;
00126           const double dx2 = yt - y0;
00127           const double c1 = (a22 * dx1 - a21 * dx2) / det;
00128           const double c2 = (-a12 * dx1 + a11 * dx2) / det;
00129           if (c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
00130             {
00131               values(kp) = double(k+1);
00132               continue;
00133             }
00134         }
00135 
00136       // it doesn't, so go through all elements
00137       for (k = 0; k < nelem; k++)
00138         {
00139           OCTAVE_QUIT;
00140           if (xt >= minx(k) && xt <= maxx(k) && yt >= miny(k) && yt <= maxy(k))
00141             {
00142               // element inside the minimum rectangle: examine it closely
00143               x0  = REF (x, k, 0);
00144               y0  = REF (y, k, 0);
00145               a11 = REF (x, k, 1) - x0;
00146               a12 = REF (y, k, 1) - y0;
00147               a21 = REF (x, k, 2) - x0;
00148               a22 = REF (y, k, 2) - y0;
00149               det = a11 * a22 - a21 * a12;
00150 
00151               // solve the system
00152               const double dx1 = xt - x0;
00153               const double dx2 = yt - y0;
00154               const double c1 = (a22 * dx1 - a21 * dx2) / det;
00155               const double c2 = (-a12 * dx1 + a11 * dx2) / det;
00156               if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
00157                 {
00158                   values(kp) = double(k+1);
00159                   break;
00160                 }
00161             } //endif # examine this element closely
00162         } //endfor # each element
00163 
00164       if (k == nelem)
00165         values(kp) = lo_ieee_nan_value ();
00166 
00167     } //endfor # kp
00168 
00169   retval(0) = values;
00170 
00171   return retval;
00172 }
00173 
00174 /*
00175 %!shared x, y, tri
00176 %! x = [-1;-1;1];
00177 %! y = [-1;1;-1];
00178 %! tri = [1, 2, 3];
00179 %!error (tsearch())
00180 %!assert (tsearch (x,y,tri,-1,-1), 1)
00181 %!assert (tsearch (x,y,tri, 1,-1), 1)
00182 %!assert (tsearch (x,y,tri,-1, 1), 1)
00183 %!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
00184 %!assert (tsearch (x,y,tri, 1, 1), NaN)
00185 
00186 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines