geompack.C
Go to the documentation of this file.
1 # include <cstdlib>
2 # include <iostream>
3 # include <iomanip>
4 # include <fstream>
5 # include <cmath>
6 # include <ctime>
7 # include <cstring>
8 
9 #if defined(__APPLE__) && defined(__clang__)
10 #pragma clang fp exceptions(ignore)
11 #endif
12 
13 using namespace std;
14 
15 # include "geompack.H"
16 
17 //******************************************************************************
18 
19 double d_epsilon ( void )
20 
21 //******************************************************************************
22 //
23 // Purpose:
24 //
25 // D_EPSILON returns the round off unit for double precision arithmetic.
26 //
27 // Discussion:
28 //
29 // D_EPSILON is a number R which is a power of 2 with the property that,
30 // to the precision of the computer's arithmetic,
31 // 1 < 1 + R
32 // but
33 // 1 = ( 1 + R / 2 )
34 //
35 // Modified:
36 //
37 // 06 May 2003
38 //
39 // Author:
40 //
41 // John Burkardt
42 //
43 // Parameters:
44 //
45 // Output, double D_EPSILON, the floating point round-off unit.
46 //
47 {
48  double r = 1.0;
49 
50  while (1.0 < 1.0 + r)
51  {
52  r = r/2.0;
53  }
54 
55  return 2.0*r;
56 }
57 
58 
59 //*********************************************************************
60 
61 double d_max ( double x, double y )
62 
63 //*********************************************************************
64 //
65 // Purpose:
66 //
67 // D_MAX returns the maximum of two real values.
68 //
69 // Modified:
70 //
71 // 10 January 2002
72 //
73 // Author:
74 //
75 // John Burkardt
76 //
77 // Parameters:
78 //
79 // Input, double X, Y, the quantities to compare.
80 //
81 // Output, double D_MAX, the maximum of X and Y.
82 //
83 {
84  if ( y < x )
85  {
86  return x;
87  }
88  else
89  {
90  return y;
91  }
92 }
93 //*********************************************************************
94 
95 double d_min ( double x, double y )
96 
97 //*********************************************************************
98 //
99 // Purpose:
100 //
101 // D_MIN returns the minimum of two real values.
102 //
103 // Modified:
104 //
105 // 09 May 2003
106 //
107 // Author:
108 //
109 // John Burkardt
110 //
111 // Parameters:
112 //
113 // Input, double X, Y, the quantities to compare.
114 //
115 // Output, double D_MIN, the minimum of X and Y.
116 //
117 {
118  if ( y < x )
119  {
120  return y;
121  }
122  else
123  {
124  return x;
125  }
126 }
127 //******************************************************************************
128 
129 void d2vec_part_quick_a ( int n, double a[], int *l, int *r )
130 
131 //******************************************************************************
132 //
133 // Purpose:
134 //
135 // D2VEC_PART_QUICK_A reorders an R2 vector as part of a quick sort.
136 //
137 // Discussion:
138 //
139 // The routine reorders the entries of A. Using A(1:2,1) as a
140 // key, all entries of A that are less than or equal to the key will
141 // precede the key, which precedes all entries that are greater than the key.
142 //
143 // Example:
144 //
145 // Input:
146 //
147 // N = 8
148 //
149 // A = ( (2,4), (8,8), (6,2), (0,2), (10,6), (10,0), (0,6), (4,8) )
150 //
151 // Output:
152 //
153 // L = 2, R = 4
154 //
155 // A = ( (0,2), (0,6), (2,4), (8,8), (6,2), (10,6), (10,0), (4,8) )
156 // ----------- ----------------------------------
157 // LEFT KEY RIGHT
158 //
159 // Modified:
160 //
161 // 01 September 2003
162 //
163 // Author:
164 //
165 // John Burkardt
166 //
167 // Parameters:
168 //
169 // Input, int N, the number of entries of A.
170 //
171 // Input/output, double A[N*2]. On input, the array to be checked.
172 // On output, A has been reordered as described above.
173 //
174 // Output, int *L, *R, the indices of A that define the three segments.
175 // Let KEY = the input value of A(1:2,1). Then
176 // I <= L A(1:2,I) < KEY;
177 // L < I < R A(1:2,I) = KEY;
178 // R <= I A(1:2,I) > KEY.
179 //
180 {
181  int i;
182  int j;
183  double key[2];
184  int ll;
185  int m;
186  int rr;
187 
188  if ( n < 1 )
189  {
190  cout << "\n";
191  cout << "D2VEC_PART_QUICK_A - Fatal error!\n";
192  cout << " N < 1.\n";
193  exit ( 1 );
194  }
195 
196  if ( n == 1 )
197  {
198  *l = 0;
199  *r = 2;
200  return;
201  }
202 
203  key[0] = a[2*0+0];
204  key[1] = a[2*0+1];
205  m = 1;
206 //
207 // The elements of unknown size have indices between L+1 and R-1.
208 //
209  ll = 1;
210  rr = n + 1;
211 
212  for ( i = 2; i <= n; i++ )
213  {
214  if ( dvec_gt ( 2, a+2*ll, key ) )
215  {
216  rr = rr - 1;
217  dvec_swap ( 2, a+2*(rr-1), a+2*ll );
218  }
219  else if ( dvec_eq ( 2, a+2*ll, key ) )
220  {
221  m = m + 1;
222  dvec_swap ( 2, a+2*(m-1), a+2*ll );
223  ll = ll + 1;
224  }
225  else if ( dvec_lt ( 2, a+2*ll, key ) )
226  {
227  ll = ll + 1;
228  }
229 
230  }
231 //
232 // Now shift small elements to the left, and KEY elements to center.
233 //
234  for ( i = 0; i < ll - m; i++ )
235  {
236  for ( j = 0; j < 2; j++ )
237  {
238  a[2*i+j] = a[2*(i+m)+j];
239  }
240  }
241 
242  ll = ll - m;
243 
244  for ( i = ll; i < ll+m; i++ )
245  {
246  for ( j = 0; j < 2; j++ )
247  {
248  a[2*i+j] = key[j];
249  }
250  }
251 
252  *l = ll;
253  *r = rr;
254 
255  return;
256 }
257 //******************************************************************************
258 
259 void d2vec_permute ( int n, double a[], int p[] )
260 
261 //******************************************************************************
262 //
263 // Purpose:
264 //
265 // D2VEC_PERMUTE permutes an R2 vector in place.
266 //
267 // Discussion:
268 //
269 // This routine permutes an array of real "objects", but the same
270 // logic can be used to permute an array of objects of any arithmetic
271 // type, or an array of objects of any complexity. The only temporary
272 // storage required is enough to store a single object. The number
273 // of data movements made is N + the number of cycles of order 2 or more,
274 // which is never more than N + N/2.
275 //
276 // Example:
277 //
278 // Input:
279 //
280 // N = 5
281 // P = ( 2, 4, 5, 1, 3 )
282 // A = ( 1.0, 2.0, 3.0, 4.0, 5.0 )
283 // (11.0, 22.0, 33.0, 44.0, 55.0 )
284 //
285 // Output:
286 //
287 // A = ( 2.0, 4.0, 5.0, 1.0, 3.0 )
288 // ( 22.0, 44.0, 55.0, 11.0, 33.0 ).
289 //
290 // Modified:
291 //
292 // 19 February 2004
293 //
294 // Author:
295 //
296 // John Burkardt
297 //
298 // Parameters:
299 //
300 // Input, int N, the number of objects.
301 //
302 // Input/output, double A[2*N], the array to be permuted.
303 //
304 // Input, int P[N], the permutation. P(I) = J means
305 // that the I-th element of the output array should be the J-th
306 // element of the input array. P must be a legal permutation
307 // of the integers from 1 to N, otherwise the algorithm will
308 // fail catastrophically.
309 //
310 {
311  double a_temp[2];
312  int i;
313  int iget;
314  int iput;
315  int istart;
316 
317  if ( !perm_check ( n, p ) )
318  {
319  cout << "\n";
320  cout << "D2VEC_PERMUTE - Fatal error!\n";
321  cout << " The input array does not represent\n";
322  cout << " a proper permutation.\n";
323  exit ( 1 );
324  }
325 //
326 // Search for the next element of the permutation that has not been used.
327 //
328  for ( istart = 1; istart <= n; istart++ )
329  {
330  if ( p[istart-1] < 0 )
331  {
332  continue;
333  }
334  else if ( p[istart-1] == istart )
335  {
336  p[istart-1] = -p[istart-1];
337  continue;
338  }
339  else
340  {
341  a_temp[0] = a[0+(istart-1)*2];
342  a_temp[1] = a[1+(istart-1)*2];
343  iget = istart;
344 //
345 // Copy the new value into the vacated entry.
346 //
347  for ( ; ; )
348  {
349  iput = iget;
350  iget = p[iget-1];
351 
352  p[iput-1] = -p[iput-1];
353 
354  if ( iget < 1 || n < iget )
355  {
356  cout << "\n";
357  cout << "D2VEC_PERMUTE - Fatal error!\n";
358  exit ( 1 );
359  }
360 
361  if ( iget == istart )
362  {
363  a[0+(iput-1)*2] = a_temp[0];
364  a[1+(iput-1)*2] = a_temp[1];
365  break;
366  }
367  a[0+(iput-1)*2] = a[0+(iget-1)*2];
368  a[1+(iput-1)*2] = a[1+(iget-1)*2];
369  }
370  }
371  }
372 //
373 // Restore the signs of the entries.
374 //
375  for ( i = 0; i < n; i++ )
376  {
377  p[i] = -p[i];
378  }
379 
380  return;
381 }
382 //******************************************************************************
383 
384 int *d2vec_sort_heap_index_a ( int n, double a[] )
385 
386 //******************************************************************************
387 //
388 // Purpose:
389 //
390 // D2VEC_SORT_HEAP_INDEX_A does an indexed heap ascending sort of
391 // an R2 vector.
392 //
393 // Discussion:
394 //
395 // The sorting is not actually carried out. Rather an index array is
396 // created which defines the sorting. This array may be used to sort
397 // or index the array, or to sort or index related arrays keyed on the
398 // original array.
399 //
400 // Once the index array is computed, the sorting can be carried out
401 // "implicitly:
402 //
403 // A(1:2,INDX(I)), I = 1 to N is sorted,
404 //
405 // or explicitly, by the call
406 //
407 // call D2VEC_PERMUTE ( N, A, INDX )
408 //
409 // after which A(1:2,I), I = 1 to N is sorted.
410 //
411 // Modified:
412 //
413 // 13 January 2004
414 //
415 // Author:
416 //
417 // John Burkardt
418 //
419 // Parameters:
420 //
421 // Input, int N, the number of entries in the array.
422 //
423 // Input, double A[2*N], an array to be index-sorted.
424 //
425 // Output, int D2VEC_SORT_HEAP_INDEX_A[N], the sort index. The
426 // I-th element of the sorted array is A(0:1,D2VEC_SORT_HEAP_INDEX_A(I-1)).
427 //
428 {
429  double aval[2];
430  int i;
431  int *indx;
432  int indxt;
433  int ir;
434  int j;
435  int l;
436 
437  if ( n < 1 )
438  {
439  return NULL;
440  }
441 
442  if ( n == 1 )
443  {
444  indx = new int[1];
445  indx[0] = 1;
446  return indx;
447  }
448 
449  indx = ivec_indicator ( n );
450 
451  l = n / 2 + 1;
452  ir = n;
453 
454  for ( ; ; )
455  {
456  if ( 1 < l )
457  {
458  l = l - 1;
459  indxt = indx[l-1];
460  aval[0] = a[0+(indxt-1)*2];
461  aval[1] = a[1+(indxt-1)*2];
462  }
463  else
464  {
465  indxt = indx[ir-1];
466  aval[0] = a[0+(indxt-1)*2];
467  aval[1] = a[1+(indxt-1)*2];
468  indx[ir-1] = indx[0];
469  ir = ir - 1;
470 
471  if ( ir == 1 )
472  {
473  indx[0] = indxt;
474  break;
475  }
476 
477  }
478 
479  i = l;
480  j = l + l;
481 
482  while ( j <= ir )
483  {
484  if ( j < ir )
485  {
486  if ( a[0+(indx[j-1]-1)*2] < a[0+(indx[j]-1)*2] ||
487  ( a[0+(indx[j-1]-1)*2] == a[0+(indx[j]-1)*2] &&
488  a[1+(indx[j-1]-1)*2] < a[1+(indx[j]-1)*2] ) )
489  {
490  j = j + 1;
491  }
492  }
493 
494  if ( aval[0] < a[0+(indx[j-1]-1)*2] ||
495  ( aval[0] == a[0+(indx[j-1]-1)*2] &&
496  aval[1] < a[1+(indx[j-1]-1)*2] ) )
497  {
498  indx[i-1] = indx[j-1];
499  i = j;
500  j = j + j;
501  }
502  else
503  {
504  j = ir + 1;
505  }
506  }
507  indx[i-1] = indxt;
508  }
509 
510  return indx;
511 }
512 //*****************************************************************************
513 
514 void d2vec_sort_quick_a ( int n, double a[] )
515 
516 //*****************************************************************************
517 //
518 // Purpose:
519 //
520 // D2VEC_SORT_QUICK_A ascending sorts an R2 vector using quick sort.
521 //
522 // Discussion:
523 //
524 // The data structure is a set of N pairs of real numbers.
525 // These values are stored in a one dimensional array, by pairs.
526 //
527 // Modified:
528 //
529 // 01 September 2003
530 //
531 // Author:
532 //
533 // John Burkardt
534 //
535 // Parameters:
536 //
537 // Input, int N, the number of entries in the array.
538 //
539 // Input/output, double A[N*2].
540 // On input, the array to be sorted.
541 // On output, the array has been sorted.
542 //
543 {
544 # define LEVEL_MAX 25
545 
546  int base;
547  int l_segment;
548  int level;
549  int n_segment;
550  int rsave[LEVEL_MAX];
551  int r_segment;
552 
553  if ( n < 1 )
554  {
555  cout << "\n";
556  cout << "D2VEC_SORT_QUICK_A - Fatal error!\n";
557  cout << " N < 1.\n";
558  exit ( 1 );
559  }
560 
561  if ( n == 1 )
562  {
563  return;
564  }
565 
566  level = 1;
567  rsave[level-1] = n + 1;
568  base = 1;
569  n_segment = n;
570 
571  while ( 0 < n_segment )
572  {
573 //
574 // Partition the segment.
575 //
576  d2vec_part_quick_a ( n_segment, a+2*(base-1)+0, &l_segment, &r_segment );
577 //
578 // If the left segment has more than one element, we need to partition it.
579 //
580  if ( 1 < l_segment )
581  {
582  if ( LEVEL_MAX < level )
583  {
584  cout << "\n";
585  cout << "D2VEC_SORT_QUICK_A - Fatal error!\n";
586  cout << " Exceeding recursion maximum of " << LEVEL_MAX << "\n";
587  exit ( 1 );
588  }
589 
590  level = level + 1;
591  n_segment = l_segment;
592  rsave[level-1] = r_segment + base - 1;
593  }
594 //
595 // The left segment and the middle segment are sorted.
596 // Must the right segment be partitioned?
597 //
598  else if ( r_segment < n_segment )
599  {
600  n_segment = n_segment + 1 - r_segment;
601  base = base + r_segment - 1;
602  }
603 //
604 // Otherwise, we back up a level if there is an earlier one.
605 //
606  else
607  {
608  for ( ; ; )
609  {
610  if ( level <= 1 )
611  {
612  n_segment = 0;
613  break;
614  }
615 
616  base = rsave[level-1];
617  n_segment = rsave[level-2] - rsave[level-1];
618  level = level - 1;
619 
620  if ( 0 < n_segment )
621  {
622  break;
623  }
624  }
625  }
626  }
627  return;
628 # undef LEVEL_MAX
629 }
630 //******************************************************************************
631 
632 int diaedg ( double x0, double y0, double x1, double y1, double x2, double y2,
633  double x3, double y3 )
634 
635 //******************************************************************************
636 //
637 // Purpose:
638 //
639 // DIAEDG chooses a diagonal edge.
640 //
641 // Discussion:
642 //
643 // The routine determines whether 0--2 or 1--3 is the diagonal edge
644 // that should be chosen, based on the circumcircle criterion, where
645 // (X0,Y0), (X1,Y1), (X2,Y2), (X3,Y3) are the vertices of a simple
646 // quadrilateral in counterclockwise order.
647 //
648 // Modified:
649 //
650 // 28 August 2003
651 //
652 // Author:
653 //
654 // Barry Joe,
655 // Department of Computing Science,
656 // University of Alberta,
657 // Edmonton, Alberta, Canada T6G 2H1
658 //
659 // Reference:
660 //
661 // Barry Joe,
662 // GEOMPACK - a software package for the generation of meshes
663 // using geometric algorithms,
664 // Advances in Engineering Software,
665 // Volume 13, pages 325-331, 1991.
666 //
667 // Parameters:
668 //
669 // Input, double X0, Y0, X1, Y1, X2, Y2, X3, Y3, the coordinates of the
670 // vertices of a quadrilateral, given in counter clockwise order.
671 //
672 // Output, int DIAEDG, chooses a diagonal:
673 // +1, if diagonal edge 02 is chosen;
674 // -1, if diagonal edge 13 is chosen;
675 // 0, if the four vertices are cocircular.
676 //
677 {
678  double ca;
679  double cb;
680  double dx10;
681  double dx12;
682  double dx30;
683  double dx32;
684  double dy10;
685  double dy12;
686  double dy30;
687  double dy32;
688  double s;
689  double tol;
690  double tola;
691  double tolb;
692  int value;
693 
694  tol = 100.0 * d_epsilon ( );
695 
696  dx10 = x1 - x0;
697  dy10 = y1 - y0;
698  dx12 = x1 - x2;
699  dy12 = y1 - y2;
700  dx30 = x3 - x0;
701  dy30 = y3 - y0;
702  dx32 = x3 - x2;
703  dy32 = y3 - y2;
704 
705  tola = tol * d_max ( fabs ( dx10 ),
706  d_max ( fabs ( dy10 ),
707  d_max ( fabs ( dx30 ), fabs ( dy30 ) ) ) );
708 
709  tolb = tol * d_max ( fabs ( dx12 ),
710  d_max ( fabs ( dy12 ),
711  d_max ( fabs ( dx32 ), fabs ( dy32 ) ) ) );
712 
713  ca = dx10 * dx30 + dy10 * dy30;
714  cb = dx12 * dx32 + dy12 * dy32;
715 
716  if ( tola < ca && tolb < cb )
717  {
718  value = -1;
719  }
720  else if ( ca < -tola && cb < -tolb )
721  {
722  value = 1;
723  }
724  else
725  {
726  tola = d_max ( tola, tolb );
727  s = ( dx10 * dy30 - dx30 * dy10 ) * cb
728  + ( dx32 * dy12 - dx12 * dy32 ) * ca;
729 
730  if ( tola < s )
731  {
732  value = -1;
733  }
734  else if ( s < -tola )
735  {
736  value = 1;
737  }
738  else
739  {
740  value = 0;
741  }
742 
743  }
744 
745  return value;
746 }
747 //******************************************************************************
748 
749 void dmat_transpose_print ( int m, int n, double a[], const char *title )
750 
751 //******************************************************************************
752 //
753 // Purpose:
754 //
755 // DMAT_TRANSPOSE_PRINT prints a real matrix, transposed.
756 //
757 // Modified:
758 //
759 // 11 August 2004
760 //
761 // Author:
762 //
763 // John Burkardt
764 //
765 // Parameters:
766 //
767 // Input, int M, N, the number of rows and columns.
768 //
769 // Input, double A[M*N], an M by N matrix to be printed.
770 //
771 // Input, const char *TITLE, an optional title.
772 //
773 {
774  dmat_transpose_print_some ( m, n, a, 1, 1, m, n, title );
775 
776  return;
777 }
778 //******************************************************************************
779 
780 void dmat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo,
781  int ihi, int jhi, const char *title )
782 
783 //******************************************************************************
784 //
785 // Purpose:
786 //
787 // DMAT_TRANSPOSE_PRINT_SOME prints some of a real matrix, transposed.
788 //
789 // Modified:
790 //
791 // 11 August 2004
792 //
793 // Author:
794 //
795 // John Burkardt
796 //
797 // Parameters:
798 //
799 // Input, int M, N, the number of rows and columns.
800 //
801 // Input, double A[M*N], an M by N matrix to be printed.
802 //
803 // Input, int ILO, JLO, the first row and column to print.
804 //
805 // Input, int IHI, JHI, the last row and column to print.
806 //
807 // Input, const char *TITLE, an optional title.
808 //
809 {
810 # define INCX 5
811 
812  int i;
813  int i2;
814  int i2hi;
815  int i2lo;
816  int inc;
817  int j;
818  int j2hi;
819  int j2lo;
820 
821  if ( 0 < s_len_trim ( title ) )
822  {
823  cout << "\n";
824  cout << title << "\n";
825  }
826 
827  for ( i2lo = i_max ( ilo, 1 ); i2lo <= i_min ( ihi, m ); i2lo = i2lo + INCX )
828  {
829  i2hi = i2lo + INCX - 1;
830  i2hi = i_min ( i2hi, m );
831  i2hi = i_min ( i2hi, ihi );
832 
833  inc = i2hi + 1 - i2lo;
834 
835  cout << "\n";
836  cout << " Row: ";
837  for ( i = i2lo; i <= i2hi; i++ )
838  {
839  cout << setw(7) << i << " ";
840  }
841  cout << "\n";
842  cout << " Col\n";
843  cout << "\n";
844 
845  j2lo = i_max ( jlo, 1 );
846  j2hi = i_min ( jhi, n );
847 
848  for ( j = j2lo; j <= j2hi; j++ )
849  {
850  cout << setw(5) << j << " ";
851  for ( i2 = 1; i2 <= inc; i2++ )
852  {
853  i = i2lo - 1 + i2;
854  cout << setw(14) << a[(i-1)+(j-1)*m];
855  }
856  cout << "\n";
857  }
858  }
859  cout << "\n";
860 
861  return;
862 # undef INCX
863 }
864 //******************************************************************************
865 
866 void dmat_uniform ( int m, int n, double b, double c, int *seed, double r[] )
867 
868 //******************************************************************************
869 //
870 // Purpose:
871 //
872 // DMAT_UNIFORM fills a double precision array with scaled
873 // pseudorandom values.
874 //
875 // Discussion:
876 //
877 // This routine implements the recursion
878 //
879 // seed = 16807 * seed mod ( 2**31 - 1 )
880 // unif = seed / ( 2**31 - 1 )
881 //
882 // The integer arithmetic never requires more than 32 bits,
883 // including a sign bit.
884 //
885 // Modified:
886 //
887 // 30 January 2005
888 //
889 // Author:
890 //
891 // John Burkardt
892 //
893 // Reference:
894 //
895 // Paul Bratley, Bennett Fox, Linus Schrage,
896 // A Guide to Simulation,
897 // Springer Verlag, pages 201-202, 1983.
898 //
899 // Bennett Fox,
900 // Algorithm 647:
901 // Implementation and Relative Efficiency of Quasirandom
902 // Sequence Generators,
903 // ACM Transactions on Mathematical Software,
904 // Volume 12, Number 4, pages 362-376, 1986.
905 //
906 // Peter Lewis, Allen Goodman, James Miller,
907 // A Pseudo-Random Number Generator for the System/360,
908 // IBM Systems Journal,
909 // Volume 8, pages 136-143, 1969.
910 //
911 // Parameters:
912 //
913 // Input, int M, N, the number of rows and columns.
914 //
915 // Input, double B, C, the limits of the pseudorandom values.
916 //
917 // Input/output, int *SEED, the "seed" value. Normally, this
918 // value should not be 0, otherwise the output value of SEED
919 // will still be 0, and D_UNIFORM will be 0. On output, SEED has
920 // been updated.
921 //
922 // Output, double DMAT_UNIFORM[M*N], a matrix of pseudorandom values.
923 //
924 {
925  int i;
926  int j;
927  int k;
928 
929  for ( j = 0; j < n; j++ )
930  {
931  for ( i = 0; i < m; i++ )
932  {
933  k = *seed / 127773;
934 
935  *seed = 16807 * ( *seed - k * 127773 ) - k * 2836;
936 
937  if ( *seed < 0 )
938  {
939  *seed = *seed + 2147483647;
940  }
941 //
942 // Although SEED can be represented exactly as a 32 bit integer,
943 // it generally cannot be represented exactly as a 32 bit real number!
944 //
945  r[i+j*m] = b + ( c - b ) * double( *seed ) * 4.656612875E-10;
946  }
947  }
948 
949  return;
950 }
951 //******************************************************************************
952 
953 int dtris2 ( int point_num, double point_xy[], int *tri_num,
954  int tri_vert[], int tri_nabe[] )
955 
956 //******************************************************************************
957 //
958 // Purpose:
959 //
960 // DTRIS2 constructs a Delaunay triangulation of 2D vertices.
961 //
962 // Discussion:
963 //
964 // The routine constructs the Delaunay triangulation of a set of 2D vertices
965 // using an incremental approach and diagonal edge swaps. Vertices are
966 // first sorted in lexicographically increasing (X,Y) order, and
967 // then are inserted one at a time from outside the convex hull.
968 //
969 // Modified:
970 //
971 // 15 January 2004
972 //
973 // Author:
974 //
975 // Barry Joe,
976 // Department of Computing Science,
977 // University of Alberta,
978 // Edmonton, Alberta, Canada T6G 2H1
979 //
980 // Reference:
981 //
982 // Barry Joe,
983 // GEOMPACK - a software package for the generation of meshes
984 // using geometric algorithms,
985 // Advances in Engineering Software,
986 // Volume 13, pages 325-331, 1991.
987 //
988 // Parameters:
989 //
990 // Input, int POINT_NUM, the number of vertices.
991 //
992 // Input/output, double POINT_XY[POINT_NUM*2], the coordinates of
993 // the vertices. On output, the vertices have been sorted into
994 // dictionary order.
995 //
996 // Output, int *TRI_NUM, the number of triangles in the triangulation;
997 // TRI_NUM is equal to 2*POINT_NUM - NB - 2, where NB is the number
998 // of boundary vertices.
999 //
1000 // Output, int TRI_VERT[TRI_NUM*3], the nodes that make up each triangle.
1001 // The elements are indices of POINT_XY. The vertices of the triangles are
1002 // in counter clockwise order.
1003 //
1004 // Output, int TRI_NABE[TRI_NUM*3], the triangle neighbor list.
1005 // Positive elements are indices of TIL; negative elements are used for links
1006 // of a counter clockwise linked list of boundary edges; LINK = -(3*I + J-1)
1007 // where I, J = triangle, edge index; TRI_NABE[I,J] refers to
1008 // the neighbor along edge from vertex J to J+1 (mod 3).
1009 //
1010 // Output, int DTRIS2, is 0 for no error.
1011 {
1012  double cmax;
1013  int e;
1014  int error;
1015  int i;
1016  int *indx;
1017  int j;
1018  int k;
1019  int l;
1020  int ledg;
1021  int lr;
1022  int ltri;
1023  int m;
1024  int m1;
1025  int m2;
1026  int n;
1027  int redg;
1028  int rtri;
1029  int *stack;
1030  int t;
1031  double tol;
1032  int top;
1033 
1034  stack = new int[point_num];
1035 
1036  tol = 100.0 * d_epsilon ( );
1037 //
1038 // Sort the vertices by increasing (x,y).
1039 //
1040  indx = d2vec_sort_heap_index_a ( point_num, point_xy );
1041 
1042  d2vec_permute ( point_num, point_xy, indx );
1043 //
1044 // Make sure that the data points are "reasonably" distinct.
1045 //
1046  m1 = 1;
1047 
1048  for ( i = 2; i <= point_num; i++ )
1049  {
1050  m = m1;
1051  m1 = i;
1052 
1053  k = -1;
1054 
1055  for ( j = 0; j <= 1; j++ )
1056  {
1057  cmax = d_max ( fabs ( point_xy[2*(m-1)+j] ),
1058  fabs ( point_xy[2*(m1-1)+j] ) );
1059 
1060  if ( tol * ( cmax + 1.0 )
1061  < fabs ( point_xy[2*(m-1)+j] - point_xy[2*(m1-1)+j] ) )
1062  {
1063  k = j;
1064  break;
1065  }
1066 
1067  }
1068 
1069  if ( k == -1 )
1070  {
1071  cout << "\n";
1072  cout << "DTRIS2 - Fatal error!\n";
1073  cout << " Fails for point number I = " << i << "\n";
1074  cout << " M = " << m << "\n";
1075  cout << " M1 = " << m1 << "\n";
1076  cout << " X,Y(M) = " << point_xy[2*(m-1)+0] << " "
1077  << point_xy[2*(m-1)+1] << "\n";
1078  cout << " X,Y(M1) = " << point_xy[2*(m1-1)+0] << " "
1079  << point_xy[2*(m1-1)+1] << "\n";
1080  delete [] stack;
1081  return 224;
1082  }
1083 
1084  }
1085 //
1086 // Starting from points M1 and M2, search for a third point M that
1087 // makes a "healthy" triangle (M1,M2,M)
1088 //
1089  m1 = 1;
1090  m2 = 2;
1091  j = 3;
1092 
1093  for ( ; ; )
1094  {
1095  if ( point_num < j )
1096  {
1097  cout << "\n";
1098  cout << "DTRIS2 - Fatal error!\n";
1099  delete [] stack;
1100  return 225;
1101  }
1102 
1103  m = j;
1104 
1105  lr = lrline ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1],
1106  point_xy[2*(m1-1)+0], point_xy[2*(m1-1)+1],
1107  point_xy[2*(m2-1)+0], point_xy[2*(m2-1)+1], 0.0 );
1108 
1109  if ( lr != 0 )
1110  {
1111  break;
1112  }
1113 
1114  j = j + 1;
1115 
1116  }
1117 //
1118 // Set up the triangle information for (M1,M2,M), and for any other
1119 // triangles you created because points were collinear with M1, M2.
1120 //
1121  *tri_num = j - 2;
1122 
1123  if ( lr == -1 )
1124  {
1125  tri_vert[3*0+0] = m1;
1126  tri_vert[3*0+1] = m2;
1127  tri_vert[3*0+2] = m;
1128  tri_nabe[3*0+2] = -3;
1129 
1130  for ( i = 2; i <= *tri_num; i++ )
1131  {
1132  m1 = m2;
1133  m2 = i+1;
1134  tri_vert[3*(i-1)+0] = m1;
1135  tri_vert[3*(i-1)+1] = m2;
1136  tri_vert[3*(i-1)+2] = m;
1137  tri_nabe[3*(i-2)+0] = -3 * i;
1138  tri_nabe[3*(i-2)+1] = i;
1139  tri_nabe[3*(i-1)+2] = i - 1;
1140 
1141  }
1142 
1143  tri_nabe[3*(*tri_num-1)+0] = -3 * (*tri_num) - 1;
1144  tri_nabe[3*(*tri_num-1)+1] = -5;
1145  ledg = 2;
1146  ltri = *tri_num;
1147  }
1148  else
1149  {
1150  tri_vert[3*0+0] = m2;
1151  tri_vert[3*0+1] = m1;
1152  tri_vert[3*0+2] = m;
1153  tri_nabe[3*0+0] = -4;
1154 
1155  for ( i = 2; i <= *tri_num; i++ )
1156  {
1157  m1 = m2;
1158  m2 = i+1;
1159  tri_vert[3*(i-1)+0] = m2;
1160  tri_vert[3*(i-1)+1] = m1;
1161  tri_vert[3*(i-1)+2] = m;
1162  tri_nabe[3*(i-2)+2] = i;
1163  tri_nabe[3*(i-1)+0] = -3 * i - 3;
1164  tri_nabe[3*(i-1)+1] = i - 1;
1165  }
1166 
1167  tri_nabe[3*(*tri_num-1)+2] = -3 * (*tri_num);
1168  tri_nabe[3*0+1] = -3 * (*tri_num) - 2;
1169  ledg = 2;
1170  ltri = 1;
1171  }
1172 //
1173 // Insert the vertices one at a time from outside the convex hull,
1174 // determine visible boundary edges, and apply diagonal edge swaps until
1175 // Delaunay triangulation of vertices (so far) is obtained.
1176 //
1177  top = 0;
1178 
1179  for ( i = j+1; i <= point_num; i++ )
1180  {
1181  m = i;
1182  m1 = tri_vert[3*(ltri-1)+ledg-1];
1183 
1184  if ( ledg <= 2 )
1185  {
1186  m2 = tri_vert[3*(ltri-1)+ledg];
1187  }
1188  else
1189  {
1190  m2 = tri_vert[3*(ltri-1)+0];
1191  }
1192 
1193  lr = lrline ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1],
1194  point_xy[2*(m1-1)+0], point_xy[2*(m1-1)+1],
1195  point_xy[2*(m2-1)+0], point_xy[2*(m2-1)+1], 0.0 );
1196 
1197  if ( 0 < lr )
1198  {
1199  rtri = ltri;
1200  redg = ledg;
1201  ltri = 0;
1202  }
1203  else
1204  {
1205  l = -tri_nabe[3*(ltri-1)+ledg-1];
1206  rtri = l / 3;
1207  redg = (l % 3) + 1;
1208  }
1209 
1210  vbedg ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1], point_num,
1211  point_xy, *tri_num, tri_vert, tri_nabe, &ltri, &ledg, &rtri, &redg );
1212 
1213  n = *tri_num + 1;
1214  l = -tri_nabe[3*(ltri-1)+ledg-1];
1215 
1216  for ( ; ; )
1217  {
1218  t = l / 3;
1219  e = ( l % 3 ) + 1;
1220  l = -tri_nabe[3*(t-1)+e-1];
1221  m2 = tri_vert[3*(t-1)+e-1];
1222 
1223  if ( e <= 2 )
1224  {
1225  m1 = tri_vert[3*(t-1)+e];
1226  }
1227  else
1228  {
1229  m1 = tri_vert[3*(t-1)+0];
1230  }
1231 
1232  *tri_num = *tri_num + 1;
1233  tri_nabe[3*(t-1)+e-1] = *tri_num;
1234  tri_vert[3*(*tri_num-1)+0] = m1;
1235  tri_vert[3*(*tri_num-1)+1] = m2;
1236  tri_vert[3*(*tri_num-1)+2] = m;
1237  tri_nabe[3*(*tri_num-1)+0] = t;
1238  tri_nabe[3*(*tri_num-1)+1] = *tri_num - 1;
1239  tri_nabe[3*(*tri_num-1)+2] = *tri_num + 1;
1240  top = top + 1;
1241 
1242  if ( point_num < top )
1243  {
1244  cout << "\n";
1245  cout << "DTRIS2 - Fatal error!\n";
1246  cout << " Stack overflow.\n";
1247  delete [] stack;
1248  return 8;
1249  }
1250 
1251  stack[top-1] = *tri_num;
1252 
1253  if ( t == rtri && e == redg )
1254  {
1255  break;
1256  }
1257 
1258  }
1259 
1260  tri_nabe[3*(ltri-1)+ledg-1] = -3 * n - 1;
1261  tri_nabe[3*(n-1)+1] = -3 * (*tri_num) - 2;
1262  tri_nabe[3*(*tri_num-1)+2] = -l;
1263  ltri = n;
1264  ledg = 2;
1265 
1266  error = swapec ( m, &top, &ltri, &ledg, point_num, point_xy, *tri_num,
1267  tri_vert, tri_nabe, stack );
1268 
1269  if ( error != 0 )
1270  {
1271  cout << "\n";
1272  cout << "DTRIS2 - Fatal error!\n";
1273  cout << " Error return from SWAPEC.\n";
1274  delete [] stack;
1275  return error;
1276  }
1277 
1278  }
1279 //
1280 // Now account for the sorting that we did.
1281 //
1282  for ( i = 0; i < 3; i++ )
1283  {
1284  for ( j = 0; j < *tri_num; j++ )
1285  {
1286  tri_vert[i+j*3] = indx [ tri_vert[i+j*3] - 1 ];
1287  }
1288  }
1289 
1290  perm_inv ( point_num, indx );
1291 
1292  d2vec_permute ( point_num, point_xy, indx );
1293 
1294  delete [] indx;
1295  delete [] stack;
1296 
1297  return 0;
1298 }
1299 //******************************************************************************
1300 
1301 bool dvec_eq ( int n, double a1[], double a2[] )
1302 
1303 //******************************************************************************
1304 //
1305 // Purpose:
1306 //
1307 // DVEC_EQ is true if every pair of entries in two vectors is equal.
1308 //
1309 // Modified:
1310 //
1311 // 28 August 2003
1312 //
1313 // Author:
1314 //
1315 // John Burkardt
1316 //
1317 // Parameters:
1318 //
1319 // Input, int N, the number of entries in the vectors.
1320 //
1321 // Input, double A1[N], A2[N], two vectors to compare.
1322 //
1323 // Output, bool DVEC_EQ.
1324 // DVEC_EQ is TRUE if every pair of elements A1(I) and A2(I) are equal,
1325 // and FALSE otherwise.
1326 //
1327 {
1328  int i;
1329 
1330  for ( i = 0; i < n; i++ )
1331  {
1332  if ( a1[i] != a2[i] )
1333  {
1334  return false;
1335  }
1336  }
1337  return true;
1338 
1339 }
1340 //******************************************************************************
1341 
1342 bool dvec_gt ( int n, double a1[], double a2[] )
1343 
1344 //******************************************************************************
1345 //
1346 // Purpose:
1347 //
1348 // DVEC_GT == ( A1 > A2 ) for real vectors.
1349 //
1350 // Discussion:
1351 //
1352 // The comparison is lexicographic.
1353 //
1354 // A1 > A2 <=> A1(1) > A2(1) or
1355 // ( A1(1) == A2(1) and A1(2) > A2(2) ) or
1356 // ...
1357 // ( A1(1:N-1) == A2(1:N-1) and A1(N) > A2(N)
1358 //
1359 // Modified:
1360 //
1361 // 28 August 2003
1362 //
1363 // Author:
1364 //
1365 // John Burkardt
1366 //
1367 // Parameters:
1368 //
1369 // Input, int N, the dimension of the vectors.
1370 //
1371 // Input, double A1[N], A2[N], the vectors to be compared.
1372 //
1373 // Output, bool DVEC_GT, is TRUE if and only if A1 > A2.
1374 //
1375 {
1376  int i;
1377 
1378  for ( i = 0; i < n; i++ )
1379  {
1380 
1381  if ( a2[i] < a1[i] )
1382  {
1383  return true;
1384  }
1385  else if ( a1[i] < a2[i] )
1386  {
1387  return false;
1388  }
1389 
1390  }
1391 
1392  return false;
1393 }
1394 //******************************************************************************
1395 
1396 bool dvec_lt ( int n, double a1[], double a2[] )
1397 
1398 //******************************************************************************
1399 //
1400 // Purpose:
1401 //
1402 // DVEC_LT == ( A1 < A2 ) for real vectors.
1403 //
1404 // Discussion:
1405 //
1406 // The comparison is lexicographic.
1407 //
1408 // A1 < A2 <=> A1(1) < A2(1) or
1409 // ( A1(1) == A2(1) and A1(2) < A2(2) ) or
1410 // ...
1411 // ( A1(1:N-1) == A2(1:N-1) and A1(N) < A2(N)
1412 //
1413 // Modified:
1414 //
1415 // 28 August 2003
1416 //
1417 // Author:
1418 //
1419 // John Burkardt
1420 //
1421 // Parameters:
1422 //
1423 // Input, int N, the dimension of the vectors.
1424 //
1425 // Input, double A1[N], A2[N], the vectors to be compared.
1426 //
1427 // Output, bool DVEC_LT, is TRUE if and only if A1 < A2.
1428 //
1429 {
1430  int i;
1431 
1432  for ( i = 0; i < n; i++ )
1433  {
1434  if ( a1[i] < a2[i] )
1435  {
1436  return true;
1437  }
1438  else if ( a2[i] < a1[i] )
1439  {
1440  return false;
1441  }
1442 
1443  }
1444 
1445  return false;
1446 }
1447 //********************************************************************
1448 
1449 void dvec_print ( int n, double a[], const char *title )
1450 
1451 //********************************************************************
1452 //
1453 // Purpose:
1454 //
1455 // DVEC_PRINT prints a double precision vector.
1456 //
1457 // Modified:
1458 //
1459 // 16 August 2004
1460 //
1461 // Author:
1462 //
1463 // John Burkardt
1464 //
1465 // Parameters:
1466 //
1467 // Input, int N, the number of components of the vector.
1468 //
1469 // Input, double A[N], the vector to be printed.
1470 //
1471 // Input, const char *TITLE, a title to be printed first.
1472 // TITLE may be blank.
1473 //
1474 {
1475  int i;
1476 
1477  if ( 0 < s_len_trim ( title ) )
1478  {
1479  cout << "\n";
1480  cout << title << "\n";
1481  }
1482 
1483  cout << "\n";
1484  for ( i = 0; i <= n-1; i++ )
1485  {
1486  cout << setw(6) << i + 1 << " "
1487  << setw(14) << a[i] << "\n";
1488  }
1489 
1490  return;
1491 }
1492 //******************************************************************************
1493 
1494 void dvec_swap ( int n, double a1[], double a2[] )
1495 
1496 //******************************************************************************
1497 //
1498 // Purpose:
1499 //
1500 // DVEC_SWAP swaps the entries of two real vectors.
1501 //
1502 // Modified:
1503 //
1504 // 28 August 2003
1505 //
1506 // Author:
1507 //
1508 // John Burkardt
1509 //
1510 // Parameters:
1511 //
1512 // Input, int N, the number of entries in the arrays.
1513 //
1514 // Input/output, double A1[N], A2[N], the vectors to swap.
1515 //
1516 {
1517  int i;
1518  double temp;
1519 
1520  for ( i = 0; i < n; i++ )
1521  {
1522  temp = a1[i];
1523  a1[i] = a2[i];
1524  a2[i] = temp;
1525  }
1526 
1527  return;
1528 }
1529 //****************************************************************************
1530 
1531 int i_max ( int i1, int i2 )
1532 
1533 //****************************************************************************
1534 //
1535 // Purpose:
1536 //
1537 // I_MAX returns the maximum of two integers.
1538 //
1539 // Modified:
1540 //
1541 // 13 October 1998
1542 //
1543 // Author:
1544 //
1545 // John Burkardt
1546 //
1547 // Parameters:
1548 //
1549 // Input, int I1, I2, are two integers to be compared.
1550 //
1551 // Output, int I_MAX, the larger of I1 and I2.
1552 //
1553 {
1554  if ( i2 < i1 )
1555  {
1556  return i1;
1557  }
1558  else
1559  {
1560  return i2;
1561  }
1562 
1563 }
1564 //****************************************************************************
1565 
1566 int i_min ( int i1, int i2 )
1567 
1568 //****************************************************************************
1569 //
1570 // Purpose:
1571 //
1572 // I_MIN returns the smaller of two integers.
1573 //
1574 // Modified:
1575 //
1576 // 13 October 1998
1577 //
1578 // Author:
1579 //
1580 // John Burkardt
1581 //
1582 // Parameters:
1583 //
1584 // Input, int I1, I2, two integers to be compared.
1585 //
1586 // Output, int I_MIN, the smaller of I1 and I2.
1587 //
1588 {
1589  if ( i1 < i2 )
1590  {
1591  return i1;
1592  }
1593  else
1594  {
1595  return i2;
1596  }
1597 
1598 }
1599 //*********************************************************************
1600 
1601 int i_modp ( int i, int j )
1602 
1603 //*********************************************************************
1604 //
1605 // Purpose:
1606 //
1607 // I_MODP returns the nonnegative remainder of integer division.
1608 //
1609 // Formula:
1610 //
1611 // If
1612 // NREM = I_MODP ( I, J )
1613 // NMULT = ( I - NREM ) / J
1614 // then
1615 // I = J * NMULT + NREM
1616 // where NREM is always nonnegative.
1617 //
1618 // Comments:
1619 //
1620 // The MOD function computes a result with the same sign as the
1621 // quantity being divided. Thus, suppose you had an angle A,
1622 // and you wanted to ensure that it was between 0 and 360.
1623 // Then mod(A,360) would do, if A was positive, but if A
1624 // was negative, your result would be between -360 and 0.
1625 //
1626 // On the other hand, I_MODP(A,360) is between 0 and 360, always.
1627 //
1628 // Examples:
1629 //
1630 // I J MOD I_MODP I_MODP Factorization
1631 //
1632 // 107 50 7 7 107 = 2 * 50 + 7
1633 // 107 -50 7 7 107 = -2 * -50 + 7
1634 // -107 50 -7 43 -107 = -3 * 50 + 43
1635 // -107 -50 -7 43 -107 = 3 * -50 + 43
1636 //
1637 // Modified:
1638 //
1639 // 26 May 1999
1640 //
1641 // Author:
1642 //
1643 // John Burkardt
1644 //
1645 // Parameters:
1646 //
1647 // Input, int I, the number to be divided.
1648 //
1649 // Input, int J, the number that divides I.
1650 //
1651 // Output, int I_MODP, the nonnegative remainder when I is
1652 // divided by J.
1653 //
1654 {
1655  int value;
1656 
1657  if ( j == 0 )
1658  {
1659  cout << "\n";
1660  cout << "I_MODP - Fatal error!\n";
1661  cout << " I_MODP ( I, J ) called with J = " << j << "\n";
1662  exit ( 1 );
1663  }
1664 
1665  value = i % j;
1666 
1667  if ( value < 0 )
1668  {
1669  value = value + abs ( j );
1670  }
1671 
1672  return value;
1673 }
1674 //********************************************************************
1675 
1676 int i_sign ( int i )
1677 
1678 //********************************************************************
1679 //
1680 // Purpose:
1681 //
1682 // I_SIGN returns the sign of an integer.
1683 //
1684 // Discussion:
1685 //
1686 // The sign of 0 and all positive integers is taken to be +1.
1687 // The sign of all negative integers is -1.
1688 //
1689 // Modified:
1690 //
1691 // 06 May 2003
1692 //
1693 // Author:
1694 //
1695 // John Burkardt
1696 //
1697 // Parameters:
1698 //
1699 // Input, int I, the integer whose sign is desired.
1700 //
1701 // Output, int I_SIGN, the sign of I.
1702 {
1703  if ( i < 0 )
1704  {
1705  return (-1);
1706  }
1707  else
1708  {
1709  return 1;
1710  }
1711 
1712 }
1713 //******************************************************************************
1714 
1715 int i_wrap ( int ival, int ilo, int ihi )
1716 
1717 //******************************************************************************
1718 //
1719 // Purpose:
1720 //
1721 // I_WRAP forces an integer to lie between given limits by wrapping.
1722 //
1723 // Example:
1724 //
1725 // ILO = 4, IHI = 8
1726 //
1727 // I I_WRAP
1728 //
1729 // -2 8
1730 // -1 4
1731 // 0 5
1732 // 1 6
1733 // 2 7
1734 // 3 8
1735 // 4 4
1736 // 5 5
1737 // 6 6
1738 // 7 7
1739 // 8 8
1740 // 9 4
1741 // 10 5
1742 // 11 6
1743 // 12 7
1744 // 13 8
1745 // 14 4
1746 //
1747 // Modified:
1748 //
1749 // 19 August 2003
1750 //
1751 // Author:
1752 //
1753 // John Burkardt
1754 //
1755 // Parameters:
1756 //
1757 // Input, int IVAL, an integer value.
1758 //
1759 // Input, int ILO, IHI, the desired bounds for the integer value.
1760 //
1761 // Output, int I_WRAP, a "wrapped" version of IVAL.
1762 //
1763 {
1764  int jhi;
1765  int jlo;
1766  int value;
1767  int wide;
1768 
1769  jlo = i_min ( ilo, ihi );
1770  jhi = i_max ( ilo, ihi );
1771 
1772  wide = jhi + 1 - jlo;
1773 
1774  if ( wide == 1 )
1775  {
1776  value = jlo;
1777  }
1778  else
1779  {
1780  value = jlo + i_modp ( ival - jlo, wide );
1781  }
1782 
1783  return value;
1784 }
1785 //******************************************************************************
1786 
1787 void imat_transpose_print ( int m, int n, int a[], const char *title )
1788 
1789 //******************************************************************************
1790 //
1791 // Purpose:
1792 //
1793 // IMAT_TRANSPOSE_PRINT prints an integer matrix, transposed.
1794 //
1795 // Modified:
1796 //
1797 // 31 January 2005
1798 //
1799 // Author:
1800 //
1801 // John Burkardt
1802 //
1803 // Parameters:
1804 //
1805 // Input, int M, the number of rows in A.
1806 //
1807 // Input, int N, the number of columns in A.
1808 //
1809 // Input, int A[M*N], the M by N matrix.
1810 //
1811 // Input, const char *TITLE, a title to be printed.
1812 //
1813 {
1814  imat_transpose_print_some ( m, n, a, 1, 1, m, n, title );
1815 
1816  return;
1817 }
1818 //******************************************************************************
1819 
1820 void imat_transpose_print_some ( int m, int n, int a[], int ilo, int jlo,
1821  int ihi, int jhi, const char *title )
1822 
1823 //******************************************************************************
1824 //
1825 // Purpose:
1826 //
1827 // IMAT_TRANSPOSE_PRINT_SOME prints some of an integer matrix, transposed.
1828 //
1829 // Modified:
1830 //
1831 // 09 February 2005
1832 //
1833 // Author:
1834 //
1835 // John Burkardt
1836 //
1837 // Parameters:
1838 //
1839 // Input, int M, the number of rows of the matrix.
1840 // M must be positive.
1841 //
1842 // Input, int N, the number of columns of the matrix.
1843 // N must be positive.
1844 //
1845 // Input, int A[M*N], the matrix.
1846 //
1847 // Input, int ILO, JLO, IHI, JHI, designate the first row and
1848 // column, and the last row and column to be printed.
1849 //
1850 // Input, const char *TITLE, a title for the matrix.
1851 {
1852 # define INCX 10
1853 
1854  int i;
1855  int i2hi;
1856  int i2lo;
1857  int j;
1858  int j2hi;
1859  int j2lo;
1860 
1861  if ( 0 < s_len_trim ( title ) )
1862  {
1863  cout << "\n";
1864  cout << title << "\n";
1865  }
1866 //
1867 // Print the columns of the matrix, in strips of INCX.
1868 //
1869  for ( i2lo = ilo; i2lo <= ihi; i2lo = i2lo + INCX )
1870  {
1871  i2hi = i2lo + INCX - 1;
1872  i2hi = i_min ( i2hi, m );
1873  i2hi = i_min ( i2hi, ihi );
1874 
1875  cout << "\n";
1876 //
1877 // For each row I in the current range...
1878 //
1879 // Write the header.
1880 //
1881  cout << " Row: ";
1882  for ( i = i2lo; i <= i2hi; i++ )
1883  {
1884  cout << setw(7) << i << " ";
1885  }
1886  cout << "\n";
1887  cout << " Col\n";
1888  cout << "\n";
1889 //
1890 // Determine the range of the rows in this strip.
1891 //
1892  j2lo = i_max ( jlo, 1 );
1893  j2hi = i_min ( jhi, n );
1894 
1895  for ( j = j2lo; j <= j2hi; j++ )
1896  {
1897 //
1898 // Print out (up to INCX) entries in column J, that lie in the current strip.
1899 //
1900  cout << setw(5) << j << " ";
1901  for ( i = i2lo; i <= i2hi; i++ )
1902  {
1903  cout << setw(6) << a[i-1+(j-1)*m] << " ";
1904  }
1905  cout << "\n";
1906  }
1907 
1908  }
1909 
1910  cout << "\n";
1911 
1912  return;
1913 # undef INCX
1914 }
1915 //********************************************************************
1916 
1917 void ivec_heap_d ( int n, int a[] )
1918 
1919 /*********************************************************************
1920 //
1921 // Purpose:
1922 //
1923 // IVEC_HEAP_D reorders an array of integers into a descending heap.
1924 //
1925 // Definition:
1926 //
1927 // A heap is an array A with the property that, for every index J,
1928 // A[J] >= A[2*J+1] and A[J] >= A[2*J+2], (as long as the indices
1929 // 2*J+1 and 2*J+2 are legal).
1930 //
1931 // Diagram:
1932 //
1933 // A(0)
1934 // / \
1935 // A(1) A(2)
1936 // / \ / \
1937 // A(3) A(4) A(5) A(6)
1938 // / \ / \
1939 // A(7) A(8) A(9) A(10)
1940 //
1941 // Reference:
1942 //
1943 // Albert Nijenhuis, Herbert Wilf,
1944 // Combinatorial Algorithms,
1945 // Academic Press, 1978, second edition,
1946 // ISBN 0-12-519260-6.
1947 //
1948 // Modified:
1949 //
1950 // 30 April 1999
1951 //
1952 // Author:
1953 //
1954 // John Burkardt
1955 //
1956 // Parameters:
1957 //
1958 // Input, int N, the size of the input array.
1959 //
1960 // Input/output, int A[N].
1961 // On input, an unsorted array.
1962 // On output, the array has been reordered into a heap.
1963 */
1964 {
1965  int i;
1966  int ifree;
1967  int key;
1968  int m;
1969 //
1970 // Only nodes (N/2)-1 down to 0 can be "parent" nodes.
1971 //
1972  for ( i = (n/2)-1; 0 <= i; i-- )
1973  {
1974 //
1975 // Copy the value out of the parent node.
1976 // Position IFREE is now "open".
1977 //
1978  key = a[i];
1979  ifree = i;
1980 
1981  for ( ;; )
1982  {
1983 //
1984 // Positions 2*IFREE + 1 and 2*IFREE + 2 are the descendants of position
1985 // IFREE. (One or both may not exist because they equal or exceed N.)
1986 //
1987  m = 2 * ifree + 1;
1988 //
1989 // Does the first position exist?
1990 //
1991  if ( n <= m )
1992  {
1993  break;
1994  }
1995  else
1996  {
1997 //
1998 // Does the second position exist?
1999 //
2000  if ( m + 1 < n )
2001  {
2002 //
2003 // If both positions exist, take the larger of the two values,
2004 // and update M if necessary.
2005 //
2006  if ( a[m] < a[m+1] )
2007  {
2008  m = m + 1;
2009  }
2010  }
2011 //
2012 // If the large descendant is larger than KEY, move it up,
2013 // and update IFREE, the location of the free position, and
2014 // consider the descendants of THIS position.
2015 //
2016  if ( key < a[m] )
2017  {
2018  a[ifree] = a[m];
2019  ifree = m;
2020  }
2021  else
2022  {
2023  break;
2024  }
2025 
2026  }
2027 
2028  }
2029 //
2030 // When you have stopped shifting items up, return the item you
2031 // pulled out back to the heap.
2032 //
2033  a[ifree] = key;
2034 
2035  }
2036 
2037  return;
2038 }
2039 //******************************************************************************
2040 
2041 int *ivec_indicator ( int n )
2042 
2043 //******************************************************************************
2044 //
2045 // Purpose:
2046 //
2047 // IVEC_INDICATOR sets an integer vector to the indicator vector.
2048 //
2049 // Modified:
2050 //
2051 // 13 January 2004
2052 //
2053 // Author:
2054 //
2055 // John Burkardt
2056 //
2057 // Parameters:
2058 //
2059 // Input, int N, the number of elements of A.
2060 //
2061 // Output, int IVEC_INDICATOR(N), the initialized array.
2062 //
2063 {
2064  int *a;
2065  int i;
2066 
2067  a = new int[n];
2068 
2069  for ( i = 0; i < n; i++ )
2070  {
2071  a[i] = i + 1;
2072  }
2073 
2074  return a;
2075 }
2076 //********************************************************************
2077 
2078 void ivec_sort_heap_a ( int n, int a[] )
2079 
2080 //********************************************************************
2081 //
2082 // Purpose:
2083 //
2084 // IVEC_SORT_HEAP_A ascending sorts an array of integers using heap sort.
2085 //
2086 // Reference:
2087 //
2088 // Albert Nijenhuis, Herbert Wilf,
2089 // Combinatorial Algorithms,
2090 // Academic Press, 1978, second edition,
2091 // ISBN 0-12-519260-6.
2092 //
2093 // Modified:
2094 //
2095 // 30 April 1999
2096 //
2097 // Author:
2098 //
2099 // John Burkardt
2100 //
2101 // Parameters:
2102 //
2103 // Input, int N, the number of entries in the array.
2104 //
2105 // Input/output, int A[N].
2106 // On input, the array to be sorted;
2107 // On output, the array has been sorted.
2108 //
2109 {
2110  int n1;
2111  int temp;
2112 
2113  if ( n <= 1 )
2114  {
2115  return;
2116  }
2117 //
2118 // 1: Put A into descending heap form.
2119 //
2120  ivec_heap_d ( n, a );
2121 //
2122 // 2: Sort A.
2123 //
2124 // The largest object in the heap is in A[0].
2125 // Move it to position A[N-1].
2126 //
2127  temp = a[0];
2128  a[0] = a[n-1];
2129  a[n-1] = temp;
2130 //
2131 // Consider the diminished heap of size N1.
2132 //
2133  for ( n1 = n-1; 2 <= n1; n1-- )
2134  {
2135 //
2136 // Restore the heap structure of the initial N1 entries of A.
2137 //
2138  ivec_heap_d ( n1, a );
2139 //
2140 // Take the largest object from A[0] and move it to A[N1-1].
2141 //
2142  temp = a[0];
2143  a[0] = a[n1-1];
2144  a[n1-1] = temp;
2145 
2146  }
2147 
2148  return;
2149 }
2150 //******************************************************************************
2151 
2152 void ivec_sorted_unique ( int n, int a[], int *nuniq )
2153 
2154 //******************************************************************************
2155 //
2156 // Purpose:
2157 //
2158 // IVEC_SORTED_UNIQUE finds unique elements in a sorted integer array.
2159 //
2160 // Modified:
2161 //
2162 // 02 September 2003
2163 //
2164 // Author:
2165 //
2166 // John Burkardt
2167 //
2168 // Parameters:
2169 //
2170 // Input, int N, the number of elements in A.
2171 //
2172 // Input/output, int A[N]. On input, the sorted
2173 // integer array. On output, the unique elements in A.
2174 //
2175 // Output, int *NUNIQ, the number of unique elements in A.
2176 //
2177 {
2178  int i;
2179 
2180  *nuniq = 0;
2181 
2182  if ( n <= 0 )
2183  {
2184  return;
2185  }
2186 
2187  *nuniq = 1;
2188 
2189  for ( i = 1; i < n; i++ )
2190  {
2191  if ( a[i] != a[*nuniq] )
2192  {
2193  *nuniq = *nuniq + 1;
2194  a[*nuniq] = a[i];
2195  }
2196 
2197  }
2198 
2199  return;
2200 }
2201 //******************************************************************************
2202 
2203 int lrline ( double xu, double yu, double xv1, double yv1, double xv2,
2204  double yv2, double dv )
2205 
2206 //******************************************************************************
2207 //
2208 // Purpose:
2209 //
2210 // LRLINE determines where a point lies in relation to a directed line.
2211 //
2212 // Discussion:
2213 //
2214 // LRLINE determines whether a point is to the left of, right of,
2215 // or on a directed line parallel to a line through given points.
2216 //
2217 // Modified:
2218 //
2219 // 28 August 2003
2220 //
2221 // Author:
2222 //
2223 // Barry Joe,
2224 // Department of Computing Science,
2225 // University of Alberta,
2226 // Edmonton, Alberta, Canada T6G 2H1
2227 //
2228 // Reference:
2229 //
2230 // Barry Joe,
2231 // GEOMPACK - a software package for the generation of meshes
2232 // using geometric algorithms,
2233 // Advances in Engineering Software,
2234 // Volume 13, pages 325-331, 1991.
2235 //
2236 // Parameters:
2237 //
2238 // Input, double XU, YU, XV1, YV1, XV2, YV2, are vertex coordinates; the
2239 // directed line is parallel to and at signed distance DV to the left of
2240 // the directed line from (XV1,YV1) to (XV2,YV2); (XU,YU) is the vertex for
2241 // which the position relative to the directed line is to be determined.
2242 //
2243 // Input, double DV, the signed distance, positive for left.
2244 //
2245 // Output, int LRLINE, is +1, 0, or -1 depending on whether (XU,YU) is
2246 // to the right of, on, or left of the directed line. LRLINE is 0 if
2247 // the line degenerates to a point.
2248 //
2249 {
2250  double dx;
2251  double dxu;
2252  double dy;
2253  double dyu;
2254  double t;
2255  double tol = 0.0000001;
2256  double tolabs;
2257  int value = 0;
2258 
2259  dx = xv2 - xv1;
2260  dy = yv2 - yv1;
2261  dxu = xu - xv1;
2262  dyu = yu - yv1;
2263 
2264  tolabs = tol * d_max ( fabs ( dx ),
2265  d_max ( fabs ( dy ),
2266  d_max ( fabs ( dxu ),
2267  d_max ( fabs ( dyu ), fabs ( dv ) ) ) ) );
2268 
2269  t = dy * dxu - dx * dyu + dv * sqrt ( dx * dx + dy * dy );
2270 
2271  if ( tolabs < t )
2272  {
2273  value = 1;
2274  }
2275  else if ( -tolabs <= t )
2276  {
2277  value = 0;
2278  }
2279  else if ( t < -tolabs )
2280  {
2281  value = -1;
2282  }
2283 
2284  return value;
2285 }
2286 //******************************************************************************
2287 
2288 bool perm_check ( int n, int p[] )
2289 
2290 //******************************************************************************
2291 //
2292 // Purpose:
2293 //
2294 // PERM_CHECK checks that a vector represents a permutation.
2295 //
2296 // Discussion:
2297 //
2298 // The routine verifies that each of the integers from 1
2299 // to N occurs among the N entries of the permutation.
2300 //
2301 // Modified:
2302 //
2303 // 13 January 2004
2304 //
2305 // Author:
2306 //
2307 // John Burkardt
2308 //
2309 // Parameters:
2310 //
2311 // Input, int N, the number of entries.
2312 //
2313 // Input, int P[N], the array to check.
2314 //
2315 // Output, bool PERM_CHECK, is TRUE if the permutation is OK.
2316 //
2317 {
2318  bool found;
2319  int i;
2320  int seek;
2321 
2322  for ( seek = 1; seek <= n; seek++ )
2323  {
2324  found = false;
2325 
2326  for ( i = 0; i < n; i++ )
2327  {
2328  if ( p[i] == seek )
2329  {
2330  found = true;
2331  break;
2332  }
2333  }
2334 
2335  if ( !found )
2336  {
2337  return false;
2338  }
2339 
2340  }
2341 
2342  return true;
2343 }
2344 //******************************************************************************
2345 
2346 void perm_inv ( int n, int p[] )
2347 
2348 //******************************************************************************
2349 //
2350 // Purpose:
2351 //
2352 // PERM_INV inverts a permutation "in place".
2353 //
2354 // Modified:
2355 //
2356 // 13 January 2004
2357 //
2358 // Parameters:
2359 //
2360 // Input, int N, the number of objects being permuted.
2361 //
2362 // Input/output, int P[N], the permutation, in standard index form.
2363 // On output, P describes the inverse permutation
2364 //
2365 {
2366  int i;
2367  int i0;
2368  int i1;
2369  int i2;
2370  int is;
2371 
2372  if ( n <= 0 )
2373  {
2374  cout << "\n";
2375  cout << "PERM_INV - Fatal error!\n";
2376  cout << " Input value of N = " << n << "\n";
2377  exit ( 1 );
2378  }
2379 
2380  if ( !perm_check ( n, p ) )
2381  {
2382  cout << "\n";
2383  cout << "PERM_INV - Fatal error!\n";
2384  cout << " The input array does not represent\n";
2385  cout << " a proper permutation.\n";
2386  exit ( 1 );
2387  }
2388 
2389  is = 1;
2390 
2391  for ( i = 1; i <= n; i++ )
2392  {
2393  i1 = p[i-1];
2394 
2395  while ( i < i1 )
2396  {
2397  i2 = p[i1-1];
2398  p[i1-1] = -i2;
2399  i1 = i2;
2400  }
2401 
2402  is = - i_sign ( p[i-1] );
2403  p[i-1] = i_sign ( is ) * abs ( p[i-1] );
2404  }
2405 
2406  for ( i = 1; i <= n; i++ )
2407  {
2408  i1 = -p[i-1];
2409 
2410  if ( 0 <= i1 )
2411  {
2412  i0 = i;
2413 
2414  for ( ; ; )
2415  {
2416  i2 = p[i1-1];
2417  p[i1-1] = i0;
2418 
2419  if ( i2 < 0 )
2420  {
2421  break;
2422  }
2423  i0 = i1;
2424  i1 = i2;
2425  }
2426  }
2427  }
2428 
2429  return;
2430 }
2431 //********************************************************************
2432 
2433 int *points_delaunay_naive_2d ( int n, double p[], int *ntri )
2434 
2435 //********************************************************************
2436 //
2437 // Purpose:
2438 //
2439 // POINTS_DELAUNAY_NAIVE_2D computes the Delaunay triangulation in 2D.
2440 //
2441 // Discussion:
2442 //
2443 // A naive and inefficient (but extremely simple) method is used.
2444 //
2445 // This routine is only suitable as a demonstration code for small
2446 // problems. Its running time is of order N^4. Much faster algorithms
2447 // are available.
2448 //
2449 // Given a set of nodes in the plane, a triangulation is a set of
2450 // triples of distinct nodes, forming triangles, so that every
2451 // point with the convex hull of the set of nodes is either one
2452 // of the nodes, or lies on an edge of one or more triangles,
2453 // or lies within exactly one triangle.
2454 //
2455 // Modified:
2456 //
2457 // 05 February 2005
2458 //
2459 // Author:
2460 //
2461 // John Burkardt
2462 //
2463 // Reference:
2464 //
2465 // Joseph O'Rourke,
2466 // Computational Geometry,
2467 // Cambridge University Press,
2468 // Second Edition, 1998, page 187.
2469 //
2470 // Parameters:
2471 //
2472 // Input, int N, the number of nodes. N must be at least 3.
2473 //
2474 // Input, double P[2*N], the coordinates of the nodes.
2475 //
2476 // Output, int *NTRI, the number of triangles.
2477 //
2478 // Output, int POINTS_DELAUNAY_NAIVE_2D[3*NTRI], the indices of the
2479 // nodes making each triangle.
2480 //
2481 {
2482  int count;
2483  int flag;
2484  int i;
2485  int j;
2486  int k;
2487  int m;
2488  int pass;
2489  int *tri = NULL;
2490  double xn;
2491  double yn;
2492  double zn;
2493  double *z;
2494 
2495  count = 0;
2496 
2497  z = new double [ n ];
2498 
2499  for ( i = 0; i < n; i++ )
2500  {
2501  z[i] = p[0+i*2] * p[0+i*2] + p[1+i*2] * p[1+i*2];
2502  }
2503 //
2504 // First pass counts triangles,
2505 // Second pass allocates triangles and sets them.
2506 //
2507  for ( pass = 1; pass <= 2; pass++ )
2508  {
2509  if ( pass == 2 )
2510  {
2511  tri = new int[3*count];
2512  }
2513  count = 0;
2514 //
2515 // For each triple (I,J,K):
2516 //
2517  for ( i = 0; i < n - 2; i++ )
2518  {
2519  for ( j = i+1; j < n; j++ )
2520  {
2521  for ( k = i+1; k < n; k++ )
2522  {
2523  if ( j != k )
2524  {
2525  xn = ( p[1+j*2] - p[1+i*2] ) * ( z[k] - z[i] )
2526  - ( p[1+k*2] - p[1+i*2] ) * ( z[j] - z[i] );
2527  yn = ( p[0+k*2] - p[0+i*2] ) * ( z[j] - z[i] )
2528  - ( p[0+j*2] - p[0+i*2] ) * ( z[k] - z[i] );
2529  zn = ( p[0+j*2] - p[0+i*2] ) * ( p[1+k*2] - p[1+i*2] )
2530  - ( p[0+k*2] - p[0+i*2] ) * ( p[1+j*2] - p[1+i*2] );
2531 
2532  flag = ( zn < 0 );
2533 
2534  if ( flag )
2535  {
2536  for ( m = 0; m < n; m++ )
2537  {
2538  flag = flag && ( ( p[0+m*2] - p[0+i*2] ) * xn
2539  + ( p[1+m*2] - p[1+i*2] ) * yn
2540  + ( z[m] - z[i] ) * zn <= 0 );
2541  }
2542  }
2543 
2544  if ( flag )
2545  {
2546  if ( pass == 2 )
2547  {
2548  tri[0+count*3] = i;
2549  tri[1+count*3] = j;
2550  tri[2+count*3] = k;
2551  }
2552  count = count + 1;
2553  }
2554 
2555  }
2556  }
2557  }
2558  }
2559  }
2560 
2561  *ntri = count;
2562  delete [] z;
2563 
2564  return tri;
2565 }
2566 //******************************************************************************
2567 
2568 int s_len_trim ( const char *s )
2569 
2570 //******************************************************************************
2571 //
2572 // Purpose:
2573 //
2574 // S_LEN_TRIM returns the length of a string to the last nonblank.
2575 //
2576 // Modified:
2577 //
2578 // 26 April 2003
2579 //
2580 // Author:
2581 //
2582 // John Burkardt
2583 //
2584 // Parameters:
2585 //
2586 // Input, const char *S, a pointer to a string.
2587 //
2588 // Output, int S_LEN_TRIM, the length of the string to the last nonblank.
2589 // If S_LEN_TRIM is 0, then the string is entirely blank.
2590 //
2591 {
2592  int n;
2593  char* t;
2594 
2595  n = strlen ( s );
2596  t = const_cast<char*>(s) + n - 1;
2597 
2598  while ( 0 < n )
2599  {
2600  if ( *t != ' ' )
2601  {
2602  return n;
2603  }
2604  t--;
2605  n--;
2606  }
2607 
2608  return n;
2609 }
2610 //******************************************************************************
2611 
2612 int swapec ( int i, int *top, int *btri, int *bedg, int point_num,
2613  double point_xy[], int tri_num, int tri_vert[], int tri_nabe[],
2614  int stack[] )
2615 
2616 //******************************************************************************
2617 //
2618 // Purpose:
2619 //
2620 // SWAPEC swaps diagonal edges until all triangles are Delaunay.
2621 //
2622 // Discussion:
2623 //
2624 // The routine swaps diagonal edges in a 2D triangulation, based on
2625 // the empty circumcircle criterion, until all triangles are Delaunay,
2626 // given that I is the index of the new vertex added to the triangulation.
2627 //
2628 // Modified:
2629 //
2630 // 03 September 2003
2631 //
2632 // Author:
2633 //
2634 // Barry Joe,
2635 // Department of Computing Science,
2636 // University of Alberta,
2637 // Edmonton, Alberta, Canada T6G 2H1
2638 //
2639 // Reference:
2640 //
2641 // Barry Joe,
2642 // GEOMPACK - a software package for the generation of meshes
2643 // using geometric algorithms,
2644 // Advances in Engineering Software,
2645 // Volume 13, pages 325-331, 1991.
2646 //
2647 // Parameters:
2648 //
2649 // Input, int I, the index of the new vertex.
2650 //
2651 // Input/output, int *TOP, the index of the top of the stack.
2652 // On output, TOP is zero.
2653 //
2654 // Input/output, int *BTRI, *BEDG; on input, if positive, are the
2655 // triangle and edge indices of a boundary edge whose updated indices
2656 // must be recorded. On output, these may be updated because of swaps.
2657 //
2658 // Input, int POINT_NUM, the number of points.
2659 //
2660 // Input, double POINT_XY[POINT_NUM*2], the coordinates of the points.
2661 //
2662 // Input, int TRI_NUM, the number of triangles.
2663 //
2664 // Input/output, int TRI_VERT[TRI_NUM*3], the triangle incidence list.
2665 // May be updated on output because of swaps.
2666 //
2667 // Input/output, int TRI_NABE[TRI_NUM*3], the triangle neighbor list;
2668 // negative values are used for links of the counter-clockwise linked
2669 // list of boundary edges; May be updated on output because of swaps.
2670 //
2671 // LINK = -(3*I + J-1) where I, J = triangle, edge index.
2672 //
2673 // Workspace, int STACK[MAXST]; on input, entries 1 through TOP
2674 // contain the indices of initial triangles (involving vertex I)
2675 // put in stack; the edges opposite I should be in interior; entries
2676 // TOP+1 through MAXST are used as a stack.
2677 //
2678 // Output, int SWAPEC, is set to 8 for abnormal return.
2679 //
2680 {
2681  int a;
2682  int b;
2683  int c;
2684  int e;
2685  int ee;
2686  int em1;
2687  int ep1;
2688  int f;
2689  int fm1;
2690  int fp1;
2691  int l;
2692  int r;
2693  int s;
2694  int swap;
2695  int t;
2696  int tt;
2697  int u;
2698  double x;
2699  double y;
2700 //
2701 // Determine whether triangles in stack are Delaunay, and swap
2702 // diagonal edge of convex quadrilateral if not.
2703 //
2704  x = point_xy[2*(i-1)+0];
2705  y = point_xy[2*(i-1)+1];
2706 
2707  for ( ; ; )
2708  {
2709  if ( *top <= 0 )
2710  {
2711  break;
2712  }
2713 
2714  t = stack[(*top)-1];
2715  *top = *top - 1;
2716 
2717  if ( tri_vert[3*(t-1)+0] == i )
2718  {
2719  e = 2;
2720  b = tri_vert[3*(t-1)+2];
2721  }
2722  else if ( tri_vert[3*(t-1)+1] == i )
2723  {
2724  e = 3;
2725  b = tri_vert[3*(t-1)+0];
2726  }
2727  else
2728  {
2729  e = 1;
2730  b = tri_vert[3*(t-1)+1];
2731  }
2732 
2733  a = tri_vert[3*(t-1)+e-1];
2734  u = tri_nabe[3*(t-1)+e-1];
2735 
2736  if ( tri_nabe[3*(u-1)+0] == t )
2737  {
2738  f = 1;
2739  c = tri_vert[3*(u-1)+2];
2740  }
2741  else if ( tri_nabe[3*(u-1)+1] == t )
2742  {
2743  f = 2;
2744  c = tri_vert[3*(u-1)+0];
2745  }
2746  else
2747  {
2748  f = 3;
2749  c = tri_vert[3*(u-1)+1];
2750  }
2751 
2752  swap = diaedg ( x, y,
2753  point_xy[2*(a-1)+0], point_xy[2*(a-1)+1],
2754  point_xy[2*(c-1)+0], point_xy[2*(c-1)+1],
2755  point_xy[2*(b-1)+0], point_xy[2*(b-1)+1] );
2756 
2757  if ( swap == 1 )
2758  {
2759  em1 = i_wrap ( e - 1, 1, 3 );
2760  ep1 = i_wrap ( e + 1, 1, 3 );
2761  fm1 = i_wrap ( f - 1, 1, 3 );
2762  fp1 = i_wrap ( f + 1, 1, 3 );
2763 
2764  tri_vert[3*(t-1)+ep1-1] = c;
2765  tri_vert[3*(u-1)+fp1-1] = i;
2766  r = tri_nabe[3*(t-1)+ep1-1];
2767  s = tri_nabe[3*(u-1)+fp1-1];
2768  tri_nabe[3*(t-1)+ep1-1] = u;
2769  tri_nabe[3*(u-1)+fp1-1] = t;
2770  tri_nabe[3*(t-1)+e-1] = s;
2771  tri_nabe[3*(u-1)+f-1] = r;
2772 
2773  if ( 0 < tri_nabe[3*(u-1)+fm1-1] )
2774  {
2775  *top = *top + 1;
2776  stack[(*top)-1] = u;
2777  }
2778 
2779  if ( 0 < s )
2780  {
2781  if ( tri_nabe[3*(s-1)+0] == u )
2782  {
2783  tri_nabe[3*(s-1)+0] = t;
2784  }
2785  else if ( tri_nabe[3*(s-1)+1] == u )
2786  {
2787  tri_nabe[3*(s-1)+1] = t;
2788  }
2789  else
2790  {
2791  tri_nabe[3*(s-1)+2] = t;
2792  }
2793 
2794  *top = *top + 1;
2795 
2796  if ( point_num < *top )
2797  {
2798  return 8;
2799  }
2800 
2801  stack[(*top)-1] = t;
2802  }
2803  else
2804  {
2805  if ( u == *btri && fp1 == *bedg )
2806  {
2807  *btri = t;
2808  *bedg = e;
2809  }
2810 
2811  l = - ( 3 * t + e - 1 );
2812  tt = t;
2813  ee = em1;
2814 
2815  while ( 0 < tri_nabe[3*(tt-1)+ee-1] )
2816  {
2817  tt = tri_nabe[3*(tt-1)+ee-1];
2818 
2819  if ( tri_vert[3*(tt-1)+0] == a )
2820  {
2821  ee = 3;
2822  }
2823  else if ( tri_vert[3*(tt-1)+1] == a )
2824  {
2825  ee = 1;
2826  }
2827  else
2828  {
2829  ee = 2;
2830  }
2831 
2832  }
2833 
2834  tri_nabe[3*(tt-1)+ee-1] = l;
2835 
2836  }
2837 
2838  if ( 0 < r )
2839  {
2840  if ( tri_nabe[3*(r-1)+0] == t )
2841  {
2842  tri_nabe[3*(r-1)+0] = u;
2843  }
2844  else if ( tri_nabe[3*(r-1)+1] == t )
2845  {
2846  tri_nabe[3*(r-1)+1] = u;
2847  }
2848  else
2849  {
2850  tri_nabe[3*(r-1)+2] = u;
2851  }
2852  }
2853  else
2854  {
2855  if ( t == *btri && ep1 == *bedg )
2856  {
2857  *btri = u;
2858  *bedg = f;
2859  }
2860 
2861  l = - ( 3 * u + f - 1 );
2862  tt = u;
2863  ee = fm1;
2864 
2865  while ( 0 < tri_nabe[3*(tt-1)+ee-1] )
2866  {
2867  tt = tri_nabe[3*(tt-1)+ee-1];
2868 
2869  if ( tri_vert[3*(tt-1)+0] == b )
2870  {
2871  ee = 3;
2872  }
2873  else if ( tri_vert[3*(tt-1)+1] == b )
2874  {
2875  ee = 1;
2876  }
2877  else
2878  {
2879  ee = 2;
2880  }
2881  }
2882  tri_nabe[3*(tt-1)+ee-1] = l;
2883  }
2884  }
2885  }
2886  return 0;
2887 }
2888 //**********************************************************************
2889 
2890 void timestamp ( void )
2891 
2892 //**********************************************************************
2893 //
2894 // Purpose:
2895 //
2896 // TIMESTAMP prints the current YMDHMS date as a time stamp.
2897 //
2898 // Example:
2899 //
2900 // May 31 2001 09:45:54 AM
2901 //
2902 // Modified:
2903 //
2904 // 21 August 2002
2905 //
2906 // Author:
2907 //
2908 // John Burkardt
2909 //
2910 // Parameters:
2911 //
2912 // None
2913 //
2914 {
2915 # define TIME_SIZE 29
2916 
2917  static char time_buffer[TIME_SIZE];
2918  const struct tm *tm;
2919  size_t len;
2920  time_t now;
2921 
2922  now = time ( NULL );
2923  tm = localtime ( &now );
2924 
2925  len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
2926 
2927  if ( len != 0 )
2928  {
2929  cout << time_buffer << "\n";
2930  }
2931 
2932  return;
2933 # undef TIME_SIZE
2934 }
2935 //**********************************************************************
2936 
2937 char *timestring ( void )
2938 
2939 //**********************************************************************
2940 //
2941 // Purpose:
2942 //
2943 // TIMESTRING returns the current YMDHMS date as a string.
2944 //
2945 // Example:
2946 //
2947 // May 31 2001 09:45:54 AM
2948 //
2949 // Modified:
2950 //
2951 // 13 June 2003
2952 //
2953 // Author:
2954 //
2955 // John Burkardt
2956 //
2957 // Parameters:
2958 //
2959 // Output, char *TIMESTRING, a string containing the current YMDHMS date.
2960 //
2961 {
2962 # define TIME_SIZE 29
2963 
2964  const struct tm *tm;
2965  time_t now;
2966  char *s;
2967 
2968  now = time ( NULL );
2969  tm = localtime ( &now );
2970 
2971  s = new char[TIME_SIZE];
2972 
2973  strftime ( s, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
2974 
2975  return s;
2976 # undef TIME_SIZE
2977 }
2978 //******************************************************************************
2979 
2980 double *triangle_circumcenter_2d ( double t[] )
2981 
2982 //******************************************************************************
2983 //
2984 // Purpose:
2985 //
2986 // TRIANGLE_CIRCUMCENTER_2D computes the circumcenter of a triangle in 2D.
2987 //
2988 // Discussion:
2989 //
2990 // The circumcenter of a triangle is the center of the circumcircle, the
2991 // circle that passes through the three vertices of the triangle.
2992 //
2993 // The circumcircle contains the triangle, but it is not necessarily the
2994 // smallest triangle to do so.
2995 //
2996 // If all angles of the triangle are no greater than 90 degrees, then
2997 // the center of the circumscribed circle will lie inside the triangle.
2998 // Otherwise, the center will lie outside the circle.
2999 //
3000 // The circumcenter is the intersection of the perpendicular bisectors
3001 // of the sides of the triangle.
3002 //
3003 // In geometry, the circumcenter of a triangle is often symbolized by "O".
3004 //
3005 // Modified:
3006 //
3007 // 09 February 2005
3008 //
3009 // Author:
3010 //
3011 // John Burkardt
3012 //
3013 // Parameters:
3014 //
3015 // Input, double T[2*3], the triangle vertices.
3016 //
3017 // Output, double *X, *Y, the coordinates of the circumcenter of
3018 // the triangle.
3019 //
3020 {
3021 # define DIM_NUM 2
3022 
3023  double asq;
3024  double bot;
3025  double *center;
3026  double csq;
3027  double top1;
3028  double top2;
3029 
3030  center = new double[DIM_NUM];
3031 
3032  asq = ( t[0+1*2] - t[0+0*2] ) * ( t[0+1*2] - t[0+0*2] )
3033  + ( t[1+1*2] - t[1+0*2] ) * ( t[1+1*2] - t[1+0*2] );
3034 
3035  csq = ( t[0+2*2] - t[0+0*2] ) * ( t[0+2*2] - t[0+0*2] )
3036  + ( t[1+2*2] - t[1+0*2] ) * ( t[1+2*2] - t[1+0*2] );
3037 
3038  top1 = ( t[1+1*2] - t[1+0*2] ) * csq - ( t[1+2*2] - t[1+0*2] ) * asq;
3039  top2 = ( t[0+1*2] - t[0+0*2] ) * csq - ( t[0+2*2] - t[0+0*2] ) * asq;
3040 
3041  bot = ( t[1+1*2] - t[1+0*2] ) * ( t[0+2*2] - t[0+0*2] )
3042  - ( t[1+2*2] - t[1+0*2] ) * ( t[0+1*2] - t[0+0*2] );
3043 
3044  center[0] = t[0+0*2] + 0.5 * top1 / bot;
3045  center[1] = t[1+0*2] + 0.5 * top2 / bot;
3046 
3047  return center;
3048 
3049 # undef DIM_NUM
3050 }
3051 //******************************************************************************
3052 
3053 bool triangulation_plot_eps ( const char *file_out_name, int g_num,
3054  double g_xy[], int tri_num, int nod_tri[] )
3055 
3056 //******************************************************************************
3057 //
3058 // Purpose:
3059 //
3060 // TRIANGULATION_PLOT_EPS plots a triangulation of a pointset.
3061 //
3062 // Discussion:
3063 //
3064 // The triangulation is most usually a Delaunay triangulation,
3065 // but this is not necessary.
3066 //
3067 // The data can be generated by calling DTRIS2, but this is not
3068 // necessary.
3069 //
3070 // Modified:
3071 //
3072 // 08 September 2003
3073 //
3074 // Author:
3075 //
3076 // John Burkardt
3077 //
3078 // Parameters:
3079 //
3080 // Input, const char *FILE_OUT_NAME, the name of the output file.
3081 //
3082 // Input, int G_NUM, the number of points.
3083 //
3084 // Input, double G_XY[G_NUM,2], the coordinates of the points.
3085 //
3086 // Input, int TRI_NUM, the number of triangles.
3087 //
3088 // Input, int NOD_TRI[3,TRI_NUM], lists, for each triangle,
3089 // the indices of the points that form the vertices of the triangle.
3090 //
3091 // Output, bool TRIANGULATION_PLOT_EPS, is TRUE for success.
3092 //
3093 {
3094  char *date_time;
3095  int e;
3096  ofstream file_out;
3097  int g;
3098  int j;
3099  int k;
3100  int t;
3101  double x_max;
3102  double x_min;
3103  int x_ps;
3104  int x_ps_max = 576;
3105  int x_ps_max_clip = 594;
3106  int x_ps_min = 36;
3107  int x_ps_min_clip = 18;
3108  double y_max;
3109  double y_min;
3110  int y_ps;
3111  int y_ps_max = 666;
3112  int y_ps_max_clip = 684;
3113  int y_ps_min = 126;
3114  int y_ps_min_clip = 108;
3115 
3116  date_time = timestring ( );
3117 
3118  x_max = g_xy[0+0*2];
3119  x_min = g_xy[0+0*2];
3120  y_max = g_xy[1+0*2];
3121  y_min = g_xy[1+0*2];
3122 
3123  for ( g = 0; g < g_num; g++ )
3124  {
3125  x_max = d_max ( x_max, g_xy[0+g*2] );
3126  x_min = d_min ( x_min, g_xy[0+g*2] );
3127  y_max = d_max ( y_max, g_xy[1+g*2] );
3128  y_min = d_min ( y_min, g_xy[1+g*2] );
3129  }
3130 //
3131 // Plot the Delaunay triangulation.
3132 //
3133 //
3134 // Open the output file.
3135 //
3136  file_out.open ( file_out_name );
3137 
3138  if ( !file_out )
3139  {
3140  cout << "\n";
3141  cout << "TRIANGULATION_PLOT_EPS - Fatal error!\n";
3142  cout << " Cannot open the output file \"" << file_out_name << "\".\n";
3143  return false;
3144  }
3145 
3146  file_out << "%!PS-Adobe-3.0 EPSF-3.0\n";
3147  file_out << "%%Creator: triangulation_plot_eps.cc\n";
3148  file_out << "%%Title: " << file_out_name << "\n";
3149  file_out << "%%CreationDate: " << date_time << "\n";
3150  file_out << "%%Pages: 1\n";
3151  file_out << "%%Bounding Box: " << x_ps_min << " " << y_ps_min << " "
3152  << x_ps_max << " " << y_ps_max << "\n";
3153  file_out << "%%Document-Fonts: Times-Roman\n";
3154  file_out << "%%LanguageLevel: 1\n";
3155  file_out << "%%EndComments\n";
3156  file_out << "%%BeginProlog\n";
3157  file_out << "/inch {72 mul} def\n";
3158  file_out << "%%EndProlog\n";
3159  file_out << "%%Page: 1 1\n";
3160  file_out << "save\n";
3161  file_out << "%\n";
3162  file_out << "% Set the RGB line color to very light gray.\n";
3163  file_out << "%\n";
3164  file_out << "0.900 0.900 0.900 setrgbcolor\n";
3165  file_out << "%\n";
3166  file_out << "% Draw a gray border around the page.\n";
3167  file_out << "%\n";
3168  file_out << "newpath\n";
3169  file_out << " " << x_ps_min << " " << y_ps_min << " moveto\n";
3170  file_out << " " << x_ps_max << " " << y_ps_min << " lineto\n";
3171  file_out << " " << x_ps_max << " " << y_ps_max << " lineto\n";
3172  file_out << " " << x_ps_min << " " << y_ps_max << " lineto\n";
3173  file_out << " " << x_ps_min << " " << y_ps_min << " lineto\n";
3174  file_out << "stroke\n";
3175  file_out << "%\n";
3176  file_out << "% Set the RGB line color to black.\n";
3177  file_out << "%\n";
3178  file_out << "0.000 0.000 0.000 setrgbcolor\n";
3179  file_out << "%\n";
3180  file_out << "% Set the font and its size.\n";
3181  file_out << "%\n";
3182  file_out << "/Times-Roman findfont\n";
3183  file_out << "0.50 inch scalefont\n";
3184  file_out << "setfont\n";
3185  file_out << "%\n";
3186  file_out << "% Print a title.\n";
3187  file_out << "%\n";
3188  file_out << "210 702 moveto\n";
3189  file_out << "(Triangulation) show\n";
3190  file_out << "%\n";
3191  file_out << "% Define a clipping polygon.\n";
3192  file_out << "%\n";
3193  file_out << "newpath\n";
3194  file_out << " " << x_ps_min_clip << " " << y_ps_min_clip << " moveto\n";
3195  file_out << " " << x_ps_max_clip << " " << y_ps_min_clip << " lineto\n";
3196  file_out << " " << x_ps_max_clip << " " << y_ps_max_clip << " lineto\n";
3197  file_out << " " << x_ps_min_clip << " " << y_ps_max_clip << " lineto\n";
3198  file_out << " " << x_ps_min_clip << " " << y_ps_min_clip << " lineto\n";
3199  file_out << "clip newpath\n";
3200  file_out << "%\n";
3201  file_out << "% Set the RGB line color to green.\n";
3202  file_out << "%\n";
3203  file_out << "0.000 0.750 0.150 setrgbcolor\n";
3204  file_out << "%\n";
3205  file_out << "% Draw the nodes.\n";
3206  file_out << "%\n";
3207 
3208  for ( g = 0; g < g_num; g++ )
3209  {
3210  x_ps = int(
3211  ( ( x_max - g_xy[0+g*2] ) * double( x_ps_min )
3212  + ( g_xy[0+g*2] - x_min ) * double( x_ps_max ) )
3213  / ( x_max - x_min ) );
3214 
3215  y_ps = int(
3216  ( ( y_max - g_xy[1+g*2] ) * double( y_ps_min )
3217  + ( g_xy[1+g*2] - y_min ) * double( y_ps_max ) )
3218  / ( y_max - y_min ) );
3219 
3220  file_out << "newpath " << x_ps << " "
3221  << y_ps << " 5 0 360 arc closepath fill\n";
3222  }
3223 
3224  file_out << "%\n";
3225  file_out << "% Set the RGB line color to red.\n";
3226  file_out << "%\n";
3227  file_out << "0.900 0.200 0.100 setrgbcolor\n";
3228  file_out << "%\n";
3229  file_out << "% Draw the triangles.\n";
3230  file_out << "%\n";
3231 
3232  for ( t = 1; t <= tri_num; t++ )
3233  {
3234  file_out << "newpath\n";
3235 
3236  for ( j = 1; j <= 4; j++ )
3237  {
3238  e = i_wrap ( j, 1, 3 );
3239 
3240  k = nod_tri[3*(t-1)+e-1];
3241 
3242  x_ps = int(
3243  ( ( x_max - g_xy[0+(k-1)*2] ) * double( x_ps_min )
3244  + ( g_xy[0+(k-1)*2] - x_min ) * double( x_ps_max ) )
3245  / ( x_max - x_min ) );
3246 
3247  y_ps = int(
3248  ( ( y_max - g_xy[1+(k-1)*2] ) * double( y_ps_min )
3249  + ( g_xy[1+(k-1)*2] - y_min ) * double( y_ps_max ) )
3250  / ( y_max - y_min ) );
3251 
3252  if ( j == 1 )
3253  {
3254  file_out << x_ps << " " << y_ps << " moveto\n";
3255  }
3256  else
3257  {
3258  file_out << x_ps << " " << y_ps << " lineto\n";
3259  }
3260 
3261  }
3262 
3263  file_out << "stroke\n";
3264 
3265  }
3266 
3267  file_out << "restore showpage\n";
3268  file_out << "%\n";
3269  file_out << "% End of page.\n";
3270  file_out << "%\n";
3271  file_out << "%%Trailer\n";
3272  file_out << "%%EOF\n";
3273 
3274  file_out.close ( );
3275 
3276  return true;
3277 }
3278 //******************************************************************************
3279 
3280 void triangulation_print ( int point_num, double xc[], int tri_num,
3281  int tri_vert[], int tri_nabe[] )
3282 
3283 //******************************************************************************
3284 //
3285 // Purpose:
3286 //
3287 // TRIANGULATION_PRINT prints information defining a Delaunay triangulation.
3288 //
3289 // Discussion:
3290 //
3291 // Triangulations created by RTRIS include extra information encoded
3292 // in the negative values of TRI_NABE.
3293 //
3294 // Because some of the nodes counted in POINT_NUM may not actually be
3295 // used in the triangulation, I needed to compute the true number
3296 // of vertices. I added this calculation on 13 October 2001.
3297 //
3298 // Ernest Fasse pointed out an error in the indexing of VERTEX_LIST,
3299 // which was corrected on 19 February 2004.
3300 //
3301 // Modified:
3302 //
3303 // 19 February 2004
3304 //
3305 // Author:
3306 //
3307 // John Burkardt
3308 //
3309 // Parameters:
3310 //
3311 // Input, int POINT_NUM, the number of points.
3312 //
3313 // Input, double XC[2*POINT_NUM], the point coordinates.
3314 //
3315 // Input, int TRI_NUM, the number of triangles.
3316 //
3317 // Input, int TRI_VERT[3*TRI_NUM], the nodes that make up the triangles.
3318 //
3319 // Input, int TRI_NABE[3*TRI_NUM], the triangle neighbors on each side.
3320 // If there is no triangle neighbor on a particular side, the value of
3321 // TRI_NABE should be negative. If the triangulation data was created by
3322 // DTRIS2, then there is more information encoded in the negative values.
3323 //
3324 {
3325 # define DIM_NUM 2
3326 
3327  int boundary_num;
3328  int i;
3329  int j;
3330  int k;
3331  int n1;
3332  int n2;
3333  int s;
3334  int s1;
3335  int s2;
3336  bool skip;
3337  int t;
3338  int *vertex_list;
3339  int vertex_num;
3340 
3341  cout << "\n";
3342  cout << "TRIANGULATION_PRINT\n";
3343  cout << " Information defining a triangulation.\n";
3344  cout << "\n";
3345  cout << " The number of points is " << point_num << "\n";
3346 
3347  dmat_transpose_print ( DIM_NUM, point_num, xc, " Point coordinates" );
3348 
3349  cout << "\n";
3350  cout << " The number of triangles is " << tri_num << "\n";
3351  cout << "\n";
3352  cout << " Sets of three points are used as vertices of\n";
3353  cout << " the triangles. For each triangle, the points\n";
3354  cout << " are listed in counterclockwise order.\n";
3355 
3356  imat_transpose_print ( 3, tri_num, tri_vert, " Triangle nodes" );
3357 
3358  cout << "\n";
3359  cout << " On each side of a given triangle, there is either\n";
3360  cout << " another triangle, or a piece of the convex hull.\n";
3361  cout << " For each triangle, we list the indices of the three\n";
3362  cout << " neighbors, or (if negative) the codes of the\n";
3363  cout << " segments of the convex hull.\n";
3364 
3365  imat_transpose_print ( 3, tri_num, tri_nabe, " Triangle neighbors" );
3366 //
3367 // Determine VERTEX_NUM, the number of vertices. This is not
3368 // the same as the number of points!
3369 //
3370  vertex_list = new int[3*tri_num];
3371 
3372  k = 0;
3373  for ( t = 0; t < tri_num; t++ )
3374  {
3375  for ( s = 0; s < 3; s++ )
3376  {
3377  vertex_list[k] = tri_vert[s+t*3];
3378  k = k + 1;
3379  }
3380  }
3381 
3382  ivec_sort_heap_a ( 3*tri_num, vertex_list );
3383 
3384  ivec_sorted_unique ( 3*tri_num, vertex_list, &vertex_num );
3385 
3386  delete [] vertex_list;
3387 //
3388 // Determine the number of boundary points.
3389 //
3390  boundary_num = 2 * vertex_num - tri_num - 2;
3391 
3392  cout << "\n";
3393  cout << " The number of boundary points is " << boundary_num << "\n";
3394  cout << "\n";
3395  cout << " The segments that make up the convex hull can be\n";
3396  cout << " determined from the negative entries of the triangle\n";
3397  cout << " neighbor list.\n";
3398  cout << "\n";
3399  cout << " # Tri Side N1 N2\n";
3400  cout << "\n";
3401 
3402  skip = false;
3403 
3404  k = 0;
3405 
3406  for ( i = 0; i < tri_num; i++ )
3407  {
3408  for ( j = 0; j < 3; j++ )
3409  {
3410  if ( tri_nabe[j+i*3] < 0 )
3411  {
3412  s = -tri_nabe[j+i*3];
3413  t = s / 3;
3414 
3415  if ( t < 1 || tri_num < t )
3416  {
3417  cout << "\n";
3418  cout << " Sorry, this data does not use the DTRIS2\n";
3419  cout << " convention for convex hull segments.\n";
3420  skip = true;
3421  break;
3422  }
3423 
3424  s1 = ( s % 3 ) + 1;
3425  s2 = i_wrap ( s1+1, 1, 3 );
3426  k = k + 1;
3427  n1 = tri_vert[s1-1+(t-1)*3];
3428  n2 = tri_vert[s2-1+(t-1)*3];
3429  cout << setw(4) << k << " "
3430  << setw(4) << t << " "
3431  << setw(4) << s1 << " "
3432  << setw(4) << n1 << " "
3433  << setw(4) << n2 << "\n";
3434  }
3435 
3436  }
3437 
3438  if ( skip )
3439  {
3440  break;
3441  }
3442 
3443  }
3444 
3445  return;
3446 # undef DIM_NUM
3447 }
3448 //******************************************************************************
3449 
3450 void vbedg ( double x, double y, int point_num, double point_xy[], int tri_num,
3451  int tri_vert[], int tri_nabe[], int *ltri, int *ledg, int *rtri, int *redg )
3452 
3453 //******************************************************************************
3454 //
3455 // Purpose:
3456 //
3457 // VBEDG determines which boundary edges are visible to a point.
3458 //
3459 // Discussion:
3460 //
3461 // The point (X,Y) is assumed to be outside the convex hull of the
3462 // region covered by the 2D triangulation.
3463 //
3464 // Author:
3465 //
3466 // Barry Joe,
3467 // Department of Computing Science,
3468 // University of Alberta,
3469 // Edmonton, Alberta, Canada T6G 2H1
3470 //
3471 // Reference:
3472 //
3473 // Barry Joe,
3474 // GEOMPACK - a software package for the generation of meshes
3475 // using geometric algorithms,
3476 // Advances in Engineering Software,
3477 // Volume 13, pages 325-331, 1991.
3478 //
3479 // Modified:
3480 //
3481 // 02 September 2003
3482 //
3483 // Parameters:
3484 //
3485 // Input, double X, Y, the coordinates of a point outside the convex hull
3486 // of the current triangulation.
3487 //
3488 // Input, int POINT_NUM, the number of points.
3489 //
3490 // Input, double POINT_XY[POINT_NUM*2], the coordinates of the vertices.
3491 //
3492 // Input, int TRI_NUM, the number of triangles.
3493 //
3494 // Input, int TRI_VERT[TRI_NUM*3], the triangle incidence list.
3495 //
3496 // Input, int TRI_NABE[TRI_NUM*3], the triangle neighbor list; negative
3497 // values are used for links of a counter clockwise linked list of boundary
3498 // edges;
3499 // LINK = -(3*I + J-1) where I, J = triangle, edge index.
3500 //
3501 // Input/output, int *LTRI, *LEDG. If LTRI != 0 then these values are
3502 // assumed to be already computed and are not changed, else they are updated.
3503 // On output, LTRI is the index of boundary triangle to the left of the
3504 // leftmost boundary triangle visible from (X,Y), and LEDG is the boundary
3505 // edge of triangle LTRI to the left of the leftmost boundary edge visible
3506 // from (X,Y). 1 <= LEDG <= 3.
3507 //
3508 // Input/output, int *RTRI. On input, the index of the boundary triangle
3509 // to begin the search at. On output, the index of the rightmost boundary
3510 // triangle visible from (X,Y).
3511 //
3512 // Input/output, int *REDG, the edge of triangle RTRI that is visible
3513 // from (X,Y). 1 <= REDG <= 3.
3514 //
3515 {
3516  int a;
3517  double ax;
3518  double ay;
3519  int b;
3520  double bx;
3521  double by;
3522  bool done;
3523  int e;
3524  int l;
3525  int lr;
3526  int t;
3527 //
3528 // Find the rightmost visible boundary edge using links, then possibly
3529 // leftmost visible boundary edge using triangle neighbor information.
3530 //
3531  if ( *ltri == 0 )
3532  {
3533  done = false;
3534  *ltri = *rtri;
3535  *ledg = *redg;
3536  }
3537  else
3538  {
3539  done = true;
3540  }
3541 
3542  for ( ; ; )
3543  {
3544  l = -tri_nabe[3*((*rtri)-1)+(*redg)-1];
3545  t = l / 3;
3546  e = 1 + l % 3;
3547  a = tri_vert[3*(t-1)+e-1];
3548 
3549  if ( e <= 2 )
3550  {
3551  b = tri_vert[3*(t-1)+e];
3552  }
3553  else
3554  {
3555  b = tri_vert[3*(t-1)+0];
3556  }
3557 
3558  ax = point_xy[2*(a-1)+0];
3559  ay = point_xy[2*(a-1)+1];
3560 
3561  bx = point_xy[2*(b-1)+0];
3562  by = point_xy[2*(b-1)+1];
3563 
3564  lr = lrline ( x, y, ax, ay, bx, by, 0.0 );
3565 
3566  if ( lr <= 0 )
3567  {
3568  break;
3569  }
3570 
3571  *rtri = t;
3572  *redg = e;
3573 
3574  }
3575 
3576  if ( done )
3577  {
3578  return;
3579  }
3580 
3581  t = *ltri;
3582  e = *ledg;
3583 
3584  for ( ; ; )
3585  {
3586  b = tri_vert[3*(t-1)+e-1];
3587  e = i_wrap ( e-1, 1, 3 );
3588 
3589  while ( 0 < tri_nabe[3*(t-1)+e-1] )
3590  {
3591  t = tri_nabe[3*(t-1)+e-1];
3592 
3593  if ( tri_vert[3*(t-1)+0] == b )
3594  {
3595  e = 3;
3596  }
3597  else if ( tri_vert[3*(t-1)+1] == b )
3598  {
3599  e = 1;
3600  }
3601  else
3602  {
3603  e = 2;
3604  }
3605 
3606  }
3607 
3608  a = tri_vert[3*(t-1)+e-1];
3609  ax = point_xy[2*(a-1)+0];
3610  ay = point_xy[2*(a-1)+1];
3611 
3612  bx = point_xy[2*(b-1)+0];
3613  by = point_xy[2*(b-1)+1];
3614 
3615  lr = lrline ( x, y, ax, ay, bx, by, 0.0 );
3616 
3617  if ( lr <= 0 )
3618  {
3619  break;
3620  }
3621 
3622  }
3623 
3624  *ltri = t;
3625  *ledg = e;
3626 
3627  return;
3628 }
int s_len_trim(const char *s)
Definition: geompack.C:2568
void timestamp(void)
Definition: geompack.C:2890
void imat_transpose_print(int m, int n, int a[], const char *title)
Definition: geompack.C:1787
int i_wrap(int ival, int ilo, int ihi)
Definition: geompack.C:1715
void vbedg(double x, double y, int point_num, double point_xy[], int tri_num, int tri_vert[], int tri_nabe[], int *ltri, int *ledg, int *rtri, int *redg)
Definition: geompack.C:3450
bool dvec_lt(int n, double a1[], double a2[])
Definition: geompack.C:1396
int * d2vec_sort_heap_index_a(int n, double a[])
Definition: geompack.C:384
#define TIME_SIZE
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
int i_sign(int i)
Definition: geompack.C:1676
void ivec_sorted_unique(int n, int a[], int *nuniq)
Definition: geompack.C:2152
dimensionedScalar yn(const int n, const dimensionedScalar &ds)
void d2vec_sort_quick_a(int n, double a[])
Definition: geompack.C:514
dimensionedScalar sqrt(const dimensionedScalar &ds)
int * ivec_indicator(int n)
Definition: geompack.C:2041
double * triangle_circumcenter_2d(double t[])
Definition: geompack.C:2980
double d_epsilon(void)
Definition: geompack.C:19
dimensionedScalar y0(const dimensionedScalar &ds)
label k
Boltzmann constant.
void dmat_transpose_print(int m, int n, double a[], const char *title)
Definition: geompack.C:749
void triangulation_print(int point_num, double xc[], int tri_num, int tri_vert[], int tri_nabe[])
Definition: geompack.C:3280
bool dvec_gt(int n, double a1[], double a2[])
Definition: geompack.C:1342
bool triangulation_plot_eps(const char *file_out_name, int g_num, double g_xy[], int tri_num, int nod_tri[])
Definition: geompack.C:3053
#define LEVEL_MAX
void perm_inv(int n, int p[])
Definition: geompack.C:2346
scalar y
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
void dmat_transpose_print_some(int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, const char *title)
Definition: geompack.C:780
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
double d_max(double x, double y)
Definition: geompack.C:61
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
int lrline(double xu, double yu, double xv1, double yv1, double xv2, double yv2, double dv)
Definition: geompack.C:2203
void dmat_uniform(int m, int n, double b, double c, int *seed, double r[])
Definition: geompack.C:866
void dvec_print(int n, double a[], const char *title)
Definition: geompack.C:1449
#define DIM_NUM
int i_min(int i1, int i2)
Definition: geompack.C:1566
dimensionedScalar y1(const dimensionedScalar &ds)
int * points_delaunay_naive_2d(int n, double p[], int *ntri)
Definition: geompack.C:2433
const uniformDimensionedVectorField & g
void imat_transpose_print_some(int m, int n, int a[], int ilo, int jlo, int ihi, int jhi, const char *title)
Definition: geompack.C:1820
char * timestring(void)
Definition: geompack.C:2937
labelList f(nPoints)
#define INCX
void ivec_sort_heap_a(int n, int a[])
Definition: geompack.C:2078
int i_modp(int i, int j)
Definition: geompack.C:1601
bool perm_check(int n, int p[])
Definition: geompack.C:2288
int dtris2(int point_num, double point_xy[], int *tri_num, int tri_vert[], int tri_nabe[])
Definition: geompack.C:953
void d2vec_part_quick_a(int n, double a[], int *l, int *r)
Definition: geompack.C:129
void ivec_heap_d(int n, int a[])
Definition: geompack.C:1917
void d2vec_permute(int n, double a[], int p[])
Definition: geompack.C:259
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
int diaedg(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3)
Definition: geompack.C:632
const dimensionedScalar c
Speed of light in a vacuum.
label n
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
volScalarField & p
double d_min(double x, double y)
Definition: geompack.C:95
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void dvec_swap(int n, double a1[], double a2[])
Definition: geompack.C:1494
bool found
bool dvec_eq(int n, double a1[], double a2[])
Definition: geompack.C:1301
int swapec(int i, int *top, int *btri, int *bedg, int point_num, double point_xy[], int tri_num, int tri_vert[], int tri_nabe[], int stack[])
Definition: geompack.C:2612
int i_max(int i1, int i2)
Definition: geompack.C:1531