Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / fmap / algorithm / triangulation / visad / DelaunayClarkson.java @ 39203

History | View | Annotate | Download (42.8 KB)

1
//
2
// DelaunayClarkson.java
3
//
4

    
5
/*
6
VisAD system for interactive analysis and visualization of numerical
7
data.  Copyright (C) 1996 - 2002 Bill Hibbard, Curtis Rueden, Tom
8
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
9
Tommy Jasmin.
10

11
This library is free software; you can redistribute it and/or
12
modify it under the terms of the GNU Library General Public
13
License as published by the Free Software Foundation; either
14
version 2 of the License, or (at your option) any later version.
15

16
This library is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
Library General Public License for more details.
20

21
You should have received a copy of the GNU Library General Public
22
License along with this library; if not, write to the Free
23
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24
MA 02111-1307, USA
25
*/
26

    
27
package org.gvsig.fmap.algorithm.triangulation.visad;
28

    
29

    
30
/* The Delaunay triangulation algorithm in this class
31
 * is originally from hull by Ken Clarkson:
32
 *
33
 * Ken Clarkson wrote this.  Copyright (c) 1995 by AT&T..
34
 * Permission to use, copy, modify, and distribute this software for any
35
 * purpose without fee is hereby granted, provided that this entire notice
36
 * is included in all copies of any software which is or includes a copy
37
 * or modification of this software and in all copies of the supporting
38
 * documentation for such software.
39
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
40
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
41
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
42
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
43
 */
