00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifdef HAVE_CONFIG_H
00036 #include <config.h>
00037 #endif
00038
00039 #include <cfloat>
00040
00041 #include "quit.h"
00042
00043 #include "defun-dld.h"
00044 #include "error.h"
00045 #include "oct-obj.h"
00046
00047 static Matrix this_contour;
00048 static Matrix contourc;
00049 static int elem;
00050
00051
00052 #define CONTOUR_QUANT 50
00053
00054
00055
00056 static void
00057 add_point (double x, double y)
00058 {
00059 if (elem % CONTOUR_QUANT == 0)
00060 this_contour = this_contour.append (Matrix (2, CONTOUR_QUANT, 0));
00061
00062 this_contour (0, elem) = x;
00063 this_contour (1, elem) = y;
00064 elem++;
00065 }
00066
00067
00068
00069
00070 static void
00071 end_contour (void)
00072 {
00073 if (elem > 2)
00074 {
00075 this_contour (1, 0) = elem - 1;
00076 contourc = contourc.append (this_contour.extract_n (0, 0, 2, elem));
00077 }
00078
00079 this_contour = Matrix ();
00080 elem = 0;
00081 }
00082
00083
00084
00085 static void
00086 start_contour (double lvl, double x, double y)
00087 {
00088 end_contour ();
00089 this_contour.resize (2, 0);
00090 add_point (lvl, 0);
00091 add_point (x, y);
00092 }
00093
00094 static void
00095 drawcn (const RowVector& X, const RowVector& Y, const Matrix& Z,
00096 double lvl, int r, int c, double ct_x, double ct_y,
00097 unsigned int start_edge, bool first, charMatrix& mark)
00098 {
00099 double px[4], py[4], pz[4], tmp;
00100 unsigned int stop_edge, next_edge, pt[2];
00101 int next_r, next_c;
00102
00103
00104 px[0] = px[3] = X(c);
00105 px[1] = px[2] = X(c+1);
00106
00107 py[0] = py[1] = Y(r);
00108 py[2] = py[3] = Y(r+1);
00109
00110 pz[3] = Z(r+1, c) - lvl;
00111 pz[2] = Z(r+1, c + 1) - lvl;
00112 pz[1] = Z(r, c+1) - lvl;
00113 pz[0] = Z(r, c) - lvl;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 char id = static_cast<char> (mark(r, c));
00125
00126
00127 if (start_edge == 255)
00128 {
00129
00130 for (unsigned int k = 0; k < 4; k++)
00131 if (static_cast<char> (1 << k) & id)
00132 start_edge = k;
00133 }
00134
00135 if (start_edge == 255)
00136 return;
00137
00138
00139 mark(r, c) -= static_cast<char> (1 << start_edge);
00140
00141
00142 pt[0] = start_edge;
00143 pt[1] = (pt[0] + 1) % 4;
00144
00145
00146 if (first)
00147 {
00148 tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]);
00149
00150 if (xisnan (tmp))
00151 ct_x = ct_y = 0.5;
00152 else
00153 {
00154 ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp);
00155 ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp);
00156 }
00157
00158 start_contour (lvl, ct_x, ct_y);
00159 }
00160
00161
00162
00163 for (unsigned int k = 1; k <= 4; k++)
00164 {
00165 if (start_edge == 0 || start_edge == 2)
00166 stop_edge = (start_edge + k) % 4;
00167 else
00168 stop_edge = (start_edge - k) % 4;
00169
00170 if (static_cast<char> (1 << stop_edge) & id)
00171 break;
00172 }
00173
00174 pt[0] = stop_edge;
00175 pt[1] = (pt[0] + 1) % 4;
00176 tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]);
00177
00178 if (xisnan (tmp))
00179 ct_x = ct_y = 0.5;
00180 else
00181 {
00182 ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp);
00183 ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp);
00184 }
00185
00186
00187 add_point (ct_x, ct_y);
00188
00189
00190 mark(r, c) -= static_cast<char> (1 << stop_edge);
00191
00192
00193 next_c = c;
00194 next_r = r;
00195
00196 if (stop_edge == 0)
00197 next_r--;
00198 else if (stop_edge == 1)
00199 next_c++;
00200 else if (stop_edge == 2)
00201 next_r++;
00202 else if (stop_edge == 3)
00203 next_c--;
00204
00205
00206
00207 if (next_r >= 0 && next_c >= 0 && next_r < mark.rows ()
00208 && next_c < mark.cols () && mark(next_r, next_c) > 0)
00209 {
00210 next_edge = (stop_edge + 2) % 4;
00211 drawcn (X, Y, Z, lvl, next_r, next_c, ct_x, ct_y, next_edge, false, mark);
00212 }
00213 }
00214
00215 static void
00216 mark_facets (const Matrix& Z, charMatrix& mark, double lvl)
00217 {
00218 unsigned int nr = mark.rows ();
00219 unsigned int nc = mark.cols ();
00220
00221 double f[4];
00222
00223 for (unsigned int c = 0; c < nc; c++)
00224 for (unsigned int r = 0; r < nr; r++)
00225 {
00226 f[0] = Z(r, c) - lvl;
00227 f[1] = Z(r, c+1) - lvl;
00228 f[3] = Z(r+1, c) - lvl;
00229 f[2] = Z(r+1, c+1) - lvl;
00230
00231 for (unsigned int i = 0; i < 4; i++)
00232 if (fabs(f[i]) < DBL_EPSILON)
00233 f[i] = DBL_EPSILON;
00234
00235 if (f[1] * f[2] < 0)
00236 mark(r, c) += 2;
00237
00238 if (f[0] * f[3] < 0)
00239 mark(r, c) += 8;
00240 }
00241
00242 for (unsigned int r = 0; r < nr; r++)
00243 for (unsigned int c = 0; c < nc; c++)
00244 {
00245 f[0] = Z(r, c) - lvl;
00246 f[1] = Z(r, c+1) - lvl;
00247 f[3] = Z(r+1, c) - lvl;
00248 f[2] = Z(r+1, c+1) - lvl;
00249
00250 for (unsigned int i = 0; i < 4; i++)
00251 if (fabs(f[i]) < DBL_EPSILON)
00252 f[i] = DBL_EPSILON;
00253
00254 if (f[0] * f[1] < 0)
00255 mark(r, c) += 1;
00256
00257 if (f[2] * f[3] < 0)
00258 mark(r, c) += 4;
00259 }
00260 }
00261
00262 static void
00263 cntr (const RowVector& X, const RowVector& Y, const Matrix& Z, double lvl)
00264 {
00265 unsigned int nr = Z.rows ();
00266 unsigned int nc = Z.cols ();
00267
00268 charMatrix mark (nr - 1, nc - 1, 0);
00269
00270 mark_facets (Z, mark, lvl);
00271
00272
00273
00274 for (unsigned int c = 0; c < nc - 1; c++)
00275 {
00276
00277 if (mark(0, c) & 1)
00278 drawcn (X, Y, Z, lvl, 0, c, 0.0, 0.0, 0, true, mark);
00279
00280
00281 if (mark(nr - 2, c) & 4)
00282 drawcn (X, Y, Z, lvl, nr - 2, c, 0.0, 0.0, 2, true, mark);
00283 }
00284
00285 for (unsigned int r = 0; r < nr - 1; r++)
00286 {
00287
00288 if (mark(r, 0) & 8)
00289 drawcn (X, Y, Z, lvl, r, 0, 0.0, 0.0, 3, true, mark);
00290
00291
00292 if (mark(r, nc - 2) & 2)
00293 drawcn (X, Y, Z, lvl, r, nc - 2, 0.0, 0.0, 1, true, mark);
00294 }
00295
00296 for (unsigned int r = 0; r < nr - 1; r++)
00297 for (unsigned int c = 0; c < nc - 1; c++)
00298 if (mark (r, c) > 0)
00299 drawcn (X, Y, Z, lvl, r, c, 0.0, 0.0, 255, true, mark);
00300 }
00301
00302 DEFUN_DLD (__contourc__, args, ,
00303 "-*- texinfo -*-\n\
00304 @deftypefn {Loadable Function} {} __contourc__ (@var{x}, @var{y}, @var{z}, @var{levels})\n\
00305 Undocumented internal function.\n\
00306 @end deftypefn")
00307 {
00308 octave_value retval;
00309
00310 if (args.length () == 4)
00311 {
00312 RowVector X = args (0).row_vector_value ();
00313 RowVector Y = args (1).row_vector_value ();
00314 Matrix Z = args (2).matrix_value ();
00315 RowVector L = args (3).row_vector_value ();
00316
00317 if (! error_state)
00318 {
00319 contourc.resize (2, 0);
00320
00321 for (int i = 0; i < L.length (); i++)
00322 cntr (X, Y, Z, L (i));
00323
00324 end_contour ();
00325
00326 retval = contourc;
00327 }
00328 else
00329 error ("__contourc__: invalid argument values");
00330 }
00331 else
00332 print_usage ();
00333
00334 return retval;
00335 }
00336
00337
00338
00339
00340
00341
00342