changelog shortlog tags changeset files revisions annotate raw

src/DLD-FUNCTIONS/tsearch.cc

changeset 10289: 4b124317dc38
parent:2c279308f6ab
author: John W. Eaton <jwe@octave.org>
date: Tue Feb 09 20:58:55 2010 -0500 (51 minutes ago)
permissions: -rw-r--r--
description: base_properties::set_children: account for hidden children
1/*
2
3Copyright (C) 2002, 2007, 2009 Andreas Stahel
4
5This file is part of Octave.
6
7Octave is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12Octave is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <iostream>
30#include <fstream>
31#include <string>
32
33#include "lo-ieee.h"
34#include "lo-math.h"
35
36#include "defun-dld.h"
37#include "error.h"
38#include "oct-obj.h"
39#include "parse.h"
40
41inline double max(double a, double b, double c)
42{
43 if (a < b)
44 return ( b < c ? c : b );
45 else
46 return ( a < c ? c : a );
47}
48
49inline double min(double a, double b, double c)
50{
51 if (a > b)
52 return ( b > c ? c : b );
53 else
54 return ( a > c ? c : a );
55}
56
57#define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
58
59// for large data set the algorithm is very slow
60// one should presort (how?) either the elements of the points of evaluation
61// to cut down the time needed to decide which triangle contains the
62// given point
63
64// e.g., build up a neighbouring triangle structure and use a simplex-like
65// method to traverse it
66
67DEFUN_DLD (tsearch, args, ,
68 "-*- texinfo -*-\n\
69@deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})\n\
70Searches for the enclosing Delaunay convex hull. For @code{@var{t} =\n\
71delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the\n\
72points @code{(@var{xi}, @var{yi})}. For points outside the convex hull,\n\
73@var{idx} is NaN.\n\
74@seealso{delaunay, delaunayn}\n\
75@end deftypefn")
76{
77 const double eps=1.0e-12;
78
79 octave_value_list retval;
80 const int nargin = args.length ();
81 if ( nargin != 5 ) {
82 print_usage ();
83 return retval;
84 }
85
86 const ColumnVector x(args(0).vector_value());
87 const ColumnVector y(args(1).vector_value());
88 const Matrix elem(args(2).matrix_value());
89 const ColumnVector xi(args(3).vector_value());
90 const ColumnVector yi(args(4).vector_value());
91
92 if (error_state) return retval;
93
94 const octave_idx_type nelem = elem.rows();
95
96 ColumnVector minx(nelem);
97 ColumnVector maxx(nelem);
98 ColumnVector miny(nelem);
99 ColumnVector maxy(nelem);
100 for(octave_idx_type k = 0; k < nelem; k++)
101 {
102 minx(k) = min(REF(x,k,0), REF(x,k,1), REF(x,k,2)) - eps;
103 maxx(k) = max(REF(x,k,0), REF(x,k,1), REF(x,k,2)) + eps;
104 miny(k) = min(REF(y,k,0), REF(y,k,1), REF(y,k,2)) - eps;
105 maxy(k) = max(REF(y,k,0), REF(y,k,1), REF(y,k,2)) + eps;
106 }
107
108 const octave_idx_type np = xi.length();
109 ColumnVector values(np);
110
111 double x0 = 0.0, y0 = 0.0;
112 double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
113
114 octave_idx_type k = nelem; // k is a counter of elements
115 for(octave_idx_type kp = 0; kp < np; kp++)
116 {
117 const double xt = xi(kp);
118 const double yt = yi(kp);
119
120 // check if last triangle contains the next point
121 if (k < nelem)
122 {
123 const double dx1 = xt - x0;
124 const double dx2 = yt - y0;
125 const double c1 = (a22 * dx1 - a21 * dx2) / det;
126 const double c2 = (-a12 * dx1 + a11 * dx2) / det;
127 if ( c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
128 {
129 values(kp) = double(k+1);
130 continue;
131 }
132 }
133
134 // it doesn't, so go through all elements
135 for (k = 0; k < nelem; k++)
136 {
137 OCTAVE_QUIT;
138 if (xt >= minx(k) && xt <= maxx(k) &&
139 yt >= miny(k) && yt <= maxy(k) )
140 {
141 // element inside the minimum rectangle: examine it closely
142 x0 = REF(x,k,0);
143 y0 = REF(y,k,0);
144 a11 = REF(x,k,1)-x0;
145 a12 = REF(y,k,1)-y0;
146 a21 = REF(x,k,2)-x0;
147 a22 = REF(y,k,2)-y0;
148 det = a11 * a22 - a21 * a12;
149
150 // solve the system
151 const double dx1 = xt - x0;
152 const double dx2 = yt - y0;
153 const double c1 = (a22 * dx1 - a21 * dx2) / det;
154 const double c2 = (-a12 * dx1 + a11 * dx2) / det;
155 if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
156 {
157 values(kp) = double(k+1);
158 break;
159 }
160 } //endif # examine this element closely
161 } //endfor # each element
162
163 if (k == nelem)
164 values(kp) = lo_ieee_nan_value ();
165
166 } //endfor # kp
167
168 retval(0) = values;
169
170 return retval;
171}
172
173/*
174%!shared x, y, tri
175%! x = [-1;-1;1];
176%! y = [-1;1;-1];
177%! tri = [1, 2, 3];
178%!error (tsearch())
179%!assert (tsearch (x,y,tri,-1,-1), 1)
180%!assert (tsearch (x,y,tri, 1,-1), 1)
181%!assert (tsearch (x,y,tri,-1, 1), 1)
182%!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
183%!assert (tsearch (x,y,tri, 1, 1), NaN)
184
185*/