GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
tsearch.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2002-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <cmath>
31
32#include "lo-ieee.h"
33
34#include "defun.h"
35#include "error.h"
36#include "ovl.h"
37
38OCTAVE_NAMESPACE_BEGIN
39
40inline double max (double a, double b, double c)
41{
42 if (a < b)
43 return (b < c ? c : b);
44 else
45 return (a < c ? c : a);
46}
47
48inline double min (double a, double b, double c)
49{
50 if (a > b)
51 return (b > c ? c : b);
52 else
53 return (a > c ? c : a);
54}
55
56#define REF(x,k,i) x(static_cast<octave_idx_type> (elem((k), (i))) - 1)
57
58// for large data set the algorithm is very slow
59// one should presort (how?) either the elements of the points of evaluation
60// to cut down the time needed to decide which triangle contains the
61// given point
62
63// e.g., build up a neighbouring triangle structure and use a simplex-like
64// method to traverse it
65
66DEFUN (tsearch, args, ,
67 doc: /* -*- texinfo -*-
68@deftypefn {} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})
69Search for the enclosing Delaunay convex hull.
70
71For @code{@var{t} = delaunay (@var{x}, @var{y})}, finds the index in @var{t}
72containing the points @code{(@var{xi}, @var{yi})}. For points outside the
73convex hull, @var{idx} is NaN.
74@seealso{delaunay, delaunayn}
75@end deftypefn */)
76{
77 if (args.length () != 5)
78 print_usage ();
79
80 const double eps = 1.0e-12;
81
82 const ColumnVector x (args(0).vector_value ());
83 const ColumnVector y (args(1).vector_value ());
84 const Matrix elem (args(2).matrix_value ());
85 const ColumnVector xi (args(3).vector_value ());
86 const ColumnVector yi (args(4).vector_value ());
87
88 const octave_idx_type nelem = elem.rows ();
89
90 ColumnVector minx (nelem);
91 ColumnVector maxx (nelem);
92 ColumnVector miny (nelem);
93 ColumnVector maxy (nelem);
94 for (octave_idx_type k = 0; k < nelem; k++)
95 {
96 minx(k) = min (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) - eps;
97 maxx(k) = max (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) + eps;
98 miny(k) = min (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) - eps;
99 maxy(k) = max (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) + eps;
100 }
101
102 const octave_idx_type np = xi.numel ();
103 ColumnVector values (np);
104
105 double x0, y0, a11, a12, a21, a22, det;
106 x0 = y0 = 0.0;
107 a11 = a12 = a21 = a22 = 0.0;
108 det = 0.0;
109
110 octave_idx_type k = nelem; // k is a counter of elements
111 for (octave_idx_type kp = 0; kp < np; kp++)
112 {
113 const double xt = xi(kp);
114 const double yt = yi(kp);
115
116 // check if last triangle contains the next point
117 if (k < nelem)
118 {
119 const double dx1 = xt - x0;
120 const double dx2 = yt - y0;
121 const double c1 = (a22 * dx1 - a21 * dx2) / det;
122 const double c2 = (-a12 * dx1 + a11 * dx2) / det;
123 if (c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
124 {
125 values(kp) = double(k+1);
126 continue;
127 }
128 }
129
130 // it doesn't, so go through all elements
131 for (k = 0; k < nelem; k++)
132 {
133 octave_quit ();
134
135 if (xt >= minx(k) && xt <= maxx(k) && yt >= miny(k) && yt <= maxy(k))
136 {
137 // element inside the minimum rectangle: examine it closely
138 x0 = REF (x, k, 0);
139 y0 = REF (y, k, 0);
140 a11 = REF (x, k, 1) - x0;
141 a12 = REF (y, k, 1) - y0;
142 a21 = REF (x, k, 2) - x0;
143 a22 = REF (y, k, 2) - y0;
144 det = a11 * a22 - a21 * a12;
145
146 // solve the system
147 const double dx1 = xt - x0;
148 const double dx2 = yt - y0;
149 const double c1 = (a22 * dx1 - a21 * dx2) / det;
150 const double c2 = (-a12 * dx1 + a11 * dx2) / det;
151 if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
152 {
153 values(kp) = double(k+1);
154 break;
155 }
156 } //endif # examine this element closely
157 } //endfor # each element
158
159 if (k == nelem)
160 values(kp) = lo_ieee_nan_value ();
161
162 } //endfor # kp
163
164 return ovl (values);
165}
166
167/*
168%!shared x, y, tri
169%! x = [-1;-1;1];
170%! y = [-1;1;-1];
171%! tri = [1, 2, 3];
172%!assert (tsearch (x,y,tri,-1,-1), 1)
173%!assert (tsearch (x,y,tri, 1,-1), 1)
174%!assert (tsearch (x,y,tri,-1, 1), 1)
175%!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
176%!assert (tsearch (x,y,tri, 1, 1), NaN)
177
178%!error tsearch ()
179*/
180
181OCTAVE_NAMESPACE_END
static int elem
Definition: __contourc__.cc:54
Definition: dMatrix.h:42
T eps(const T &x)
Definition: data.cc:4842
OCTINTERP_API void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:84
F77_RET_T const F77_DBLE * x
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
static const double xi[33]
Definition: quadcc.cc:68
double min(double a, double b, double c)
Definition: tsearch.cc:48
OCTAVE_NAMESPACE_BEGIN double max(double a, double b, double c)
Definition: tsearch.cc:40
#define REF(x, k, i)
Definition: tsearch.cc:56