44

    
45
/**
46
   DelaunayClarkson represents an O(N*logN) method
47
   with high overhead to find the Delaunay triangulation
48
   of a set of samples of R^DomainDimension.<P>
49
*/
50
public class DelaunayClarkson extends Delaunay {
51

    
52
/* ******* BEGINNING OF CONVERTED HULL CODE ******* */
53

    
54
  // <<<< Constants >>>>
55
  private static final double DBL_MANT_DIG = 53;
56
  private static final double FLT_RADIX = 2;
57
  private static final double DBL_EPSILON = 2.2204460492503131E-16;
58
  private static final double ln2 = Math.log(2);
59

    
60

    
61
  // <<<< Variables >>>>
62
  /* we need to have two indices for every pointer into basis_s and
63
     simplex arrays, because they are two-dimensional arrays of
64
     blocks.  ( _bn = block number ) */
65

    
66
  // for the pseudo-pointers
67
  private static final int INFINITY = -2;      // replaces infinity
68
  private static final int NOVAL = -1;         // replaces null
69

    
70
  private double[][] site_blocks;        // copy of samples array
71
  private int[][]   a3s;                // output array
72
  private int       a3size;             // output array maximum size
73
  private int       nts = 0;            // # output objects
74

    
75
  private static final int max_blocks = 10000; // max # basis/simplex blocks
76
  private static final int Nobj = 10000;
77
  private static final int MAXDIM = 8;         // max dimension
78

    
79
  private int    dim;
80
  private int    p;
81
  private long   pnum;
82
  private int    rdim,          // region dimension
83
                 cdim;          // # sites currently specifying region
84
  private int    exact_bits;
85
  private double b_err_min,
86
                 b_err_min_sq;
87
  private double ldetbound = 0;
88
  private int    failcount = 0;          // static: reduce_inner
89
  private int    lscale;                 // static: reduce_inner
90
  private double max_scale;              // static: reduce_inner
91
  private float  Sb;                     // static: reduce_inner
92
  private int    nsb = 0;                // # simplex blocks
93
  private int    nbb = 0;                // # basis_s blocks
94
  private int    ss = MAXDIM;            // static: search
95
  private int    ss2 = 2000;             // static: visit_triang
96
  private long   vnum = -1;              // static: visit_triang
97
  private int    p_neigh_vert = NOVAL;   // static: main
98

    
99
  // "void stuff" -- dummy variables to hold unused return information
100
  private int[] voidp = new int[1];
101
  private int[] voidp_bn = new int[1];
102

    
103
  // basis_s stuff
104
  private int[][]      bbt_next = new int[max_blocks][];
105
  private int[][]      bbt_next_bn = new int[max_blocks][];
106
  private int[][]      bbt_ref_count = new int[max_blocks][];
107
  private int[][]      bbt_lscale = new int[max_blocks][];
108
  private double[][]   bbt_sqa = new double[max_blocks][];
109
  private double[][]   bbt_sqb = new double[max_blocks][];
110
  private double[][][] bbt_vecs = new double[max_blocks][][];
111

    
112
  private int ttbp;
113
  private int ttbp_bn;
114
  private int ib;
115
  private int ib_bn;
116
  private int basis_s_list = NOVAL;
117
  private int basis_s_list_bn;
118
  private int pnb = NOVAL;
119
  private int pnb_bn;
120
  private int b = NOVAL;              // static: sees
121
  private int b_bn;
122

    
123
  // simplex stuff
124
  private int[][]   sbt_next = new int[max_blocks][];
125
  private int[][]   sbt_next_bn = new int[max_blocks][];
126
  private long[][]  sbt_visit = new long[max_blocks][];
127
  private short[][] sbt_mark = new short[max_blocks][];
128
  private int[][]   sbt_normal = new int[max_blocks][];
129
  private int[][]   sbt_normal_bn = new int[max_blocks][];
130
  private int[][]   sbt_peak_vert = new int[max_blocks][];
131
  private int[][]   sbt_peak_simp = new int[max_blocks][];
132
  private int[][]   sbt_peak_simp_bn = new int[max_blocks][];
133
  private int[][]   sbt_peak_basis = new int[max_blocks][];
134
  private int[][]   sbt_peak_basis_bn = new int[max_blocks][];
135
  private int[][][] sbt_neigh_vert = new int[max_blocks][][];
136
  private int[][][] sbt_neigh_simp = new int[max_blocks][][];
137
  private int[][][] sbt_neigh_simp_bn = new int[max_blocks][][];
138
  private int[][][] sbt_neigh_basis = new int[max_blocks][][];
139
  private int[][][] sbt_neigh_basis_bn = new int[max_blocks][][];
140

    
141
  private int   simplex_list = NOVAL;
142
  private int   simplex_list_bn;
143
  private int   ch_root;
144
  private int   ch_root_bn;
145
  private int   ns;                            // static: make_facets
146
  private int   ns_bn;
147
  private int[] st = new int[ss+MAXDIM+1];    // static: search
148
  private int[] st_bn = new int[ss+MAXDIM+1];
149
  private int[] st2 = new int[ss2+MAXDIM+1];    // static: visit_triang
150
  private int[] st2_bn = new int[ss2+MAXDIM+1];
151

    
152

    
153
  // <<<< Functions >>>>
154
  private int new_block_basis_s() {
155
    bbt_next[nbb] = new int[Nobj];
156
    bbt_next_bn[nbb] = new int[Nobj];
157
    bbt_ref_count[nbb] = new int[Nobj];
158
    bbt_lscale[nbb] = new int[Nobj];
159
    bbt_sqa[nbb] = new double[Nobj];
160
    bbt_sqb[nbb] = new double[Nobj];
161
    bbt_vecs[nbb] = new double[2*rdim][];
162
    for (int i=0; i<2*rdim; i++) bbt_vecs[nbb][i] = new double[Nobj];
163
    for (int i=0; i<Nobj; i++) {
164
      bbt_next[nbb][i] = i+1;
165
      bbt_next_bn[nbb][i] = nbb;
166
      bbt_ref_count[nbb][i] = 0;
167
      bbt_lscale[nbb][i] = 0;
168
      bbt_sqa[nbb][i] = 0;
169
      bbt_sqb[nbb][i] = 0;
170
      for (int j=0; j<2*rdim; j++) bbt_vecs[nbb][j][i] = 0;
171
    }
172
    bbt_next[nbb][Nobj-1] = NOVAL;
173
    basis_s_list = 0;
174
    basis_s_list_bn = nbb;
175
    nbb++;
176
    return basis_s_list;
177
  }
178

    
179
  private int reduce_inner(int v, int v_bn, int s, int s_bn, int k) {
180
    int q, q_bn;
181
    double dd,
182
           Sb = 0;
183
    double scale;
184

    
185
    bbt_sqa[v_bn][v] = 0;
186
    for (int i=0; i<rdim; i++) {
187
      bbt_sqa[v_bn][v] += bbt_vecs[v_bn][i][v] * bbt_vecs[v_bn][i][v];
188
    }
189
    bbt_sqb[v_bn][v] = bbt_sqa[v_bn][v];
190
    if (k <= 1) {
191
      for (int i=0; i<rdim; i++) {
192
        bbt_vecs[v_bn][i][v] = bbt_vecs[v_bn][rdim+i][v];
193
      }
194
      return 1;
195
    }
196
    for (int j=0; j<250; j++) {
197
      int    xx = rdim;
198
      double labound;
199

    
200
      for (int i=0; i<rdim; i++) {
201
        bbt_vecs[v_bn][i][v] = bbt_vecs[v_bn][rdim+i][v];
202
      }
203
      for (int i=k-1; i>0; i--) {
204
        q = sbt_neigh_basis[s_bn][i][s];
205
        q_bn = sbt_neigh_basis_bn[s_bn][i][s];
206
        dd = 0;
207
        for (int l=0; l<rdim; l++) {
208
          dd -= bbt_vecs[q_bn][l][q] * bbt_vecs[v_bn][l][v];
209
        }
210
        dd /= bbt_sqb[q_bn][q];
211
        for (int l=0; l<rdim; l++) {
212
          bbt_vecs[v_bn][l][v] += dd * bbt_vecs[q_bn][rdim+l][q];
213
        }
214
      }
215
      bbt_sqb[v_bn][v] = 0;
216
      for (int i=0; i<rdim; i++) {
217
        bbt_sqb[v_bn][v] += bbt_vecs[v_bn][i][v] * bbt_vecs[v_bn][i][v];
218
      }
219
      bbt_sqa[v_bn][v] = 0;
220
      for (int i=0; i<rdim; i++) {
221
        bbt_sqa[v_bn][v] += bbt_vecs[v_bn][rdim+i][v]
222
                          * bbt_vecs[v_bn][rdim+i][v];
223
      }
224

    
225
      if (2*bbt_sqb[v_bn][v] >= bbt_sqa[v_bn][v]) return 1;
226

    
227
      // scale up vector
228
      if (j < 10) {
229
        labound = Math.floor(Math.log(bbt_sqa[v_bn][v])/ln2) / 2;
230
        max_scale = exact_bits-labound-0.66*(k-2)-1;
231
        if (max_scale < 1) max_scale = 1;
232

    
233
        if (j == 0) {
234

    
235
          ldetbound = 0;
236
          Sb = 0;
237
          for (int l=k-1; l>0; l--) {
238
            q = sbt_neigh_basis[s_bn][l][s];
239
            q_bn = sbt_neigh_basis_bn[s_bn][l][s];
240
            Sb += bbt_sqb[q_bn][q];
241
            ldetbound += Math.floor(Math.log(bbt_sqb[q_bn][q])/ln2) / 2 + 1;
242
            ldetbound -= bbt_lscale[q_bn][q];
243
          }
244
        }
245
      }
246
      if (ldetbound - bbt_lscale[v_bn][v]
247
        + Math.floor(Math.log(bbt_sqb[v_bn][v])/ln2) / 2 + 1 < 0) {
248
        scale = 0;
249
      }
250
      else {
251
        lscale = (int) (Math.log(2*Sb/(bbt_sqb[v_bn][v]
252
                                     + bbt_sqa[v_bn][v]*b_err_min))/ln2) / 2;
253
        if (lscale > max_scale) lscale = (int) max_scale;
254
        else if (lscale < 0) lscale = 0;
255
        bbt_lscale[v_bn][v] += lscale;
256
        scale = (lscale < 20) ? 1 << lscale : Math.pow(2, lscale);
257
      }
258

    
259
      while (xx < 2*rdim) bbt_vecs[v_bn][xx++][v] *= scale;
260

    
261
      for (int i=k-1; i>0; i--) {
262
        q = sbt_neigh_basis[s_bn][i][s];
263
        q_bn = sbt_neigh_basis_bn[s_bn][i][s];
264
        dd = 0;
265
        for (int l=0; l<rdim; l++) {
266
          dd -= bbt_vecs[q_bn][l][q] * bbt_vecs[v_bn][rdim+l][v];
267
        }
268
        dd /= bbt_sqb[q_bn][q];
269
        dd = Math.floor(dd+0.5);
270
        for (int l=0; l<rdim; l++) {
271
          bbt_vecs[v_bn][rdim+l][v] += dd * bbt_vecs[q_bn][rdim+l][q];
272
        }
273
      }
274
    }
275
    if (failcount++ < 10) System.out.println("reduce_inner failed!");
276
    return 0;
277
  }
278

    
279
  private int reduce(int[] v, int[] v_bn, int rp, int s, int s_bn, int k) {
280
    if (v[0] == NOVAL) {
281
      v[0] = basis_s_list != NOVAL ? basis_s_list : new_block_basis_s();
282
      v_bn[0] = basis_s_list_bn;
283
      basis_s_list = bbt_next[v_bn[0]][v[0]];
284
      basis_s_list_bn = bbt_next_bn[v_bn[0]][v[0]];
285
      bbt_ref_count[v_bn[0]][v[0]] = 1;
286
    }
287
    else bbt_lscale[v_bn[0]][v[0]] = 0;
288
    if (rp == INFINITY) {
289
      bbt_next[v_bn[0]][v[0]] = bbt_next[ib_bn][ib];
290
      bbt_next_bn[v_bn[0]][v[0]] = bbt_next_bn[ib_bn][ib];
291
      bbt_ref_count[v_bn[0]][v[0]] = bbt_ref_count[ib_bn][ib];
292
      bbt_lscale[v_bn[0]][v[0]] = bbt_lscale[ib_bn][ib];
293
      bbt_sqa[v_bn[0]][v[0]] = bbt_sqa[ib_bn][ib];
294
      bbt_sqb[v_bn[0]][v[0]] = bbt_sqb[ib_bn][ib];
295
      for (int i=0; i<2*rdim; i++) {
296
        bbt_vecs[v_bn[0]][i][v[0]] = bbt_vecs[ib_bn][i][ib];
297
      }
298
    }
299
    else {
300
      double sum = 0;
301
      int sbt_nv = sbt_neigh_vert[s_bn][0][s];
302
      if (sbt_nv == INFINITY) {
303
        for (int i=0; i<dim; i++) {
304
          bbt_vecs[v_bn[0]][i+rdim][v[0]] = bbt_vecs[v_bn[0]][i][v[0]]
305
            = (double) site_blocks[i][rp];
306
        }
307
      }
308
      else {
309
        for (int i=0; i<dim; i++) {
310
          bbt_vecs[v_bn[0]][i+rdim][v[0]] = bbt_vecs[v_bn[0]][i][v[0]]
311
            = (double) (site_blocks[i][rp] - site_blocks[i][sbt_nv]);
312
        }
313
      }
314
      for (int i=0; i<dim; i++) {
315
        sum += bbt_vecs[v_bn[0]][i][v[0]] * bbt_vecs[v_bn[0]][i][v[0]];
316
      }
317
      bbt_vecs[v_bn[0]][2*rdim-1][v[0]] = sum;
318
      bbt_vecs[v_bn[0]][rdim-1][v[0]] = sum;
319
    }
320
    return reduce_inner(v[0], v_bn[0], s, s_bn, k);
321
  }
322

    
323
  private void get_basis_sede(int s, int s_bn) {
324
    int   k=1;
325
    int   q, q_bn;
326
    int[] curt = new int[1];
327
    int[] curt_bn = new int[1];
328

    
329
    if (sbt_neigh_vert[s_bn][0][s] == INFINITY && cdim > 1) {
330
      int t_vert, t_simp, t_simp_bn, t_basis, t_basis_bn;
331
      t_vert = sbt_neigh_vert[s_bn][0][s];
332
      t_simp = sbt_neigh_simp[s_bn][0][s];
333
      t_simp_bn = sbt_neigh_simp_bn[s_bn][0][s];
334
      t_basis = sbt_neigh_basis[s_bn][0][s];
335
      t_basis_bn = sbt_neigh_basis_bn[s_bn][0][s];
336
      sbt_neigh_vert[s_bn][0][s] = sbt_neigh_vert[s_bn][k][s];
337
      sbt_neigh_simp[s_bn][0][s] = sbt_neigh_simp[s_bn][k][s];
338
      sbt_neigh_simp_bn[s_bn][0][s] = sbt_neigh_simp_bn[s_bn][k][s];
339
      sbt_neigh_basis[s_bn][0][s] = sbt_neigh_basis[s_bn][k][s];
340
      sbt_neigh_basis_bn[s_bn][0][s] = sbt_neigh_basis_bn[s_bn][k][s];
341
      sbt_neigh_vert[s_bn][k][s] = t_vert;
342
      sbt_neigh_simp[s_bn][k][s] = t_simp;
343
      sbt_neigh_simp_bn[s_bn][k][s] = t_simp_bn;
344
      sbt_neigh_basis[s_bn][k][s] = t_basis;
345
      sbt_neigh_basis_bn[s_bn][k][s] = t_basis_bn;
346

    
347
      q = sbt_neigh_basis[s_bn][0][s];
348
      q_bn = sbt_neigh_basis_bn[s_bn][0][s];
349
      if ((q != NOVAL) && --bbt_ref_count[q_bn][q] == 0) {
350
        bbt_next[q_bn][q] = basis_s_list;
351
        bbt_next_bn[q_bn][q] = basis_s_list_bn;
352
        bbt_ref_count[q_bn][q] = 0;
353
        bbt_lscale[q_bn][q] = 0;
354
        bbt_sqa[q_bn][q] = 0;
355
        bbt_sqb[q_bn][q] = 0;
356
        for (int j=0; j<2*rdim; j++) bbt_vecs[q_bn][j][q] = 0;
357
        basis_s_list = q;
358
        basis_s_list_bn = q_bn;
359
      }
360

    
361
      sbt_neigh_basis[s_bn][0][s] = ttbp;
362
      sbt_neigh_basis_bn[s_bn][0][s] = ttbp_bn;
363
      bbt_ref_count[ttbp_bn][ttbp]++;
364
    }
365
    else {
366
      if (sbt_neigh_basis[s_bn][0][s] == NOVAL) {
367
        sbt_neigh_basis[s_bn][0][s] = ttbp;
368
        sbt_neigh_basis_bn[s_bn][0][s] = ttbp_bn;
369
        bbt_ref_count[ttbp_bn][ttbp]++;
370
      } else while (k < cdim && sbt_neigh_basis[s_bn][k][s] != NOVAL) k++;
371
    }
372
    while (k < cdim) {
373
      q = sbt_neigh_basis[s_bn][k][s];
374
      q_bn = sbt_neigh_basis_bn[s_bn][k][s];
375
      if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
376
        bbt_next[q_bn][q] = basis_s_list;
377
        bbt_next_bn[q_bn][q] = basis_s_list_bn;
378
        bbt_ref_count[q_bn][q] = 0;
379
        bbt_lscale[q_bn][q] = 0;
380
        bbt_sqa[q_bn][q] = 0;
381
        bbt_sqb[q_bn][q] = 0;
382
        for (int j=0; j<2*rdim; j++) bbt_vecs[q_bn][j][q] = 0;
383
        basis_s_list = q;
384
        basis_s_list_bn = q_bn;
385
      }
386
      sbt_neigh_basis[s_bn][k][s] = NOVAL;
387
      curt[0] = sbt_neigh_basis[s_bn][k][s];
388
      curt_bn[0] = sbt_neigh_basis_bn[s_bn][k][s];
389
      reduce(curt, curt_bn, sbt_neigh_vert[s_bn][k][s], s, s_bn, k);
390
      sbt_neigh_basis[s_bn][k][s] = curt[0];
391
      sbt_neigh_basis_bn[s_bn][k][s] = curt_bn[0];
392
      k++;
393
    }
394
  }
