GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
tsearch.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2002-2017 Andreas Stahel
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 // Author: Andreas Stahel <Andreas.Stahel@hta-bi.bfh.ch>
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include "lo-ieee.h"
30 #include "lo-math.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "ovl.h"
35 
36 inline double max (double a, double b, double c)
37 {
38  if (a < b)
39  return (b < c ? c : b);
40  else
41  return (a < c ? c : a);
42 }
43 
44 inline double min (double a, double b, double c)
45 {
46  if (a > b)
47  return (b > c ? c : b);
48  else
49  return (a > c ? c : a);
50 }
51 
52 #define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
53 
54 // for large data set the algorithm is very slow
55 // one should presort (how?) either the elements of the points of evaluation
56 // to cut down the time needed to decide which triangle contains the
57 // given point
58 
59 // e.g., build up a neighbouring triangle structure and use a simplex-like
60 // method to traverse it
61 
62 DEFUN (tsearch, args, ,
63  doc: /* -*- texinfo -*-
64 @deftypefn {} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})
65 Search for the enclosing Delaunay convex hull.
66 
67 For @code{@var{t} = delaunay (@var{x}, @var{y})}, finds the index in @var{t}
68 containing the points @code{(@var{xi}, @var{yi})}. For points outside the
69 convex hull, @var{idx} is NaN.
70 @seealso{delaunay, delaunayn}
71 @end deftypefn */)
72 {
73  if (args.length () != 5)
74  print_usage ();
75 
76  const double eps = 1.0e-12;
77 
78  const ColumnVector x (args(0).vector_value ());
79  const ColumnVector y (args(1).vector_value ());
80  const Matrix elem (args(2).matrix_value ());
81  const ColumnVector xi (args(3).vector_value ());
82  const ColumnVector yi (args(4).vector_value ());
83 
84  const octave_idx_type nelem = elem.rows ();
85 
86  ColumnVector minx (nelem);
87  ColumnVector maxx (nelem);
88  ColumnVector miny (nelem);
89  ColumnVector maxy (nelem);
90  for (octave_idx_type k = 0; k < nelem; k++)
91  {
92  minx(k) = min (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) - eps;
93  maxx(k) = max (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) + eps;
94  miny(k) = min (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) - eps;
95  maxy(k) = max (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) + eps;
96  }
97 
98  const octave_idx_type np = xi.numel ();
99  ColumnVector values (np);
100 
101  double x0, y0, a11, a12, a21, a22, det;
102  x0 = y0 = 0.0;
103  a11 = a12 = a21 = a22 = 0.0;
104  det = 0.0;
105 
106  octave_idx_type k = nelem; // k is a counter of elements
107  for (octave_idx_type kp = 0; kp < np; kp++)
108  {
109  const double xt = xi(kp);
110  const double yt = yi(kp);
111 
112  // check if last triangle contains the next point
113  if (k < nelem)
114  {
115  const double dx1 = xt - x0;
116  const double dx2 = yt - y0;
117  const double c1 = (a22 * dx1 - a21 * dx2) / det;
118  const double c2 = (-a12 * dx1 + a11 * dx2) / det;
119  if (c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
120  {
121  values(kp) = double(k+1);
122  continue;
123  }
124  }
125 
126  // it doesn't, so go through all elements
127  for (k = 0; k < nelem; k++)
128  {
129  OCTAVE_QUIT;
130  if (xt >= minx(k) && xt <= maxx(k) && yt >= miny(k) && yt <= maxy(k))
131  {
132  // element inside the minimum rectangle: examine it closely
133  x0 = REF (x, k, 0);
134  y0 = REF (y, k, 0);
135  a11 = REF (x, k, 1) - x0;
136  a12 = REF (y, k, 1) - y0;
137  a21 = REF (x, k, 2) - x0;
138  a22 = REF (y, k, 2) - y0;
139  det = a11 * a22 - a21 * a12;
140 
141  // solve the system
142  const double dx1 = xt - x0;
143  const double dx2 = yt - y0;
144  const double c1 = (a22 * dx1 - a21 * dx2) / det;
145  const double c2 = (-a12 * dx1 + a11 * dx2) / det;
146  if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
147  {
148  values(kp) = double(k+1);
149  break;
150  }
151  } //endif # examine this element closely
152  } //endfor # each element
153 
154  if (k == nelem)
155  values(kp) = lo_ieee_nan_value ();
156 
157  } //endfor # kp
158 
159  return ovl (values);
160 }
161 
162 /*
163 %!shared x, y, tri
164 %! x = [-1;-1;1];
165 %! y = [-1;1;-1];
166 %! tri = [1, 2, 3];
167 %!assert (tsearch (x,y,tri,-1,-1), 1)
168 %!assert (tsearch (x,y,tri, 1,-1), 1)
169 %!assert (tsearch (x,y,tri,-1, 1), 1)
170 %!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
171 %!assert (tsearch (x,y,tri, 1, 1), NaN)
172 
173 %!error tsearch ()
174 */
#define REF(x, k, i)
Definition: tsearch.cc:52
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
for large enough k
Definition: lu.cc:606
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:126
double max(double a, double b, double c)
Definition: tsearch.cc:36
octave_idx_type rows(void) const
Definition: Array.h:401
cell array If invoked with two or more scalar integer or a vector of integer values
Definition: ov-cell.cc:1205
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
JNIEnv void * args
Definition: ov-java.cc:67
double min(double a, double b, double c)
Definition: tsearch.cc:44
static int elem
Definition: __contourc__.cc:50
Definition: dMatrix.h:37
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
#define eps(C)
issues an error eealso double
Definition: ov-bool-mat.cc:594
the element is set to zero In other the statement xample y
Definition: data.cc:5342
b
Definition: cellfun.cc:398
#define OCTAVE_QUIT
Definition: quit.h:212
static const double xi[33]
Definition: quadcc.cc:55
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x