395

    
396
  private int sees(int rp, int s, int s_bn) {
397
    double  dd, dds;
398
    int     q, q_bn, q1, q1_bn, q2, q2_bn;
399
    int[]   curt = new int[1];
400
    int[]   curt_bn = new int[1];
401

    
402
    if (b == NOVAL) {
403
      b = (basis_s_list != NOVAL) ? basis_s_list : new_block_basis_s();
404
      b_bn = basis_s_list_bn;
405
      basis_s_list = bbt_next[b_bn][b];
406
      basis_s_list_bn = bbt_next_bn[b_bn][b];
407
    }
408
    else bbt_lscale[b_bn][b] = 0;
409
    if (cdim==0) return 0;
410
    if (sbt_normal[s_bn][s] == NOVAL) {
411
      get_basis_sede(s, s_bn);
412
      if (rdim==3 && cdim==3) {
413
        sbt_normal[s_bn][s] = basis_s_list != NOVAL ? basis_s_list
414
                                                    : new_block_basis_s();
415
        sbt_normal_bn[s_bn][s] = basis_s_list_bn;
416
        q = sbt_normal[s_bn][s];
417
        q_bn = sbt_normal_bn[s_bn][s];
418
        basis_s_list = bbt_next[q_bn][q];
419
        basis_s_list_bn = bbt_next_bn[q_bn][q];
420
        q1 = sbt_neigh_basis[s_bn][1][s];
421
        q1_bn = sbt_neigh_basis_bn[s_bn][1][s];
422
        q2 = sbt_neigh_basis[s_bn][2][s];
423
        q2_bn = sbt_neigh_basis_bn[s_bn][2][s];
424
        bbt_ref_count[q_bn][q] = 1;
425
        bbt_vecs[q_bn][0][q] = bbt_vecs[q1_bn][1][q1]
426
                  *bbt_vecs[q2_bn][2][q2]
427
             - bbt_vecs[q1_bn][2][q1]
428
                  *bbt_vecs[q2_bn][1][q2];
429
        bbt_vecs[q_bn][1][q] = bbt_vecs[q1_bn][2][q1]
430
                  *bbt_vecs[q2_bn][0][q2]
431
             - bbt_vecs[q1_bn][0][q1]
432
                  *bbt_vecs[q2_bn][2][q2];
433
        bbt_vecs[q_bn][2][q] = bbt_vecs[q1_bn][0][q1]
434
                  *bbt_vecs[q2_bn][1][q2]
435
             - bbt_vecs[q1_bn][1][q1]
436
                  *bbt_vecs[q2_bn][0][q2];
437
        bbt_sqb[q_bn][q] = 0;
438
        for (int i=0; i<rdim; i++) bbt_sqb[q_bn][q] += bbt_vecs[q_bn][i][q]
439
                                                     * bbt_vecs[q_bn][i][q];
440
        for (int i=cdim+1; i>0; i--) {
441
          int m = (i > 1) ? sbt_neigh_vert[ch_root_bn][i-2][ch_root]
442
                          : INFINITY;
443
          int j;
444
          for (j=0; j<cdim && m != sbt_neigh_vert[s_bn][j][s]; j++);
445
          if (j < cdim) continue;
446
          if (m == INFINITY) {
447
            if (bbt_vecs[q_bn][2][q] > -b_err_min) continue;
448
          }
449
          else {
450
            if (sees(m, s, s_bn) == 0) {
451
              continue;
452
            }
453
          }
454
          bbt_vecs[q_bn][0][q] = -bbt_vecs[q_bn][0][q];
455
          bbt_vecs[q_bn][1][q] = -bbt_vecs[q_bn][1][q];
456
          bbt_vecs[q_bn][2][q] = -bbt_vecs[q_bn][2][q];
457
          break;
458
        }
459
      }
460
      else {
461
        for (int i=cdim+1; i>0; i--) {
462
          int m = (i > 1) ? sbt_neigh_vert[ch_root_bn][i-2][ch_root]
463
                          : INFINITY;
464
          int j;
465
          for (j=0; j<cdim && m != sbt_neigh_vert[s_bn][j][s]; j++);
466
          if (j < cdim) continue;
467
          curt[0] = sbt_normal[s_bn][s];
468
          curt_bn[0] = sbt_normal_bn[s_bn][s];
469
          reduce(curt, curt_bn, m, s, s_bn, cdim);
470
          q = sbt_normal[s_bn][s] = curt[0];
471
          q_bn = sbt_normal_bn[s_bn][s] = curt_bn[0];
472
          if (bbt_sqb[q_bn][q] != 0) break;
473
        }
474
      }
475

    
476
      for (int i=0; i<cdim; i++) {
477
        q = sbt_neigh_basis[s_bn][i][s];
478
        q_bn = sbt_neigh_basis_bn[s_bn][i][s];
479
        if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
480
          bbt_next[q_bn][q] = basis_s_list;
481
          bbt_next_bn[q_bn][q] = basis_s_list_bn;
482
          bbt_ref_count[q_bn][q] = 0;
483
          bbt_lscale[q_bn][q] = 0;
484
          bbt_sqa[q_bn][q] = 0;
485
          bbt_sqb[q_bn][q] = 0;
486
          for (int l=0; l<2*rdim; l++) bbt_vecs[q_bn][l][q] = 0;
487
          basis_s_list = q;
488
          basis_s_list_bn = q_bn;
489
        }
490
        sbt_neigh_basis[s_bn][i][s] = NOVAL;
491
      }
492
    }
493
    if (rp == INFINITY) {
494
      bbt_next[b_bn][b] = bbt_next[ib_bn][ib];
495
      bbt_next_bn[b_bn][b] = bbt_next_bn[ib_bn][ib];
496
      bbt_ref_count[b_bn][b] = bbt_ref_count[ib_bn][ib];
497
      bbt_lscale[b_bn][b] = bbt_lscale[ib_bn][ib];
498
      bbt_sqa[b_bn][b] = bbt_sqa[ib_bn][ib];
499
      bbt_sqb[b_bn][b] = bbt_sqb[ib_bn][ib];
500
      for (int i=0; i<2*rdim; i++) {
501
        bbt_vecs[b_bn][i][b] = bbt_vecs[ib_bn][i][ib];
502
      }
503
    }
504
    else {
505
      double sum = 0;
506
      int sbt_nv = sbt_neigh_vert[s_bn][0][s];
507
      if (sbt_nv == INFINITY) {
508
        for (int l=0; l<dim; l++) {
509
          bbt_vecs[b_bn][l+rdim][b] = bbt_vecs[b_bn][l][b]
510
            = (double) site_blocks[l][rp];
511
        }
512
      }
513
      else {
514
        for (int l=0; l<dim; l++) {
515
          bbt_vecs[b_bn][l+rdim][b] = bbt_vecs[b_bn][l][b]
516
            = (double) (site_blocks[l][rp] - site_blocks[l][sbt_nv]);
517
        }
518
      }
519
      for (int l=0; l<dim; l++) {
520
        sum += bbt_vecs[b_bn][l][b] * bbt_vecs[b_bn][l][b];
521
      }
522
      bbt_vecs[b_bn][2*rdim-1][b] = bbt_vecs[b_bn][rdim-1][b] = sum;
523
    }
524
    q = sbt_normal[s_bn][s];
525
    q_bn = sbt_normal_bn[s_bn][s];
526
    for (int i=0; i<3; i++) {
527
      double sum = 0;
528
      dd = 0;
529
      for (int l=0; l<rdim; l++) {
530
        dd += bbt_vecs[b_bn][l][b] * bbt_vecs[q_bn][l][q];
531
      }
532
      if (dd == 0.0) return 0;
533
      for (int l=0; l<rdim; l++) {
534
        sum += bbt_vecs[b_bn][l][b] * bbt_vecs[b_bn][l][b];
535
      }
536
      dds = dd*dd/bbt_sqb[q_bn][q]/sum;
537
      if (dds > b_err_min_sq) return (dd < 0 ? 1 : 0);
538
      get_basis_sede(s, s_bn);
539
      reduce_inner(b, b_bn, s, s_bn, cdim);
540
    }
541
    return 0;
542
  }
543

    
544
  private int new_block_simplex() {
545
    sbt_next[nsb] = new int[Nobj];
546
    sbt_next_bn[nsb] = new int[Nobj];
547
    sbt_visit[nsb] = new long[Nobj];
548
    sbt_mark[nsb] = new short[Nobj];
549
    sbt_normal[nsb] = new int[Nobj];
550
    sbt_normal_bn[nsb] = new int[Nobj];
551
    sbt_peak_vert[nsb] = new int[Nobj];
552
    sbt_peak_simp[nsb] = new int[Nobj];
553
    sbt_peak_simp_bn[nsb] = new int[Nobj];
554
    sbt_peak_basis[nsb] = new int[Nobj];
555
    sbt_peak_basis_bn[nsb] = new int[Nobj];
556
    sbt_neigh_vert[nsb] = new int[rdim][];
557
    sbt_neigh_simp[nsb] = new int[rdim][];
558
    sbt_neigh_simp_bn[nsb] = new int[rdim][];
559
    sbt_neigh_basis[nsb] = new int[rdim][];
560
    sbt_neigh_basis_bn[nsb] = new int[rdim][];
561
    for (int i=0; i<rdim; i++) {
562
      sbt_neigh_vert[nsb][i] = new int[Nobj];
563
      sbt_neigh_simp[nsb][i] = new int[Nobj];
564
      sbt_neigh_simp_bn[nsb][i] = new int[Nobj];
565
      sbt_neigh_basis[nsb][i] = new int[Nobj];
566
      sbt_neigh_basis_bn[nsb][i] = new int[Nobj];
567
    }
568
    for (int i=0; i<Nobj; i++) {
569
      sbt_next[nsb][i] = i+1;
570
      sbt_next_bn[nsb][i] = nsb;
571
      sbt_visit[nsb][i] = 0;
572
      sbt_mark[nsb][i] = 0;
573
      sbt_normal[nsb][i] = NOVAL;
574
      sbt_peak_vert[nsb][i] = NOVAL;
575
      sbt_peak_simp[nsb][i] = NOVAL;
576
      sbt_peak_basis[nsb][i] = NOVAL;
577
      for (int j=0; j<rdim; j++) {
578
        sbt_neigh_vert[nsb][j][i] = NOVAL;
579
        sbt_neigh_simp[nsb][j][i] = NOVAL;
580
        sbt_neigh_basis[nsb][j][i] = NOVAL;
581
      }
582
    }
583
    sbt_next[nsb][Nobj-1] = NOVAL;
584
    simplex_list = 0;
585
    simplex_list_bn = nsb;
586

    
587
    nsb++;
588
    return simplex_list;
589
  }
590

    
591
  /**
592
     starting at s, visit simplices t such that test(s,i,0) is true,
593
     and t is the i'th neighbor of s;
594
     apply visit function to all visited simplices;
595
     when visit returns nonnull, exit and return its value.
596
  */
597
  private void visit_triang_gen(int s, int s_bn, int whichfunc,
598
                                int[] ret, int[] ret_bn) {
599
    int v;
600
    int v_bn;
601
    int t;
602
    int t_bn;
603
    int tms = 0;
604

    
605
    vnum--;
606
    if (s != NOVAL) {
607
      st2[tms] = s;
608
      st2_bn[tms] = s_bn;
609
      tms++;
610
    }
611
    while (tms != 0) {
612
      if (tms > ss2) {
613
        // JAVA: efficiency issue: how much is this stack hammered?
614
        ss2 += ss2;
615
        int[] newst2 = new int[ss2+MAXDIM+1];
616
        int[] newst2_bn = new int[ss2+MAXDIM+1];
617
        System.arraycopy(st2, 0, newst2, 0, st2.length);
618
        System.arraycopy(st2_bn, 0, newst2_bn, 0, st2_bn.length);
619
        st2 = newst2;
620
        st2_bn = newst2_bn;
621
      }
622
      tms--;
623
      t = st2[tms];
624
      t_bn = st2_bn[tms];
625
      if (t == NOVAL || sbt_visit[t_bn][t] == vnum) continue;
626
      sbt_visit[t_bn][t] = vnum;
627
      if (whichfunc == 1) {
628
        if (sbt_peak_vert[t_bn][t] == NOVAL) {
629
          v = t;
630
          v_bn = t_bn;
631
        }
632
        else {
633
          v = NOVAL;
634
          v_bn = NOVAL;
635
        }
636
        if (v != NOVAL) {
637
          ret[0] = v;
638
          ret_bn[0] = v_bn;
639
          return;
640
        }
641
      }
642
      else {
643
        int[] vfp = new int[cdim];
644

    
645
        if (t != NOVAL) {
646
          for (int j=0; j<cdim; j++) vfp[j] = sbt_neigh_vert[t_bn][j][t];
647
          for (int j=0; j<cdim; j++) {
648
            a3s[j][nts] = (vfp[j] == INFINITY) ? -1 : vfp[j];
649
          }
650
          nts++;
651
          if (nts > a3size) {
652
            // JAVA: efficiency issue, hammering an array
653
            a3size += a3size;
654
            int[][] newa3s = new int[rdim][a3size+MAXDIM+1];
655
            for (int i=0; i<rdim; i++) {
656
              System.arraycopy(a3s[i], 0, newa3s[i], 0, a3s[i].length);
657
            }
658
            a3s = newa3s;
659
          }
660
        }
661
      }
662
      for (int i=0; i<cdim; i++) {
663
        int j = sbt_neigh_simp[t_bn][i][t];
664
        int j_bn = sbt_neigh_simp_bn[t_bn][i][t];
665
        if ((j != NOVAL) && sbt_visit[j_bn][j] != vnum) {
666
          st2[tms] = j;
667
          st2_bn[tms] = j_bn;
668
          tms++;
669
        }
670
      }
671
    }
672
    ret[0] = NOVAL;
673
  }
674

    
675
  /**
676
     make neighbor connections between newly created simplices incident to p.
677
  */
678
  private void connect(int s, int s_bn) {
679
    int xb, xf;
680
    int sb, sb_bn;
681
    int sf, sf_bn;
682
    int tf, tf_bn;
683
    int ccj, ccj_bn;
684
    int xfi;
685

    
686
    if (s == NOVAL) return;
687
    for (int i=0; (sbt_neigh_vert[s_bn][i][s] != p) && (i<cdim); i++);
688
    if (sbt_visit[s_bn][s] == pnum) return;
689
    sbt_visit[s_bn][s] = pnum;
690
    ccj = sbt_peak_simp[s_bn][s];
691
    ccj_bn = sbt_peak_simp_bn[s_bn][s];
692
    for (xfi=0; (sbt_neigh_simp[ccj_bn][xfi][ccj] != s
693
              || sbt_neigh_simp_bn[ccj_bn][xfi][ccj] != s_bn)
694
                     && (xfi<cdim); xfi++);
695
    for (int i=0; i<cdim; i++) {
696
      int l;
697
      if (p == sbt_neigh_vert[s_bn][i][s]) continue;
698
      sb = sbt_peak_simp[s_bn][s];
699
      sb_bn = sbt_peak_simp_bn[s_bn][s];
700
      sf = sbt_neigh_simp[s_bn][i][s];
701
      sf_bn = sbt_neigh_simp_bn[s_bn][i][s];
702
      xf = sbt_neigh_vert[ccj_bn][xfi][ccj];
703
      if (sbt_peak_vert[sf_bn][sf] == NOVAL) {  // are we done already?
704
        for (l=0; (sbt_neigh_vert[ccj_bn][l][ccj]
705
                != sbt_neigh_vert[s_bn][i][s]) && (l<cdim); l++);
706
        sf = sbt_neigh_simp[ccj_bn][l][ccj];
707
        sf_bn = sbt_neigh_simp_bn[ccj_bn][l][ccj];
708
        if (sbt_peak_vert[sf_bn][sf] != NOVAL) continue;
709
      } else do {
710
        xb = xf;
711
        for (l=0; (sbt_neigh_simp[sf_bn][l][sf] != sb
712
                || sbt_neigh_simp_bn[sf_bn][l][sf] != sb_bn)
713
                && l<cdim; l++);
714
        xf = sbt_neigh_vert[sf_bn][l][sf];
715
        sb = sf;
716
        sb_bn = sf_bn;
717
        for (l=0; (sbt_neigh_vert[sb_bn][l][sb] != xb) && (l<cdim); l++);
718
        tf = sbt_neigh_simp[sf_bn][l][sf];
719
        tf_bn = sbt_neigh_simp_bn[sf_bn][l][sf];
720
        sf = tf;
721
        sf_bn = tf_bn;
722
      } while (sbt_peak_vert[sf_bn][sf] != NOVAL);
723

    
724
      sbt_neigh_simp[s_bn][i][s] = sf;
725
      sbt_neigh_simp_bn[s_bn][i][s] = sf_bn;
726
      for (l=0; (sbt_neigh_vert[sf_bn][l][sf] != xf) && (l<cdim); l++);
727
      sbt_neigh_simp[sf_bn][l][sf] = s;
728
      sbt_neigh_simp_bn[sf_bn][l][sf] = s_bn;
729

    
730
      connect(sf, sf_bn);
731
    }
732

    
733
  }
734

    
735
  /**
736
     visit simplices s with sees(p,s), and make a facet for every neighbor
737
     of s not seen by p.
738
  */
739
  private void make_facets(int seen, int seen_bn, int[] ret, int[] ret_bn) {
740
    int n, n_bn;
741
    int q, q_bn;
742
    int j;
743

    
744
    if (seen == NOVAL) {
745
      ret[0] = NOVAL;
746
      return;
747
    }
748
    sbt_peak_vert[seen_bn][seen] = p;
749

    
750
    for (int i=0; i<cdim; i++) {
751
      n = sbt_neigh_simp[seen_bn][i][seen];
752
      n_bn = sbt_neigh_simp_bn[seen_bn][i][seen];
753

    
754
      if (pnum != sbt_visit[n_bn][n]) {
755
        sbt_visit[n_bn][n] = pnum;
756
        if (sees(p, n, n_bn) != 0) make_facets(n, n_bn, voidp, voidp_bn);
757
      }
758
      if (sbt_peak_vert[n_bn][n] != NOVAL) continue;
759

    
760
      ns = (simplex_list != NOVAL) ? simplex_list : new_block_simplex();
761
      ns_bn = simplex_list_bn;
762
      simplex_list = sbt_next[ns_bn][ns];
763
      simplex_list_bn = sbt_next_bn[ns_bn][ns];
764
      sbt_next[ns_bn][ns] = sbt_next[seen_bn][seen];
765
      sbt_next_bn[ns_bn][ns] = sbt_next_bn[seen_bn][seen];
766
      sbt_visit[ns_bn][ns] = sbt_visit[seen_bn][seen];
767
      sbt_mark[ns_bn][ns] = sbt_mark[seen_bn][seen];
768
      sbt_normal[ns_bn][ns] = sbt_normal[seen_bn][seen];
769
      sbt_normal_bn[ns_bn][ns] = sbt_normal_bn[seen_bn][seen];
770
      sbt_peak_vert[ns_bn][ns] = sbt_peak_vert[seen_bn][seen];
771
      sbt_peak_simp[ns_bn][ns] = sbt_peak_simp[seen_bn][seen];
772
      sbt_peak_simp_bn[ns_bn][ns] = sbt_peak_simp_bn[seen_bn][seen];
773
      sbt_peak_basis[ns_bn][ns] = sbt_peak_basis[seen_bn][seen];
774
      sbt_peak_basis_bn[ns_bn][ns] = sbt_peak_basis_bn[seen_bn][seen];
775
      for (j=0; j<rdim; j++) {
776
        sbt_neigh_vert[ns_bn][j][ns] = sbt_neigh_vert[seen_bn][j][seen];
777
        sbt_neigh_simp[ns_bn][j][ns] = sbt_neigh_simp[seen_bn][j][seen];
778
        sbt_neigh_simp_bn[ns_bn][j][ns]
779
                       = sbt_neigh_simp_bn[seen_bn][j][seen];
780
        sbt_neigh_basis[ns_bn][j][ns] = sbt_neigh_basis[seen_bn][j][seen];
781
        sbt_neigh_basis_bn[ns_bn][j][ns]
782
                        = sbt_neigh_basis_bn[seen_bn][j][seen];
783
      }
784

    
785
      for (j=0; j<cdim; j++) {
786
        q = sbt_neigh_basis[seen_bn][j][seen];
787
        q_bn = sbt_neigh_basis_bn[seen_bn][j][seen];
788
        if (q != NOVAL) bbt_ref_count[q_bn][q]++;
789
      }
790

    
791
      sbt_visit[ns_bn][ns] = 0;
792
      sbt_peak_vert[ns_bn][ns] = NOVAL;
793
      sbt_normal[ns_bn][ns] = NOVAL;
794
      sbt_peak_simp[ns_bn][ns] = seen;
795
      sbt_peak_simp_bn[ns_bn][ns] = seen_bn;
796

    
797
      q = sbt_neigh_basis[ns_bn][i][ns];
798
      q_bn = sbt_neigh_basis_bn[ns_bn][i][ns];
799
      if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
800
        bbt_next[q_bn][q] = basis_s_list;
801
        bbt_next_bn[q_bn][q] = basis_s_list_bn;
802
        bbt_ref_count[q_bn][q] = 0;
803
        bbt_lscale[q_bn][q] = 0;
804
        bbt_sqa[q_bn][q] = 0;
805
        bbt_sqb[q_bn][q] = 0;
806
        for (int l=0; l<2*rdim; l++) bbt_vecs[q_bn][l][q] = 0;
807
        basis_s_list = q;
808
        basis_s_list_bn = q_bn;
809
      }
810
      sbt_neigh_basis[ns_bn][i][ns] = NOVAL;
811

    
812
      sbt_neigh_vert[ns_bn][i][ns] = p;
813
      for (j=0; (sbt_neigh_simp[n_bn][j][n] != seen
814
                  || sbt_neigh_simp_bn[n_bn][j][n] != seen_bn)
815
                  && j<cdim; j++);
816
      sbt_neigh_simp[seen_bn][i][seen] = sbt_neigh_simp[n_bn][j][n] = ns;
817
      sbt_neigh_simp_bn[seen_bn][i][seen] = ns_bn;
818
      sbt_neigh_simp_bn[n_bn][j][n] = ns_bn;
819
    }
820
    ret[0] = ns;
821
    ret_bn[0] = ns_bn;
822
  }
823

    
824
  /**
825
     p lies outside flat containing previous sites;
826
     make p a vertex of every current simplex, and create some new simplices.
827
  */
828
  private void extend_simplices(int s, int s_bn, int[] ret, int[] ret_bn) {
829
    int q, q_bn;
830
    int ns, ns_bn;
831

    
832
    if (sbt_visit[s_bn][s] == pnum) {
833
      if (sbt_peak_vert[s_bn][s] != NOVAL) {
834
        ret[0] = sbt_neigh_simp[s_bn][cdim-1][s];
835
        ret_bn[0] = sbt_neigh_simp_bn[s_bn][cdim-1][s];
836
      }
837
      else {
838
        ret[0] = s;
839
        ret_bn[0] = s_bn;
840
      }
841
      return;
842
    }
843
    sbt_visit[s_bn][s] = pnum;
844
    sbt_neigh_vert[s_bn][cdim-1][s] = p;
845
    q = sbt_normal[s_bn][s];
846
    q_bn = sbt_normal_bn[s_bn][s];
847
    if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
848
      bbt_next[q_bn][q] = basis_s_list;
849
      bbt_next_bn[q_bn][q] = basis_s_list_bn;
850
      bbt_ref_count[q_bn][q] = 0;
851
      bbt_lscale[q_bn][q] = 0;
852
      bbt_sqa[q_bn][q] = 0;
853
      bbt_sqb[q_bn][q] = 0;
854
      for (int j=0; j<2*rdim; j++) bbt_vecs[q_bn][j][q] = 0;
855
      basis_s_list = q;
856
      basis_s_list_bn = q_bn;
857
    }
858
    sbt_normal[s_bn][s] = NOVAL;
859

    
860
    q = sbt_neigh_basis[s_bn][0][s];
861
    q_bn = sbt_neigh_basis_bn[s_bn][0][s];
862
    if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
863
      bbt_next[q_bn][q] = basis_s_list;
864
      bbt_ref_count[q_bn][q] = 0;
865
      bbt_lscale[q_bn][q] = 0;
866
      bbt_sqa[q_bn][q] = 0;
867
      bbt_sqb[q_bn][q] = 0;
868
      for (int j=0; j<2*rdim; j++) bbt_vecs[q_bn][j][q] = 0;
869

    
870
      basis_s_list = q;
871
      basis_s_list_bn = q_bn;
872
    }
873
    sbt_neigh_basis[s_bn][0][s] = NOVAL;
874

    
875
    if (sbt_peak_vert[s_bn][s] == NOVAL) {
876
      int[] esretp = new int[1];
877
      int[] esretp_bn = new int[1];
878
      extend_simplices(sbt_peak_simp[s_bn][s],
879
                       sbt_peak_simp_bn[s_bn][s], esretp, esretp_bn);
880
      sbt_neigh_simp[s_bn][cdim-1][s] = esretp[0];
881
      sbt_neigh_simp_bn[s_bn][cdim-1][s] = esretp_bn[0];
882
      ret[0] = s;
883
      ret_bn[0] = s_bn;
884
      return;
885
    }
886
    else {
887
      ns = (simplex_list != NOVAL) ? simplex_list : new_block_simplex();
888
      ns_bn = simplex_list_bn;
889
      simplex_list = sbt_next[ns_bn][ns];
890
      simplex_list_bn = sbt_next_bn[ns_bn][ns];
891
      sbt_next[ns_bn][ns] = sbt_next[s_bn][s];
892
      sbt_next_bn[ns_bn][ns] = sbt_next_bn[s_bn][s];
893
      sbt_visit[ns_bn][ns] = sbt_visit[s_bn][s];
894
      sbt_mark[ns_bn][ns] = sbt_mark[s_bn][s];
895
      sbt_normal[ns_bn][ns] = sbt_normal[s_bn][s];
896
      sbt_normal_bn[ns_bn][ns] = sbt_normal_bn[s_bn][s];
897
      sbt_peak_vert[ns_bn][ns] = sbt_peak_vert[s_bn][s];
898
      sbt_peak_simp[ns_bn][ns] = sbt_peak_simp[s_bn][s];
899
      sbt_peak_simp_bn[ns_bn][ns] = sbt_peak_simp_bn[s_bn][s];
900
      sbt_peak_basis[ns_bn][ns] = sbt_peak_basis[s_bn][s];
901
      sbt_peak_basis_bn[ns_bn][ns] = sbt_peak_basis_bn[s_bn][s];
902
      for (int j=0; j<rdim; j++) {
903
        sbt_neigh_vert[ns_bn][j][ns] = sbt_neigh_vert[s_bn][j][s];
904
        sbt_neigh_simp[ns_bn][j][ns] = sbt_neigh_simp[s_bn][j][s];
905
        sbt_neigh_simp_bn[ns_bn][j][ns] = sbt_neigh_simp_bn[s_bn][j][s];
906
        sbt_neigh_basis[ns_bn][j][ns] = sbt_neigh_basis[s_bn][j][s];
907
        sbt_neigh_basis_bn[ns_bn][j][ns] = sbt_neigh_basis_bn[s_bn][j][s];
908
      }
909

    
910
      for (int j=0; j<cdim; j++) {
911
        q = sbt_neigh_basis[s_bn][j][s];
912
        q_bn = sbt_neigh_basis_bn[s_bn][j][s];
913
        if (q != NOVAL) bbt_ref_count[q_bn][q]++;
914
      }
915

    
916
      sbt_neigh_simp[s_bn][cdim-1][s] = ns;
917
      sbt_neigh_simp_bn[s_bn][cdim-1][s] = ns_bn;
918
      sbt_peak_vert[ns_bn][ns] = NOVAL;
919
      sbt_peak_simp[ns_bn][ns] = s;
920
      sbt_peak_simp_bn[ns_bn][ns] = s_bn;
921
      sbt_neigh_vert[ns_bn][cdim-1][ns] = sbt_peak_vert[s_bn][s];
922
      sbt_neigh_simp[ns_bn][cdim-1][ns] = sbt_peak_simp[s_bn][s];
923
      sbt_neigh_simp_bn[ns_bn][cdim-1][ns] = sbt_peak_simp_bn[s_bn][s];
924
      sbt_neigh_basis[ns_bn][cdim-1][ns] = sbt_peak_basis[s_bn][s];
925
      sbt_neigh_basis_bn[ns_bn][cdim-1][ns] = sbt_peak_basis_bn[s_bn][s];
926
      q = sbt_peak_basis[s_bn][s];
927
      q_bn = sbt_peak_basis_bn[s_bn][s];
928
      if (q != NOVAL) bbt_ref_count[q_bn][q]++;
929
      for (int i=0; i<cdim; i++) {
930
        int[] esretp = new int[1];
931
        int[] esretp_bn = new int[1];
932
        extend_simplices(sbt_neigh_simp[ns_bn][i][ns],
933
                         sbt_neigh_simp_bn[ns_bn][i][ns], esretp, esretp_bn);
934
        sbt_neigh_simp[ns_bn][i][ns] = esretp[0];
935
        sbt_neigh_simp_bn[ns_bn][i][ns] = esretp_bn[0];
936
      }
937
    }
938
    ret[0] = ns;
939
    ret_bn[0] = ns_bn;
940
    return;
941
  }
942

    
943
  /**
944
     return a simplex s that corresponds to a facet of the
945
     current hull, and sees(p, s).
946
  */
947
  private void search(int root, int root_bn, int[] ret, int[] ret_bn) {
948
    int s, s_bn;
949
    int tms = 0;
950

    
951
    st[tms] = sbt_peak_simp[root_bn][root];
952
    st_bn[tms] = sbt_peak_simp_bn[root_bn][root];
953
    tms++;
954
    sbt_visit[root_bn][root] = pnum;
955
    if (sees(p, root, root_bn) == 0) {
956
      for (int i=0; i<cdim; i++) {
957
        st[tms] = sbt_neigh_simp[root_bn][i][root];
958
        st_bn[tms] = sbt_neigh_simp_bn[root_bn][i][root];
959
        tms++;
960
      }
961
    }
962
    while (tms != 0) {
963
      if (tms > ss) {
964
        // JAVA: efficiency issue: how much is this stack hammered?
965
        ss += ss;
966
        int[] newst = new int[ss+MAXDIM+1];
967
        int[] newst_bn = new int[ss+MAXDIM+1];
968
        System.arraycopy(st, 0, newst, 0, st.length);
969
        System.arraycopy(st_bn, 0, newst_bn, 0, st_bn.length);
970
        st = newst;
971
        st_bn = newst_bn;
972
      }
973
      tms--;
974
      s = st[tms];
975
      s_bn = st_bn[tms];
976
      if (sbt_visit[s_bn][s] == pnum) continue;
977
      sbt_visit[s_bn][s] = pnum;
978
      if (sees(p, s, s_bn) == 0) continue;
979
      if (sbt_peak_vert[s_bn][s] == NOVAL) {
980
        ret[0] = s;
981
        ret_bn[0] = s_bn;
982
        return;
983
      }
984
      for (int i=0; i<cdim; i++) {
985
        st[tms] = sbt_neigh_simp[s_bn][i][s];
986
        st_bn[tms] = sbt_neigh_simp_bn[s_bn][i][s];
987
        tms++;
988
      }
989
    }
990
    ret[0] = NOVAL;
991
    return;
992
  }
993

    
994

    
995
  // <<<< Constructor >>>>
996
  public DelaunayClarkson(double[][] samples) throws VisADException {
997
    int s, s_bn, q, q_bn;
998
    int root, root_bn;
999
    int k=0;
1000
    int[] retp = new int[1];
1001
    int[] retp_bn = new int[1];
1002
    int[] ret2p = new int[1];
1003
    int[] ret2p_bn = new int[1];
1004
    int[] curt = new int[1];
1005
    int[] curt_bn = new int[1];
1006
    int s_num = 0;
1007
    int nrs;
1008

    
1009
    // Start of main hull triangulation algorithm
1010
    dim = samples.length;
1011
    nrs = samples[0].length;
1012
    for (int i=1; i<dim; i++) nrs = Math.min(nrs, samples[i].length);
1013

    
1014
    if (nrs <= dim) throw new SetException("DelaunayClarkson: "
1015
                                          +"not enough samples");
1016
    if (dim > MAXDIM) throw new SetException("DelaunayClarkson: "
1017
                               +"dimension bound MAXDIM exceeded");
1018

    
1019
    // copy samples
1020
    site_blocks = new double[dim][nrs];
1021
    for (int j=0; j<dim; j++) {
1022
      System.arraycopy(samples[j], 0, site_blocks[j], 0, nrs);
1023
    }
1024

    
1025
/* WLH 29 Jan 98 - scale samples values as discussed in Delaunay.factory
1026
    for (int j=0; j<dim; j++) {
1027
      for (int kk=0; kk<nrs; kk++) {
1028
        site_blocks[j][kk] = 100.0f * samples[j][kk];
1029
      }
1030
    }
1031
*/
1032

    
1033
    exact_bits = (int) (DBL_MANT_DIG*Math.log(FLT_RADIX)/ln2);
1034
    b_err_min = DBL_EPSILON*MAXDIM*(1<<MAXDIM)*MAXDIM*3.01;
1035
    b_err_min_sq = b_err_min * b_err_min;
1036

    
1037
    cdim = 0;
1038
    rdim = dim+1;
1039
    if (rdim > MAXDIM) throw new SetException(
1040
              "dimension bound MAXDIM exceeded; rdim="+rdim+"; dim="+dim);
1041

    
1042
    pnb = basis_s_list != NOVAL ? basis_s_list : new_block_basis_s();
1043
    pnb_bn = basis_s_list_bn;
1044
    basis_s_list = bbt_next[pnb_bn][pnb];
1045
    basis_s_list_bn = bbt_next_bn[pnb_bn][pnb];
1046
    bbt_next[pnb_bn][pnb] = NOVAL;
1047

    
1048
    ttbp = basis_s_list != NOVAL ? basis_s_list : new_block_basis_s();
1049
    ttbp_bn = basis_s_list_bn;
1050
    basis_s_list = bbt_next[ttbp_bn][ttbp];
1051
    basis_s_list_bn = bbt_next_bn[ttbp_bn][ttbp];
1052
    bbt_next[ttbp_bn][ttbp] = NOVAL;
1053
    bbt_ref_count[ttbp_bn][ttbp] = 1;
1054
    bbt_lscale[ttbp_bn][ttbp] = -1;
1055
    bbt_sqa[ttbp_bn][ttbp] = 0;
1056
    bbt_sqb[ttbp_bn][ttbp] = 0;
1057
    for (int j=0; j<2*rdim; j++) bbt_vecs[ttbp_bn][j][ttbp] = 0;
1058

    
1059
    root = NOVAL;
1060
    p = INFINITY;
1061
    ib = (basis_s_list != NOVAL) ? basis_s_list : new_block_basis_s();
1062
    ib_bn = basis_s_list_bn;
1063
    basis_s_list = bbt_next[ib_bn][ib];
1064
    basis_s_list_bn = bbt_next_bn[ib_bn][ib];
1065
    bbt_ref_count[ib_bn][ib] = 1;
1066
    bbt_vecs[ib_bn][2*rdim-1][ib] = bbt_vecs[ib_bn][rdim-1][ib] = 1;
1067
    bbt_sqa[ib_bn][ib] = bbt_sqb[ib_bn][ib] = 1;
1068

    
1069
    root = (simplex_list != NOVAL) ? simplex_list : new_block_simplex();
1070
    root_bn = simplex_list_bn;
1071
    simplex_list = sbt_next[root_bn][root];
1072
    simplex_list_bn = sbt_next_bn[root_bn][root];
1073

    
1074
    ch_root = root;
1075
    ch_root_bn = root_bn;
1076

    
1077
    s = (simplex_list != NOVAL) ? simplex_list : new_block_simplex();
1078
    s_bn = simplex_list_bn;
1079
    simplex_list = sbt_next[s_bn][s];
1080
    simplex_list_bn = sbt_next_bn[s_bn][s];
1081
    sbt_next[s_bn][s] = sbt_next[root_bn][root];
1082
    sbt_next_bn[s_bn][s] = sbt_next_bn[root_bn][root];
1083
    sbt_visit[s_bn][s] = sbt_visit[root_bn][root];
1084
    sbt_mark[s_bn][s] = sbt_mark[root_bn][root];
1085
    sbt_normal[s_bn][s] = sbt_normal[root_bn][root];
1086
    sbt_normal_bn[s_bn][s] = sbt_normal_bn[root_bn][root];
1087
    sbt_peak_vert[s_bn][s] = sbt_peak_vert[root_bn][root];
1088
    sbt_peak_simp[s_bn][s] = sbt_peak_simp[root_bn][root];
1089
    sbt_peak_simp_bn[s_bn][s] = sbt_peak_simp_bn[root_bn][root];
1090
    sbt_peak_basis[s_bn][s] = sbt_peak_basis[root_bn][root];
1091
    sbt_peak_basis_bn[s_bn][s] = sbt_peak_basis_bn[root_bn][root];
1092
    for (int i=0; i<rdim; i++) {
1093
      sbt_neigh_vert[s_bn][i][s] = sbt_neigh_vert[root_bn][i][root];
1094
      sbt_neigh_simp[s_bn][i][s] = sbt_neigh_simp[root_bn][i][root];
1095
      sbt_neigh_simp_bn[s_bn][i][s] = sbt_neigh_simp_bn[root_bn][i][root];
1096
      sbt_neigh_basis[s_bn][i][s] = sbt_neigh_basis[root_bn][i][root];
1097
      sbt_neigh_basis_bn[s_bn][i][s] = sbt_neigh_basis_bn[root_bn][i][root];
1098
    }
1099
    for (int i=0;i<cdim;i++) {
1100
      q = sbt_neigh_basis[root_bn][i][root];
1101
      q_bn = sbt_neigh_basis_bn[root_bn][i][root];
1102
      if (q != NOVAL) bbt_ref_count[q_bn][q]++;
1103
    }
1104
    sbt_peak_vert[root_bn][root] = p;
1105
    sbt_peak_simp[root_bn][root] = s;
1106
    sbt_peak_simp_bn[root_bn][root] = s_bn;
1107
    sbt_peak_simp[s_bn][s] = root;
1108
    sbt_peak_simp_bn[s_bn][s] = root_bn;
1109
    while (cdim < rdim) {
1110
      int oof = 0;
1111

    
1112
      if (s_num == 0) p = 0;
1113
      else p++;
1114
      for (int i=0; i<dim; i++) {
1115
        site_blocks[i][p] = (double) Math.floor(site_blocks[i][p]+0.5);
1116
      }
1117
      s_num++;
1118
      pnum = (s_num*dim-1)/dim + 2;
1119

    
1120
      cdim++;
1121
      sbt_neigh_vert[root_bn][cdim-1][root] = sbt_peak_vert[root_bn][root];
1122

    
1123
      q = sbt_neigh_basis[root_bn][cdim-1][root];
1124
      q_bn = sbt_neigh_basis_bn[root_bn][cdim-1][root];
1125
      if (q != NOVAL && --bbt_ref_count[q_bn][q] == 0) {
1126
        bbt_next[q_bn][q] = basis_s_list;
1127
        bbt_next_bn[q_bn][q] = basis_s_list_bn;
1128
        bbt_ref_count[q_bn][q] = 0;
1129
        bbt_lscale[q_bn][q] = 0;
1130
        bbt_sqa[q_bn][q] = 0;
1131
        bbt_sqb[q_bn][q] = 0;
1132
        for (int l=0; l<2*rdim; l++) bbt_vecs[q_bn][l][q] = 0;
1133

    
1134
        basis_s_list = q;
1135
        basis_s_list_bn = q_bn;
1136
      }
1137
      sbt_neigh_basis[root_bn][cdim-1][root] = NOVAL;
1138

    
1139
      get_basis_sede(root, root_bn);
1140
      if (sbt_neigh_vert[root_bn][0][root] == INFINITY) oof = 1;
1141
      else {
1142
        curt[0] = pnb;
1143
        curt_bn[0] = pnb_bn;
1144
        reduce(curt, curt_bn, p, root, root_bn, cdim);
1145
        pnb = curt[0];
1146
        pnb_bn = curt_bn[0];
1147
        if (bbt_sqa[pnb_bn][pnb] != 0) oof = 1;
1148
        else cdim--;
1149
      }
1150
      if (oof != 0) extend_simplices(root, root_bn, voidp, voidp_bn);
1151
      else {
1152
        search(root, root_bn, retp, retp_bn);
1153
        make_facets(retp[0], retp_bn[0], ret2p, ret2p_bn);
1154
        connect(ret2p[0], ret2p_bn[0]);
1155
      }
1156
    }
1157

    
1158
    for (int i=s_num; i<nrs; i++) {
1159
      p++;
1160
      s_num++;
1161
      for (int j=0; j<dim; j++) {
1162
        site_blocks[j][p] = (double) Math.floor(site_blocks[j][p]+0.5);
1163
      }
1164
      pnum = (s_num*dim-1)/dim + 2;
1165
      search(root, root_bn, retp, retp_bn);
1166
      make_facets(retp[0], retp_bn[0], ret2p, ret2p_bn);
1167
      connect(ret2p[0], ret2p_bn[0]);
1168
    }
1169

    
1170
    a3size = rdim*nrs;
1171
    a3s = new int[rdim][a3size+MAXDIM+1];
1172
    visit_triang_gen(root, root_bn, 1, retp, retp_bn);
1173
    visit_triang_gen(retp[0], retp_bn[0], 0, voidp, voidp_bn);
1174

    
1175
    // deallocate memory
1176
    /* NOTE: If this deallocation is not performed, more points
1177
       could theoretically be added to the triangulation later */
1178
    site_blocks = null;
1179
    st = null;
1180
    st_bn = null;
1181
    st2 = null;
1182
    st2_bn = null;
1183
    sbt_next = null;
1184
    sbt_next_bn = null;
1185
    sbt_visit = null;
1186
    sbt_mark = null;
1187
    sbt_normal = null;
1188
    sbt_normal_bn = null;
1189
    sbt_peak_vert = null;
1190
    sbt_peak_simp = null;
1191
    sbt_peak_simp_bn = null;
1192
    sbt_peak_basis = null;
1193
    sbt_peak_basis_bn = null;
1194
    sbt_neigh_vert = null;
1195
    sbt_neigh_simp = null;
1196
    sbt_neigh_simp_bn = null;
1197
    sbt_neigh_basis = null;
1198
    sbt_neigh_basis_bn = null;
1199
    bbt_next = null;
1200
    bbt_next_bn = null;
1201
    bbt_ref_count = null;
1202
    bbt_lscale = null;
1203
    bbt_sqa = null;
1204
    bbt_sqb = null;
1205
    bbt_vecs = null;
1206

    
1207
/* ********** END OF CONVERTED HULL CODE ********** */
1208
/*          (but still inside constructor)          */
1209

    
1210
    // compute number of triangles or tetrahedra
1211
    int[] nverts = new int[nrs];
1212
    for (int i=0; i<nrs; i++) nverts[i] = 0;
1213
    int ntris = 0;
1214
    boolean positive;
1215
    for (int i=0; i<nts; i++) {
1216
      positive = true;
1217
      for (int j=0; j<rdim; j++) {
1218
        if (a3s[j][i] < 0) positive = false;
1219
      }
1220
      if (positive) {
1221
        ntris++;
1222
        for (int j=0; j<rdim; j++) nverts[a3s[j][i]]++;
1223
      }
1224
    }
1225
    Vertices = new int[nrs][];
1226
    for (int i=0; i<nrs; i++) Vertices[i] = new int[nverts[i]];
1227
    for (int i=0; i<nrs; i++) nverts[i] = 0;
1228

    
1229
    // build Tri & Vertices components
1230
    Tri = new int[ntris][rdim];
1231
    int a, b, c, d;
1232
    int itri = 0;
1233
    for (int i=0; i<nts; i++) {
1234
      positive = true;
1235
      for (int j=0; j<rdim; j++) {
1236
        if (a3s[j][i] < 0) positive = false;
1237
      }
1238
      if (positive) {
1239
        for (int j=0; j<rdim; j++) {
1240
          Vertices[a3s[j][i]][nverts[a3s[j][i]]++] = itri;
1241
          Tri[itri][j] = a3s[j][i];
1242
        }
1243
        itri++;
1244
      }
1245
    }
1246

    
1247
    // Deallocate remaining helper information
1248
    a3s = null;
1249

    
1250
    // call more generic method for constructing Walk and Edges arrays
1251
    finish_triang(samples);
1252
  }
1253

    
1254
}
1255