FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

geompack.C

Go to the documentation of this file.
00001 # include <cstdlib>
00002 # include <iostream>
00003 # include <iomanip>
00004 # include <fstream>
00005 # include <cmath>
00006 # include <ctime>
00007 # include <cstring>
00008 
00009 using namespace std;
00010 
00011 # include <meshTools/geompack.H>
00012 
00013 //******************************************************************************
00014 
00015 double d_epsilon ( void )
00016 
00017 //******************************************************************************
00018 //
00019 //  Purpose:
00020 //
00021 //    D_EPSILON returns the round off unit for double precision arithmetic.
00022 //
00023 //  Discussion:
00024 //
00025 //    D_EPSILON is a number R which is a power of 2 with the property that,
00026 //    to the precision of the computer's arithmetic,
00027 //      1 < 1 + R
00028 //    but
00029 //      1 = ( 1 + R / 2 )
00030 //
00031 //  Modified:
00032 //
00033 //    06 May 2003
00034 //
00035 //  Author:
00036 //
00037 //    John Burkardt
00038 //
00039 //  Parameters:
00040 //
00041 //    Output, double D_EPSILON, the floating point round-off unit.
00042 //
00043 {
00044     double r = 1.0;
00045 
00046     while (1.0 < 1.0 + r)
00047     {
00048         r = r/2.0;
00049     }
00050 
00051     return 2.0*r;
00052 }
00053 
00054 
00055 //*********************************************************************
00056 
00057 double d_max ( double x, double y )
00058 
00059 //*********************************************************************
00060 //
00061 //  Purpose:
00062 //
00063 //    D_MAX returns the maximum of two real values.
00064 //
00065 //  Modified:
00066 //
00067 //    10 January 2002
00068 //
00069 //  Author:
00070 //
00071 //    John Burkardt
00072 //
00073 //  Parameters:
00074 //
00075 //    Input, double X, Y, the quantities to compare.
00076 //
00077 //    Output, double D_MAX, the maximum of X and Y.
00078 //
00079 {
00080   if ( y < x )
00081   {
00082     return x;
00083   }
00084   else
00085   {
00086     return y;
00087   }
00088 }
00089 //*********************************************************************
00090 
00091 double d_min ( double x, double y )
00092 
00093 //*********************************************************************
00094 //
00095 //  Purpose:
00096 //
00097 //    D_MIN returns the minimum of two real values.
00098 //
00099 //  Modified:
00100 //
00101 //    09 May 2003
00102 //
00103 //  Author:
00104 //
00105 //    John Burkardt
00106 //
00107 //  Parameters:
00108 //
00109 //    Input, double X, Y, the quantities to compare.
00110 //
00111 //    Output, double D_MIN, the minimum of X and Y.
00112 //
00113 {
00114   if ( y < x )
00115   {
00116     return y;
00117   }
00118   else
00119   {
00120     return x;
00121   }
00122 }
00123 //******************************************************************************
00124 
00125 void d2vec_part_quick_a ( int n, double a[], int *l, int *r )
00126 
00127 //******************************************************************************
00128 //
00129 //  Purpose:
00130 //
00131 //    D2VEC_PART_QUICK_A reorders an R2 vector as part of a quick sort.
00132 //
00133 //  Discussion:
00134 //
00135 //    The routine reorders the entries of A.  Using A(1:2,1) as a
00136 //    key, all entries of A that are less than or equal to the key will
00137 //    precede the key, which precedes all entries that are greater than the key.
00138 //
00139 //  Example:
00140 //
00141 //    Input:
00142 //
00143 //      N = 8
00144 //
00145 //      A = ( (2,4), (8,8), (6,2), (0,2), (10,6), (10,0), (0,6), (4,8) )
00146 //
00147 //    Output:
00148 //
00149 //      L = 2, R = 4
00150 //
00151 //      A = ( (0,2), (0,6), (2,4), (8,8), (6,2), (10,6), (10,0), (4,8) )
00152 //             -----------          ----------------------------------
00153 //             LEFT          KEY    RIGHT
00154 //
00155 //  Modified:
00156 //
00157 //    01 September 2003
00158 //
00159 //  Author:
00160 //
00161 //    John Burkardt
00162 //
00163 //  Parameters:
00164 //
00165 //    Input, int N, the number of entries of A.
00166 //
00167 //    Input/output, double A[N*2].  On input, the array to be checked.
00168 //    On output, A has been reordered as described above.
00169 //
00170 //    Output, int *L, *R, the indices of A that define the three segments.
00171 //    Let KEY = the input value of A(1:2,1).  Then
00172 //    I <= L                 A(1:2,I) < KEY;
00173 //         L < I < R         A(1:2,I) = KEY;
00174 //                 R <= I    A(1:2,I) > KEY.
00175 //
00176 {
00177   int i;
00178   int j;
00179   double key[2];
00180   int ll;
00181   int m;
00182   int rr;
00183 
00184   if ( n < 1 )
00185   {
00186     cout << "\n";
00187     cout << "D2VEC_PART_QUICK_A - Fatal error!\n";
00188     cout << "  N < 1.\n";
00189     exit ( 1 );
00190   }
00191 
00192   if ( n == 1 )
00193   {
00194     *l = 0;
00195     *r = 2;
00196     return;
00197   }
00198 
00199   key[0] = a[2*0+0];
00200   key[1] = a[2*0+1];
00201   m = 1;
00202 //
00203 //  The elements of unknown size have indices between L+1 and R-1.
00204 //
00205   ll = 1;
00206   rr = n + 1;
00207 
00208   for ( i = 2; i <= n; i++ )
00209   {
00210     if ( dvec_gt ( 2, a+2*ll, key ) )
00211     {
00212       rr = rr - 1;
00213       dvec_swap ( 2, a+2*(rr-1), a+2*ll );
00214     }
00215     else if ( dvec_eq ( 2, a+2*ll, key ) )
00216     {
00217       m = m + 1;
00218       dvec_swap ( 2, a+2*(m-1), a+2*ll );
00219       ll = ll + 1;
00220     }
00221     else if ( dvec_lt ( 2, a+2*ll, key ) )
00222     {
00223       ll = ll + 1;
00224     }
00225 
00226   }
00227 //
00228 //  Now shift small elements to the left, and KEY elements to center.
00229 //
00230   for ( i = 0; i < ll - m; i++ )
00231   {
00232     for ( j = 0; j < 2; j++ )
00233     {
00234       a[2*i+j] = a[2*(i+m)+j];
00235     }
00236   }
00237 
00238   ll = ll - m;
00239 
00240   for ( i = ll; i < ll+m; i++ )
00241   {
00242     for ( j = 0; j < 2; j++ )
00243     {
00244       a[2*i+j] = key[j];
00245     }
00246   }
00247 
00248   *l = ll;
00249   *r = rr;
00250 
00251   return;
00252 }
00253 //*******************************************************************************
00254 
00255 void d2vec_permute ( int n, double a[], int p[] )
00256 
00257 //*******************************************************************************
00258 //
00259 //  Purpose:
00260 //
00261 //    D2VEC_PERMUTE permutes an R2 vector in place.
00262 //
00263 //  Discussion:
00264 //
00265 //    This routine permutes an array of real "objects", but the same
00266 //    logic can be used to permute an array of objects of any arithmetic
00267 //    type, or an array of objects of any complexity.  The only temporary
00268 //    storage required is enough to store a single object.  The number
00269 //    of data movements made is N + the number of cycles of order 2 or more,
00270 //    which is never more than N + N/2.
00271 //
00272 //  Example:
00273 //
00274 //    Input:
00275 //
00276 //      N = 5
00277 //      P = (   2,    4,    5,    1,    3 )
00278 //      A = ( 1.0,  2.0,  3.0,  4.0,  5.0 )
00279 //          (11.0, 22.0, 33.0, 44.0, 55.0 )
00280 //
00281 //    Output:
00282 //
00283 //      A    = (  2.0,  4.0,  5.0,  1.0,  3.0 )
00284 //             ( 22.0, 44.0, 55.0, 11.0, 33.0 ).
00285 //
00286 //  Modified:
00287 //
00288 //    19 February 2004
00289 //
00290 //  Author:
00291 //
00292 //    John Burkardt
00293 //
00294 //  Parameters:
00295 //
00296 //    Input, int N, the number of objects.
00297 //
00298 //    Input/output, double A[2*N], the array to be permuted.
00299 //
00300 //    Input, int P[N], the permutation.  P(I) = J means
00301 //    that the I-th element of the output array should be the J-th
00302 //    element of the input array.  P must be a legal permutation
00303 //    of the integers from 1 to N, otherwise the algorithm will
00304 //    fail catastrophically.
00305 //
00306 {
00307   double a_temp[2];
00308   int i;
00309   int iget;
00310   int iput;
00311   int istart;
00312 
00313   if ( !perm_check ( n, p ) )
00314   {
00315     cout << "\n";
00316     cout << "D2VEC_PERMUTE - Fatal error!\n";
00317     cout << "  The input array does not represent\n";
00318     cout << "  a proper permutation.\n";
00319     exit ( 1 );
00320   }
00321 //
00322 //  Search for the next element of the permutation that has not been used.
00323 //
00324   for ( istart = 1; istart <= n; istart++ )
00325   {
00326     if ( p[istart-1] < 0 )
00327     {
00328       continue;
00329     }
00330     else if ( p[istart-1] == istart )
00331     {
00332       p[istart-1] = -p[istart-1];
00333       continue;
00334     }
00335     else
00336     {
00337       a_temp[0] = a[0+(istart-1)*2];
00338       a_temp[1] = a[1+(istart-1)*2];
00339       iget = istart;
00340 //
00341 //  Copy the new value into the vacated entry.
00342 //
00343       for ( ; ; )
00344       {
00345         iput = iget;
00346         iget = p[iget-1];
00347 
00348         p[iput-1] = -p[iput-1];
00349 
00350         if ( iget < 1 || n < iget )
00351         {
00352           cout << "\n";
00353           cout << "D2VEC_PERMUTE - Fatal error!\n";
00354           exit ( 1 );
00355         }
00356 
00357         if ( iget == istart )
00358         {
00359           a[0+(iput-1)*2] = a_temp[0];
00360           a[1+(iput-1)*2] = a_temp[1];
00361           break;
00362         }
00363         a[0+(iput-1)*2] = a[0+(iget-1)*2];
00364         a[1+(iput-1)*2] = a[1+(iget-1)*2];
00365       }
00366     }
00367   }
00368 //
00369 //  Restore the signs of the entries.
00370 //
00371   for ( i = 0; i < n; i++ )
00372   {
00373     p[i] = -p[i];
00374   }
00375 
00376   return;
00377 }
00378 //******************************************************************************
00379 
00380 int *d2vec_sort_heap_index_a ( int n, double a[] )
00381 
00382 //******************************************************************************
00383 //
00384 //  Purpose:
00385 //
00386 //    D2VEC_SORT_HEAP_INDEX_A does an indexed heap ascending sort of an R2 vector.
00387 //
00388 //  Discussion:
00389 //
00390 //    The sorting is not actually carried out.  Rather an index array is
00391 //    created which defines the sorting.  This array may be used to sort
00392 //    or index the array, or to sort or index related arrays keyed on the
00393 //    original array.
00394 //
00395 //    Once the index array is computed, the sorting can be carried out
00396 //    "implicitly:
00397 //
00398 //      A(1:2,INDX(I)), I = 1 to N is sorted,
00399 //
00400 //    or explicitly, by the call
00401 //
00402 //      call D2VEC_PERMUTE ( N, A, INDX )
00403 //
00404 //    after which A(1:2,I), I = 1 to N is sorted.
00405 //
00406 //  Modified:
00407 //
00408 //    13 January 2004
00409 //
00410 //  Author:
00411 //
00412 //    John Burkardt
00413 //
00414 //  Parameters:
00415 //
00416 //    Input, int N, the number of entries in the array.
00417 //
00418 //    Input, double A[2*N], an array to be index-sorted.
00419 //
00420 //    Output, int D2VEC_SORT_HEAP_INDEX_A[N], the sort index.  The
00421 //    I-th element of the sorted array is A(0:1,D2VEC_SORT_HEAP_INDEX_A(I-1)).
00422 //
00423 {
00424   double aval[2];
00425   int i;
00426   int *indx;
00427   int indxt;
00428   int ir;
00429   int j;
00430   int l;
00431 
00432   if ( n < 1 )
00433   {
00434     return NULL;
00435   }
00436 
00437   if ( n == 1 )
00438   {
00439     indx = new int[1];
00440     indx[0] = 1;
00441     return indx;
00442   }
00443 
00444   indx = ivec_indicator ( n );
00445 
00446   l = n / 2 + 1;
00447   ir = n;
00448 
00449   for ( ; ; )
00450   {
00451     if ( 1 < l )
00452     {
00453       l = l - 1;
00454       indxt = indx[l-1];
00455       aval[0] = a[0+(indxt-1)*2];
00456       aval[1] = a[1+(indxt-1)*2];
00457     }
00458     else
00459     {
00460       indxt = indx[ir-1];
00461       aval[0] = a[0+(indxt-1)*2];
00462       aval[1] = a[1+(indxt-1)*2];
00463       indx[ir-1] = indx[0];
00464       ir = ir - 1;
00465 
00466       if ( ir == 1 )
00467       {
00468         indx[0] = indxt;
00469         break;
00470       }
00471 
00472     }
00473 
00474     i = l;
00475     j = l + l;
00476 
00477     while ( j <= ir )
00478     {
00479       if ( j < ir )
00480       {
00481         if (   a[0+(indx[j-1]-1)*2] <  a[0+(indx[j]-1)*2] ||
00482              ( a[0+(indx[j-1]-1)*2] == a[0+(indx[j]-1)*2] &&
00483                a[1+(indx[j-1]-1)*2] <  a[1+(indx[j]-1)*2] ) )
00484         {
00485           j = j + 1;
00486         }
00487       }
00488 
00489       if (   aval[0] <  a[0+(indx[j-1]-1)*2] ||
00490            ( aval[0] == a[0+(indx[j-1]-1)*2] &&
00491              aval[1] <  a[1+(indx[j-1]-1)*2] ) )
00492       {
00493         indx[i-1] = indx[j-1];
00494         i = j;
00495         j = j + j;
00496       }
00497       else
00498       {
00499         j = ir + 1;
00500       }
00501     }
00502     indx[i-1] = indxt;
00503   }
00504 
00505   return indx;
00506 }
00507 //*****************************************************************************
00508 
00509 void d2vec_sort_quick_a ( int n, double a[] )
00510 
00511 //*****************************************************************************
00512 //
00513 //  Purpose:
00514 //
00515 //    D2VEC_SORT_QUICK_A ascending sorts an R2 vector using quick sort.
00516 //
00517 //  Discussion:
00518 //
00519 //    The data structure is a set of N pairs of real numbers.
00520 //    These values are stored in a one dimensional array, by pairs.
00521 //
00522 //  Modified:
00523 //
00524 //    01 September 2003
00525 //
00526 //  Author:
00527 //
00528 //    John Burkardt
00529 //
00530 //  Parameters:
00531 //
00532 //    Input, int N, the number of entries in the array.
00533 //
00534 //    Input/output, double A[N*2].
00535 //    On input, the array to be sorted.
00536 //    On output, the array has been sorted.
00537 //
00538 {
00539 # define LEVEL_MAX 25
00540 
00541   int base;
00542   int l_segment;
00543   int level;
00544   int n_segment;
00545   int rsave[LEVEL_MAX];
00546   int r_segment;
00547 
00548   if ( n < 1 )
00549   {
00550     cout << "\n";
00551     cout << "D2VEC_SORT_QUICK_A - Fatal error!\n";
00552     cout << "  N < 1.\n";
00553     exit ( 1 );
00554   }
00555 
00556   if ( n == 1 )
00557   {
00558     return;
00559   }
00560 
00561   level = 1;
00562   rsave[level-1] = n + 1;
00563   base = 1;
00564   n_segment = n;
00565 
00566   while ( 0 < n_segment )
00567   {
00568 //
00569 //  Partition the segment.
00570 //
00571     d2vec_part_quick_a ( n_segment, a+2*(base-1)+0, &l_segment, &r_segment );
00572 //
00573 //  If the left segment has more than one element, we need to partition it.
00574 //
00575     if ( 1 < l_segment )
00576     {
00577       if ( LEVEL_MAX < level )
00578       {
00579         cout << "\n";
00580         cout << "D2VEC_SORT_QUICK_A - Fatal error!\n";
00581         cout << "  Exceeding recursion maximum of " << LEVEL_MAX << "\n";
00582         exit ( 1 );
00583       }
00584 
00585       level = level + 1;
00586       n_segment = l_segment;
00587       rsave[level-1] = r_segment + base - 1;
00588     }
00589 //
00590 //  The left segment and the middle segment are sorted.
00591 //  Must the right segment be partitioned?
00592 //
00593     else if ( r_segment < n_segment )
00594     {
00595       n_segment = n_segment + 1 - r_segment;
00596       base = base + r_segment - 1;
00597     }
00598 //
00599 //  Otherwise, we back up a level if there is an earlier one.
00600 //
00601     else
00602     {
00603       for ( ; ; )
00604       {
00605         if ( level <= 1 )
00606         {
00607           n_segment = 0;
00608           break;
00609         }
00610 
00611         base = rsave[level-1];
00612         n_segment = rsave[level-2] - rsave[level-1];
00613         level = level - 1;
00614 
00615         if ( 0 < n_segment )
00616         {
00617           break;
00618         }
00619       }
00620     }
00621   }
00622   return;
00623 # undef LEVEL_MAX
00624 }
00625 //******************************************************************************
00626 
00627 int diaedg ( double x0, double y0, double x1, double y1, double x2, double y2,
00628   double x3, double y3 )
00629 
00630 //******************************************************************************
00631 //
00632 //  Purpose:
00633 //
00634 //    DIAEDG chooses a diagonal edge.
00635 //
00636 //  Discussion:
00637 //
00638 //    The routine determines whether 0--2 or 1--3 is the diagonal edge
00639 //    that should be chosen, based on the circumcircle criterion, where
00640 //    (X0,Y0), (X1,Y1), (X2,Y2), (X3,Y3) are the vertices of a simple
00641 //    quadrilateral in counterclockwise order.
00642 //
00643 //  Modified:
00644 //
00645 //    28 August 2003
00646 //
00647 //  Author:
00648 //
00649 //    Barry Joe,
00650 //    Department of Computing Science,
00651 //    University of Alberta,
00652 //    Edmonton, Alberta, Canada  T6G 2H1
00653 //
00654 //  Reference:
00655 //
00656 //    Barry Joe,
00657 //    GEOMPACK - a software package for the generation of meshes
00658 //    using geometric algorithms,
00659 //    Advances in Engineering Software,
00660 //    Volume 13, pages 325-331, 1991.
00661 //
00662 //  Parameters:
00663 //
00664 //    Input, double X0, Y0, X1, Y1, X2, Y2, X3, Y3, the coordinates of the
00665 //    vertices of a quadrilateral, given in counter clockwise order.
00666 //
00667 //    Output, int DIAEDG, chooses a diagonal:
00668 //    +1, if diagonal edge 02 is chosen;
00669 //    -1, if diagonal edge 13 is chosen;
00670 //     0, if the four vertices are cocircular.
00671 //
00672 {
00673   double ca;
00674   double cb;
00675   double dx10;
00676   double dx12;
00677   double dx30;
00678   double dx32;
00679   double dy10;
00680   double dy12;
00681   double dy30;
00682   double dy32;
00683   double s;
00684   double tol;
00685   double tola;
00686   double tolb;
00687   int value;
00688 
00689   tol = 100.0 * d_epsilon ( );
00690 
00691   dx10 = x1 - x0;
00692   dy10 = y1 - y0;
00693   dx12 = x1 - x2;
00694   dy12 = y1 - y2;
00695   dx30 = x3 - x0;
00696   dy30 = y3 - y0;
00697   dx32 = x3 - x2;
00698   dy32 = y3 - y2;
00699 
00700   tola = tol * d_max ( fabs ( dx10 ),
00701                d_max ( fabs ( dy10 ),
00702                d_max ( fabs ( dx30 ), fabs ( dy30 ) ) ) );
00703 
00704   tolb = tol * d_max ( fabs ( dx12 ),
00705                d_max ( fabs ( dy12 ),
00706                d_max ( fabs ( dx32 ), fabs ( dy32 ) ) ) );
00707 
00708   ca = dx10 * dx30 + dy10 * dy30;
00709   cb = dx12 * dx32 + dy12 * dy32;
00710 
00711   if ( tola < ca && tolb < cb )
00712   {
00713     value = -1;
00714   }
00715   else if ( ca < -tola && cb < -tolb )
00716   {
00717     value = 1;
00718   }
00719   else
00720   {
00721     tola = d_max ( tola, tolb );
00722     s = ( dx10 * dy30 - dx30 * dy10 ) * cb
00723       + ( dx32 * dy12 - dx12 * dy32 ) * ca;
00724 
00725     if ( tola < s )
00726     {
00727       value = -1;
00728     }
00729     else if ( s < -tola )
00730     {
00731       value = 1;
00732     }
00733     else
00734     {
00735       value = 0;
00736     }
00737 
00738   }
00739 
00740   return value;
00741 }
00742 //******************************************************************************
00743 
00744 void dmat_transpose_print ( int m, int n, double a[], const char *title )
00745 
00746 //******************************************************************************
00747 //
00748 //  Purpose:
00749 //
00750 //    DMAT_TRANSPOSE_PRINT prints a real matrix, transposed.
00751 //
00752 //  Modified:
00753 //
00754 //    11 August 2004
00755 //
00756 //  Author:
00757 //
00758 //    John Burkardt
00759 //
00760 //  Parameters:
00761 //
00762 //    Input, int M, N, the number of rows and columns.
00763 //
00764 //    Input, double A[M*N], an M by N matrix to be printed.
00765 //
00766 //    Input, const char *TITLE, an optional title.
00767 //
00768 {
00769   dmat_transpose_print_some ( m, n, a, 1, 1, m, n, title );
00770 
00771   return;
00772 }
00773 //******************************************************************************
00774 
00775 void dmat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo,
00776   int ihi, int jhi, const char *title )
00777 
00778 //******************************************************************************
00779 //
00780 //  Purpose:
00781 //
00782 //    DMAT_TRANSPOSE_PRINT_SOME prints some of a real matrix, transposed.
00783 //
00784 //  Modified:
00785 //
00786 //    11 August 2004
00787 //
00788 //  Author:
00789 //
00790 //    John Burkardt
00791 //
00792 //  Parameters:
00793 //
00794 //    Input, int M, N, the number of rows and columns.
00795 //
00796 //    Input, double A[M*N], an M by N matrix to be printed.
00797 //
00798 //    Input, int ILO, JLO, the first row and column to print.
00799 //
00800 //    Input, int IHI, JHI, the last row and column to print.
00801 //
00802 //    Input, const char *TITLE, an optional title.
00803 //
00804 {
00805 # define INCX 5
00806 
00807   int i;
00808   int i2;
00809   int i2hi;
00810   int i2lo;
00811   int inc;
00812   int j;
00813   int j2hi;
00814   int j2lo;
00815 
00816   if ( 0 < s_len_trim ( title ) )
00817   {
00818     cout << "\n";
00819     cout << title << "\n";
00820   }
00821 
00822   for ( i2lo = i_max ( ilo, 1 ); i2lo <= i_min ( ihi, m ); i2lo = i2lo + INCX )
00823   {
00824     i2hi = i2lo + INCX - 1;
00825     i2hi = i_min ( i2hi, m );
00826     i2hi = i_min ( i2hi, ihi );
00827 
00828     inc = i2hi + 1 - i2lo;
00829 
00830     cout << "\n";
00831     cout << "  Row: ";
00832     for ( i = i2lo; i <= i2hi; i++ )
00833     {
00834       cout << setw(7) << i << "       ";
00835     }
00836     cout << "\n";
00837     cout << "  Col\n";
00838     cout << "\n";
00839 
00840     j2lo = i_max ( jlo, 1 );
00841     j2hi = i_min ( jhi, n );
00842 
00843     for ( j = j2lo; j <= j2hi; j++ )
00844     {
00845       cout << setw(5) << j << " ";
00846       for ( i2 = 1; i2 <= inc; i2++ )
00847       {
00848         i = i2lo - 1 + i2;
00849         cout << setw(14) << a[(i-1)+(j-1)*m];
00850       }
00851       cout << "\n";
00852     }
00853   }
00854   cout << "\n";
00855 
00856   return;
00857 # undef INCX
00858 }
00859 //******************************************************************************
00860 
00861 void dmat_uniform ( int m, int n, double b, double c, int *seed, double r[] )
00862 
00863 //******************************************************************************
00864 //
00865 //  Purpose:
00866 //
00867 //    DMAT_UNIFORM fills a double precision array with scaled pseudorandom values.
00868 //
00869 //  Discussion:
00870 //
00871 //    This routine implements the recursion
00872 //
00873 //      seed = 16807 * seed mod ( 2**31 - 1 )
00874 //      unif = seed / ( 2**31 - 1 )
00875 //
00876 //    The integer arithmetic never requires more than 32 bits,
00877 //    including a sign bit.
00878 //
00879 //  Modified:
00880 //
00881 //    30 January 2005
00882 //
00883 //  Author:
00884 //
00885 //    John Burkardt
00886 //
00887 //  Reference:
00888 //
00889 //    Paul Bratley, Bennett Fox, Linus Schrage,
00890 //    A Guide to Simulation,
00891 //    Springer Verlag, pages 201-202, 1983.
00892 //
00893 //    Bennett Fox,
00894 //    Algorithm 647:
00895 //    Implementation and Relative Efficiency of Quasirandom
00896 //    Sequence Generators,
00897 //    ACM Transactions on Mathematical Software,
00898 //    Volume 12, Number 4, pages 362-376, 1986.
00899 //
00900 //    Peter Lewis, Allen Goodman, James Miller,
00901 //    A Pseudo-Random Number Generator for the System/360,
00902 //    IBM Systems Journal,
00903 //    Volume 8, pages 136-143, 1969.
00904 //
00905 //  Parameters:
00906 //
00907 //    Input, int M, N, the number of rows and columns.
00908 //
00909 //    Input, double B, C, the limits of the pseudorandom values.
00910 //
00911 //    Input/output, int *SEED, the "seed" value.  Normally, this
00912 //    value should not be 0, otherwise the output value of SEED
00913 //    will still be 0, and D_UNIFORM will be 0.  On output, SEED has
00914 //    been updated.
00915 //
00916 //    Output, double DMAT_UNIFORM[M*N], a matrix of pseudorandom values.
00917 //
00918 {
00919   int i;
00920   int j;
00921   int k;
00922 
00923   for ( j = 0; j < n; j++ )
00924   {
00925     for ( i = 0; i < m; i++ )
00926     {
00927       k = *seed / 127773;
00928 
00929       *seed = 16807 * ( *seed - k * 127773 ) - k * 2836;
00930 
00931       if ( *seed < 0 )
00932       {
00933         *seed = *seed + 2147483647;
00934       }
00935 //
00936 //  Although SEED can be represented exactly as a 32 bit integer,
00937 //  it generally cannot be represented exactly as a 32 bit real number!
00938 //
00939       r[i+j*m] = b + ( c - b ) * double( *seed ) * 4.656612875E-10;
00940     }
00941   }
00942 
00943   return;
00944 }
00945 //******************************************************************************
00946 
00947 int dtris2 ( int point_num, double point_xy[], int *tri_num,
00948   int tri_vert[], int tri_nabe[] )
00949 
00950 //******************************************************************************
00951 //
00952 //  Purpose:
00953 //
00954 //    DTRIS2 constructs a Delaunay triangulation of 2D vertices.
00955 //
00956 //  Discussion:
00957 //
00958 //    The routine constructs the Delaunay triangulation of a set of 2D vertices
00959 //    using an incremental approach and diagonal edge swaps.  Vertices are
00960 //    first sorted in lexicographically increasing (X,Y) order, and
00961 //    then are inserted one at a time from outside the convex hull.
00962 //
00963 //  Modified:
00964 //
00965 //    15 January 2004
00966 //
00967 //  Author:
00968 //
00969 //    Barry Joe,
00970 //    Department of Computing Science,
00971 //    University of Alberta,
00972 //    Edmonton, Alberta, Canada  T6G 2H1
00973 //
00974 //  Reference:
00975 //
00976 //    Barry Joe,
00977 //    GEOMPACK - a software package for the generation of meshes
00978 //    using geometric algorithms,
00979 //    Advances in Engineering Software,
00980 //    Volume 13, pages 325-331, 1991.
00981 //
00982 //  Parameters:
00983 //
00984 //    Input, int POINT_NUM, the number of vertices.
00985 //
00986 //    Input/output, double POINT_XY[POINT_NUM*2], the coordinates of the vertices.
00987 //    On output, the vertices have been sorted into dictionary order.
00988 //
00989 //    Output, int *TRI_NUM, the number of triangles in the triangulation;
00990 //    TRI_NUM is equal to 2*POINT_NUM - NB - 2, where NB is the number
00991 //    of boundary vertices.
00992 //
00993 //    Output, int TRI_VERT[TRI_NUM*3], the nodes that make up each triangle.
00994 //    The elements are indices of POINT_XY.  The vertices of the triangles are
00995 //    in counter clockwise order.
00996 //
00997 //    Output, int TRI_NABE[TRI_NUM*3], the triangle neighbor list.
00998 //    Positive elements are indices of TIL; negative elements are used for links
00999 //    of a counter clockwise linked list of boundary edges; LINK = -(3*I + J-1)
01000 //    where I, J = triangle, edge index; TRI_NABE[I,J] refers to
01001 //    the neighbor along edge from vertex J to J+1 (mod 3).
01002 //
01003 //    Output, int DTRIS2, is 0 for no error.
01004 {
01005   double cmax;
01006   int e;
01007   int error;
01008   int i;
01009   int *indx;
01010   int j;
01011   int k;
01012   int l;
01013   int ledg;
01014   int lr;
01015   int ltri;
01016   int m;
01017   int m1;
01018   int m2;
01019   int n;
01020   int redg;
01021   int rtri;
01022   int *stack;
01023   int t;
01024   double tol;
01025   int top;
01026 
01027   stack = new int[point_num];
01028 
01029   tol = 100.0 * d_epsilon ( );
01030 //
01031 //  Sort the vertices by increasing (x,y).
01032 //
01033   indx = d2vec_sort_heap_index_a ( point_num, point_xy );
01034 
01035   d2vec_permute ( point_num, point_xy, indx );
01036 //
01037 //  Make sure that the data points are "reasonably" distinct.
01038 //
01039   m1 = 1;
01040 
01041   for ( i = 2; i <= point_num; i++ )
01042   {
01043     m = m1;
01044     m1 = i;
01045 
01046     k = -1;
01047 
01048     for ( j = 0; j <= 1; j++ )
01049     {
01050       cmax = d_max ( fabs ( point_xy[2*(m-1)+j] ),
01051                      fabs ( point_xy[2*(m1-1)+j] ) );
01052 
01053       if ( tol * ( cmax + 1.0 )
01054            < fabs ( point_xy[2*(m-1)+j] - point_xy[2*(m1-1)+j] ) )
01055       {
01056         k = j;
01057         break;
01058       }
01059 
01060     }
01061 
01062     if ( k == -1 )
01063     {
01064       cout << "\n";
01065       cout << "DTRIS2 - Fatal error!\n";
01066       cout << "  Fails for point number I = " << i << "\n";
01067       cout << "  M =  " << m  << "\n";
01068       cout << "  M1 = " << m1 << "\n";
01069       cout << "  X,Y(M)  = " << point_xy[2*(m-1)+0] << "  "
01070                              << point_xy[2*(m-1)+1] << "\n";
01071       cout << "  X,Y(M1) = " << point_xy[2*(m1-1)+0] << "  "
01072                              << point_xy[2*(m1-1)+1] << "\n";
01073       delete [] stack;
01074       return 224;
01075     }
01076 
01077   }
01078 //
01079 //  Starting from points M1 and M2, search for a third point M that
01080 //  makes a "healthy" triangle (M1,M2,M)
01081 //
01082   m1 = 1;
01083   m2 = 2;
01084   j = 3;
01085 
01086   for ( ; ; )
01087   {
01088     if ( point_num < j )
01089     {
01090       cout << "\n";
01091       cout << "DTRIS2 - Fatal error!\n";
01092       delete [] stack;
01093       return 225;
01094     }
01095 
01096     m = j;
01097 
01098     lr = lrline ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1],
01099       point_xy[2*(m1-1)+0], point_xy[2*(m1-1)+1],
01100       point_xy[2*(m2-1)+0], point_xy[2*(m2-1)+1], 0.0 );
01101 
01102     if ( lr != 0 )
01103     {
01104       break;
01105     }
01106 
01107     j = j + 1;
01108 
01109   }
01110 //
01111 //  Set up the triangle information for (M1,M2,M), and for any other
01112 //  triangles you created because points were collinear with M1, M2.
01113 //
01114   *tri_num = j - 2;
01115 
01116   if ( lr == -1 )
01117   {
01118     tri_vert[3*0+0] = m1;
01119     tri_vert[3*0+1] = m2;
01120     tri_vert[3*0+2] = m;
01121     tri_nabe[3*0+2] = -3;
01122 
01123     for ( i = 2; i <= *tri_num; i++ )
01124     {
01125       m1 = m2;
01126       m2 = i+1;
01127       tri_vert[3*(i-1)+0] = m1;
01128       tri_vert[3*(i-1)+1] = m2;
01129       tri_vert[3*(i-1)+2] = m;
01130       tri_nabe[3*(i-1)+0] = -3 * i;
01131       tri_nabe[3*(i-1)+1] = i;
01132       tri_nabe[3*(i-1)+2] = i - 1;
01133 
01134     }
01135 
01136     tri_nabe[3*(*tri_num-1)+0] = -3 * (*tri_num) - 1;
01137     tri_nabe[3*(*tri_num-1)+1] = -5;
01138     ledg = 2;
01139     ltri = *tri_num;
01140   }
01141   else
01142   {
01143     tri_vert[3*0+0] = m2;
01144     tri_vert[3*0+1] = m1;
01145     tri_vert[3*0+2] = m;
01146     tri_nabe[3*0+0] = -4;
01147 
01148     for ( i = 2; i <= *tri_num; i++ )
01149     {
01150       m1 = m2;
01151       m2 = i+1;
01152       tri_vert[3*(i-1)+0] = m2;
01153       tri_vert[3*(i-1)+1] = m1;
01154       tri_vert[3*(i-1)+2] = m;
01155       tri_nabe[3*(i-2)+2] = i;
01156       tri_nabe[3*(i-1)+0] = -3 * i - 3;
01157       tri_nabe[3*(i-1)+1] = i - 1;
01158     }
01159 
01160     tri_nabe[3*(*tri_num-1)+2] = -3 * (*tri_num);
01161     tri_nabe[3*0+1] = -3 * (*tri_num) - 2;
01162     ledg = 2;
01163     ltri = 1;
01164   }
01165 //
01166 //  Insert the vertices one at a time from outside the convex hull,
01167 //  determine visible boundary edges, and apply diagonal edge swaps until
01168 //  Delaunay triangulation of vertices (so far) is obtained.
01169 //
01170   top = 0;
01171 
01172   for ( i = j+1; i <= point_num; i++ )
01173   {
01174     m = i;
01175     m1 = tri_vert[3*(ltri-1)+ledg-1];
01176 
01177     if ( ledg <= 2 )
01178     {
01179       m2 = tri_vert[3*(ltri-1)+ledg];
01180     }
01181     else
01182     {
01183       m2 = tri_vert[3*(ltri-1)+0];
01184     }
01185 
01186     lr = lrline ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1],
01187       point_xy[2*(m1-1)+0], point_xy[2*(m1-1)+1],
01188       point_xy[2*(m2-1)+0], point_xy[2*(m2-1)+1], 0.0 );
01189 
01190     if ( 0 < lr )
01191     {
01192       rtri = ltri;
01193       redg = ledg;
01194       ltri = 0;
01195     }
01196     else
01197     {
01198       l = -tri_nabe[3*(ltri-1)+ledg-1];
01199       rtri = l / 3;
01200       redg = (l % 3) + 1;
01201     }
01202 
01203     vbedg ( point_xy[2*(m-1)+0], point_xy[2*(m-1)+1], point_num,
01204       point_xy, *tri_num, tri_vert, tri_nabe, &ltri, &ledg, &rtri, &redg );
01205 
01206     n = *tri_num + 1;
01207     l = -tri_nabe[3*(ltri-1)+ledg-1];
01208 
01209     for ( ; ; )
01210     {
01211       t = l / 3;
01212       e = ( l % 3 ) + 1;
01213       l = -tri_nabe[3*(t-1)+e-1];
01214       m2 = tri_vert[3*(t-1)+e-1];
01215 
01216       if ( e <= 2 )
01217       {
01218         m1 = tri_vert[3*(t-1)+e];
01219       }
01220       else
01221       {
01222         m1 = tri_vert[3*(t-1)+0];
01223       }
01224 
01225       *tri_num = *tri_num + 1;
01226       tri_nabe[3*(t-1)+e-1] = *tri_num;
01227       tri_vert[3*(*tri_num-1)+0] = m1;
01228       tri_vert[3*(*tri_num-1)+1] = m2;
01229       tri_vert[3*(*tri_num-1)+2] = m;
01230       tri_nabe[3*(*tri_num-1)+0] = t;
01231       tri_nabe[3*(*tri_num-1)+1] = *tri_num - 1;
01232       tri_nabe[3*(*tri_num-1)+2] = *tri_num + 1;
01233       top = top + 1;
01234 
01235       if ( point_num < top )
01236       {
01237         cout << "\n";
01238         cout << "DTRIS2 - Fatal error!\n";
01239         cout << "  Stack overflow.\n";
01240         delete [] stack;
01241         return 8;
01242       }
01243 
01244       stack[top-1] = *tri_num;
01245 
01246       if ( t == rtri && e == redg )
01247       {
01248         break;
01249       }
01250 
01251     }
01252 
01253     tri_nabe[3*(ltri-1)+ledg-1] = -3 * n - 1;
01254     tri_nabe[3*(n-1)+1] = -3 * (*tri_num) - 2;
01255     tri_nabe[3*(*tri_num-1)+2] = -l;
01256     ltri = n;
01257     ledg = 2;
01258 
01259     error = swapec ( m, &top, &ltri, &ledg, point_num, point_xy, *tri_num,
01260       tri_vert, tri_nabe, stack );
01261 
01262     if ( error != 0 )
01263     {
01264       cout << "\n";
01265       cout << "DTRIS2 - Fatal error!\n";
01266       cout << "  Error return from SWAPEC.\n";
01267       delete [] stack;
01268       return error;
01269     }
01270 
01271   }
01272 //
01273 //  Now account for the sorting that we did.
01274 //
01275   for ( i = 0; i < 3; i++ )
01276   {
01277     for ( j = 0; j < *tri_num; j++ )
01278     {
01279       tri_vert[i+j*3] = indx [ tri_vert[i+j*3] - 1 ];
01280     }
01281   }
01282 
01283   perm_inv ( point_num, indx );
01284 
01285   d2vec_permute ( point_num, point_xy, indx );
01286 
01287   delete [] indx;
01288   delete [] stack;
01289 
01290   return 0;
01291 }
01292 //******************************************************************************
01293 
01294 bool dvec_eq ( int n, double a1[], double a2[] )
01295 
01296 //******************************************************************************
01297 //
01298 //  Purpose:
01299 //
01300 //    DVEC_EQ is true if every pair of entries in two vectors is equal.
01301 //
01302 //  Modified:
01303 //
01304 //    28 August 2003
01305 //
01306 //  Author:
01307 //
01308 //    John Burkardt
01309 //
01310 //  Parameters:
01311 //
01312 //    Input, int N, the number of entries in the vectors.
01313 //
01314 //    Input, double A1[N], A2[N], two vectors to compare.
01315 //
01316 //    Output, bool DVEC_EQ.
01317 //    DVEC_EQ is TRUE if every pair of elements A1(I) and A2(I) are equal,
01318 //    and FALSE otherwise.
01319 //
01320 {
01321   int i;
01322 
01323   for ( i = 0; i < n; i++ )
01324   {
01325     if ( a1[i] != a2[i] )
01326     {
01327       return false;
01328     }
01329   }
01330   return true;
01331 
01332 }
01333 //******************************************************************************
01334 
01335 bool dvec_gt ( int n, double a1[], double a2[] )
01336 
01337 //******************************************************************************
01338 //
01339 //  Purpose:
01340 //
01341 //    DVEC_GT == ( A1 > A2 ) for real vectors.
01342 //
01343 //  Discussion:
01344 //
01345 //    The comparison is lexicographic.
01346 //
01347 //    A1 > A2  <=>                              A1(1) > A2(1) or
01348 //                 ( A1(1)     == A2(1)     and A1(2) > A2(2) ) or
01349 //                 ...
01350 //                 ( A1(1:N-1) == A2(1:N-1) and A1(N) > A2(N)
01351 //
01352 //  Modified:
01353 //
01354 //    28 August 2003
01355 //
01356 //  Author:
01357 //
01358 //    John Burkardt
01359 //
01360 //  Parameters:
01361 //
01362 //    Input, int N, the dimension of the vectors.
01363 //
01364 //    Input, double A1[N], A2[N], the vectors to be compared.
01365 //
01366 //    Output, bool DVEC_GT, is TRUE if and only if A1 > A2.
01367 //
01368 {
01369   int i;
01370 
01371   for ( i = 0; i < n; i++ )
01372   {
01373 
01374     if ( a2[i] < a1[i] )
01375     {
01376        return true;
01377     }
01378     else if ( a1[i] < a2[i] )
01379     {
01380       return false;
01381     }
01382 
01383   }
01384 
01385   return false;
01386 }
01387 //******************************************************************************
01388 
01389 bool dvec_lt ( int n, double a1[], double a2[] )
01390 
01391 //******************************************************************************
01392 //
01393 //  Purpose:
01394 //
01395 //    DVEC_LT == ( A1 < A2 ) for real vectors.
01396 //
01397 //  Discussion:
01398 //
01399 //    The comparison is lexicographic.
01400 //
01401 //    A1 < A2  <=>                              A1(1) < A2(1) or
01402 //                 ( A1(1)     == A2(1)     and A1(2) < A2(2) ) or
01403 //                 ...
01404 //                 ( A1(1:N-1) == A2(1:N-1) and A1(N) < A2(N)
01405 //
01406 //  Modified:
01407 //
01408 //    28 August 2003
01409 //
01410 //  Author:
01411 //
01412 //    John Burkardt
01413 //
01414 //  Parameters:
01415 //
01416 //    Input, int N, the dimension of the vectors.
01417 //
01418 //    Input, double A1[N], A2[N], the vectors to be compared.
01419 //
01420 //    Output, bool DVEC_LT, is TRUE if and only if A1 < A2.
01421 //
01422 {
01423   int i;
01424 
01425   for ( i = 0; i < n; i++ )
01426   {
01427     if ( a1[i] < a2[i] )
01428     {
01429       return true;
01430     }
01431     else if ( a2[i] < a1[i] )
01432     {
01433       return false;
01434     }
01435 
01436   }
01437 
01438   return false;
01439 }
01440 //********************************************************************
01441 
01442 void dvec_print ( int n, double a[], const char *title )
01443 
01444 //********************************************************************
01445 //
01446 //  Purpose:
01447 //
01448 //    DVEC_PRINT prints a double precision vector.
01449 //
01450 //  Modified:
01451 //
01452 //    16 August 2004
01453 //
01454 //  Author:
01455 //
01456 //    John Burkardt
01457 //
01458 //  Parameters:
01459 //
01460 //    Input, int N, the number of components of the vector.
01461 //
01462 //    Input, double A[N], the vector to be printed.
01463 //
01464 //    Input, const char *TITLE, a title to be printed first.
01465 //    TITLE may be blank.
01466 //
01467 {
01468   int i;
01469 
01470   if ( 0 < s_len_trim ( title ) )
01471   {
01472     cout << "\n";
01473     cout << title << "\n";
01474   }
01475 
01476   cout << "\n";
01477   for ( i = 0; i <= n-1; i++ )
01478   {
01479     cout << setw(6)  << i + 1 << "  "
01480          << setw(14) << a[i]  << "\n";
01481   }
01482 
01483   return;
01484 }
01485 //******************************************************************************
01486 
01487 void dvec_swap ( int n, double a1[], double a2[] )
01488 
01489 //******************************************************************************
01490 //
01491 //  Purpose:
01492 //
01493 //    DVEC_SWAP swaps the entries of two real vectors.
01494 //
01495 //  Modified:
01496 //
01497 //    28 August 2003
01498 //
01499 //  Author:
01500 //
01501 //    John Burkardt
01502 //
01503 //  Parameters:
01504 //
01505 //    Input, int N, the number of entries in the arrays.
01506 //
01507 //    Input/output, double A1[N], A2[N], the vectors to swap.
01508 //
01509 {
01510   int i;
01511   double temp;
01512 
01513   for ( i = 0; i < n; i++ )
01514   {
01515     temp  = a1[i];
01516     a1[i] = a2[i];
01517     a2[i] = temp;
01518   }
01519 
01520   return;
01521 }
01522 //****************************************************************************
01523 
01524 int i_max ( int i1, int i2 )
01525 
01526 //****************************************************************************
01527 //
01528 //  Purpose:
01529 //
01530 //    I_MAX returns the maximum of two integers.
01531 //
01532 //  Modified:
01533 //
01534 //    13 October 1998
01535 //
01536 //  Author:
01537 //
01538 //    John Burkardt
01539 //
01540 //  Parameters:
01541 //
01542 //    Input, int I1, I2, are two integers to be compared.
01543 //
01544 //    Output, int I_MAX, the larger of I1 and I2.
01545 //
01546 {
01547   if ( i2 < i1 )
01548   {
01549     return i1;
01550   }
01551   else
01552   {
01553     return i2;
01554   }
01555 
01556 }
01557 //****************************************************************************
01558 
01559 int i_min ( int i1, int i2 )
01560 
01561 //****************************************************************************
01562 //
01563 //  Purpose:
01564 //
01565 //    I_MIN returns the smaller of two integers.
01566 //
01567 //  Modified:
01568 //
01569 //    13 October 1998
01570 //
01571 //  Author:
01572 //
01573 //    John Burkardt
01574 //
01575 //  Parameters:
01576 //
01577 //    Input, int I1, I2, two integers to be compared.
01578 //
01579 //    Output, int I_MIN, the smaller of I1 and I2.
01580 //
01581 {
01582   if ( i1 < i2 )
01583   {
01584     return i1;
01585   }
01586   else
01587   {
01588     return i2;
01589   }
01590 
01591 }
01592 //*********************************************************************
01593 
01594 int i_modp ( int i, int j )
01595 
01596 //*********************************************************************
01597 //
01598 //  Purpose:
01599 //
01600 //    I_MODP returns the nonnegative remainder of integer division.
01601 //
01602 //  Formula:
01603 //
01604 //    If
01605 //      NREM = I_MODP ( I, J )
01606 //      NMULT = ( I - NREM ) / J
01607 //    then
01608 //      I = J * NMULT + NREM
01609 //    where NREM is always nonnegative.
01610 //
01611 //  Comments:
01612 //
01613 //    The MOD function computes a result with the same sign as the
01614 //    quantity being divided.  Thus, suppose you had an angle A,
01615 //    and you wanted to ensure that it was between 0 and 360.
01616 //    Then mod(A,360) would do, if A was positive, but if A
01617 //    was negative, your result would be between -360 and 0.
01618 //
01619 //    On the other hand, I_MODP(A,360) is between 0 and 360, always.
01620 //
01621 //  Examples:
01622 //
01623 //        I         J     MOD  I_MODP   I_MODP Factorization
01624 //
01625 //      107        50       7       7    107 =  2 *  50 + 7
01626 //      107       -50       7       7    107 = -2 * -50 + 7
01627 //     -107        50      -7      43   -107 = -3 *  50 + 43
01628 //     -107       -50      -7      43   -107 =  3 * -50 + 43
01629 //
01630 //  Modified:
01631 //
01632 //    26 May 1999
01633 //
01634 //  Author:
01635 //
01636 //    John Burkardt
01637 //
01638 //  Parameters:
01639 //
01640 //    Input, int I, the number to be divided.
01641 //
01642 //    Input, int J, the number that divides I.
01643 //
01644 //    Output, int I_MODP, the nonnegative remainder when I is
01645 //    divided by J.
01646 //
01647 {
01648   int value;
01649 
01650   if ( j == 0 )
01651   {
01652     cout << "\n";
01653     cout << "I_MODP - Fatal error!\n";
01654     cout << "  I_MODP ( I, J ) called with J = " << j << "\n";
01655     exit ( 1 );
01656   }
01657 
01658   value = i % j;
01659 
01660   if ( value < 0 )
01661   {
01662     value = value + abs ( j );
01663   }
01664 
01665   return value;
01666 }
01667 //********************************************************************
01668 
01669 int i_sign ( int i )
01670 
01671 //********************************************************************
01672 //
01673 //  Purpose:
01674 //
01675 //    I_SIGN returns the sign of an integer.
01676 //
01677 //  Discussion:
01678 //
01679 //    The sign of 0 and all positive integers is taken to be +1.
01680 //    The sign of all negative integers is -1.
01681 //
01682 //  Modified:
01683 //
01684 //    06 May 2003
01685 //
01686 //  Author:
01687 //
01688 //    John Burkardt
01689 //
01690 //  Parameters:
01691 //
01692 //    Input, int I, the integer whose sign is desired.
01693 //
01694 //    Output, int I_SIGN, the sign of I.
01695 {
01696   if ( i < 0 )
01697   {
01698     return (-1);
01699   }
01700   else
01701   {
01702     return 1;
01703   }
01704 
01705 }
01706 //*******************************************************************************
01707 
01708 int i_wrap ( int ival, int ilo, int ihi )
01709 
01710 //*******************************************************************************
01711 //
01712 //  Purpose:
01713 //
01714 //    I_WRAP forces an integer to lie between given limits by wrapping.
01715 //
01716 //  Example:
01717 //
01718 //    ILO = 4, IHI = 8
01719 //
01720 //    I  I_WRAP
01721 //
01722 //    -2     8
01723 //    -1     4
01724 //     0     5
01725 //     1     6
01726 //     2     7
01727 //     3     8
01728 //     4     4
01729 //     5     5
01730 //     6     6
01731 //     7     7
01732 //     8     8
01733 //     9     4
01734 //    10     5
01735 //    11     6
01736 //    12     7
01737 //    13     8
01738 //    14     4
01739 //
01740 //  Modified:
01741 //
01742 //    19 August 2003
01743 //
01744 //  Author:
01745 //
01746 //    John Burkardt
01747 //
01748 //  Parameters:
01749 //
01750 //    Input, int IVAL, an integer value.
01751 //
01752 //    Input, int ILO, IHI, the desired bounds for the integer value.
01753 //
01754 //    Output, int I_WRAP, a "wrapped" version of IVAL.
01755 //
01756 {
01757   int jhi;
01758   int jlo;
01759   int value;
01760   int wide;
01761 
01762   jlo = i_min ( ilo, ihi );
01763   jhi = i_max ( ilo, ihi );
01764 
01765   wide = jhi + 1 - jlo;
01766 
01767   if ( wide == 1 )
01768   {
01769     value = jlo;
01770   }
01771   else
01772   {
01773     value = jlo + i_modp ( ival - jlo, wide );
01774   }
01775 
01776   return value;
01777 }
01778 //******************************************************************************
01779 
01780 void imat_transpose_print ( int m, int n, int a[], const char *title )
01781 
01782 //******************************************************************************
01783 //
01784 //  Purpose:
01785 //
01786 //    IMAT_TRANSPOSE_PRINT prints an integer matrix, transposed.
01787 //
01788 //  Modified:
01789 //
01790 //    31 January 2005
01791 //
01792 //  Author:
01793 //
01794 //    John Burkardt
01795 //
01796 //  Parameters:
01797 //
01798 //    Input, int M, the number of rows in A.
01799 //
01800 //    Input, int N, the number of columns in A.
01801 //
01802 //    Input, int A[M*N], the M by N matrix.
01803 //
01804 //    Input, const char *TITLE, a title to be printed.
01805 //
01806 {
01807   imat_transpose_print_some ( m, n, a, 1, 1, m, n, title );
01808 
01809   return;
01810 }
01811 //******************************************************************************
01812 
01813 void imat_transpose_print_some ( int m, int n, int a[], int ilo, int jlo,
01814   int ihi, int jhi, const char *title )
01815 
01816 //******************************************************************************
01817 //
01818 //  Purpose:
01819 //
01820 //    IMAT_TRANSPOSE_PRINT_SOME prints some of an integer matrix, transposed.
01821 //
01822 //  Modified:
01823 //
01824 //    09 February 2005
01825 //
01826 //  Author:
01827 //
01828 //    John Burkardt
01829 //
01830 //  Parameters:
01831 //
01832 //    Input, int M, the number of rows of the matrix.
01833 //    M must be positive.
01834 //
01835 //    Input, int N, the number of columns of the matrix.
01836 //    N must be positive.
01837 //
01838 //    Input, int A[M*N], the matrix.
01839 //
01840 //    Input, int ILO, JLO, IHI, JHI, designate the first row and
01841 //    column, and the last row and column to be printed.
01842 //
01843 //    Input, const char *TITLE, a title for the matrix.
01844 {
01845 # define INCX 10
01846 
01847   int i;
01848   int i2hi;
01849   int i2lo;
01850   int j;
01851   int j2hi;
01852   int j2lo;
01853 
01854   if ( 0 < s_len_trim ( title ) )
01855   {
01856     cout << "\n";
01857     cout << title << "\n";
01858   }
01859 //
01860 //  Print the columns of the matrix, in strips of INCX.
01861 //
01862   for ( i2lo = ilo; i2lo <= ihi; i2lo = i2lo + INCX )
01863   {
01864     i2hi = i2lo + INCX - 1;
01865     i2hi = i_min ( i2hi, m );
01866     i2hi = i_min ( i2hi, ihi );
01867 
01868     cout << "\n";
01869 //
01870 //  For each row I in the current range...
01871 //
01872 //  Write the header.
01873 //
01874     cout << "  Row:    ";
01875     for ( i = i2lo; i <= i2hi; i++ )
01876     {
01877       cout << setw(7) << i << "       ";
01878     }
01879     cout << "\n";
01880     cout << "  Col\n";
01881     cout << "\n";
01882 //
01883 //  Determine the range of the rows in this strip.
01884 //
01885     j2lo = i_max ( jlo, 1 );
01886     j2hi = i_min ( jhi, n );
01887 
01888     for ( j = j2lo; j <= j2hi; j++ )
01889     {
01890 //
01891 //  Print out (up to INCX) entries in column J, that lie in the current strip.
01892 //
01893       cout << setw(5) << j << "  ";
01894       for ( i = i2lo; i <= i2hi; i++ )
01895       {
01896         cout << setw(6) << a[i-1+(j-1)*m] << "  ";
01897       }
01898       cout << "\n";
01899     }
01900 
01901   }
01902 
01903   cout << "\n";
01904 
01905   return;
01906 # undef INCX
01907 }
01908 //********************************************************************
01909 
01910 void ivec_heap_d ( int n, int a[] )
01911 
01912 /*********************************************************************
01913 //
01914 //  Purpose:
01915 //
01916 //    IVEC_HEAP_D reorders an array of integers into a descending heap.
01917 //
01918 //  Definition:
01919 //
01920 //    A heap is an array A with the property that, for every index J,
01921 //    A[J] >= A[2*J+1] and A[J] >= A[2*J+2], (as long as the indices
01922 //    2*J+1 and 2*J+2 are legal).
01923 //
01924 //  Diagram:
01925 //
01926 //                  A(0)
01927 //                /      \
01928 //            A(1)         A(2)
01929 //          /     \        /  \
01930 //      A(3)       A(4)  A(5) A(6)
01931 //      /  \       /   \
01932 //    A(7) A(8)  A(9) A(10)
01933 //
01934 //  Reference:
01935 //
01936 //    Albert Nijenhuis, Herbert Wilf,
01937 //    Combinatorial Algorithms,
01938 //    Academic Press, 1978, second edition,
01939 //    ISBN 0-12-519260-6.
01940 //
01941 //  Modified:
01942 //
01943 //    30 April 1999
01944 //
01945 //  Author:
01946 //
01947 //    John Burkardt
01948 //
01949 //  Parameters:
01950 //
01951 //    Input, int N, the size of the input array.
01952 //
01953 //    Input/output, int A[N].
01954 //    On input, an unsorted array.
01955 //    On output, the array has been reordered into a heap.
01956 */
01957 {
01958   int i;
01959   int ifree;
01960   int key;
01961   int m;
01962 //
01963 //  Only nodes (N/2)-1 down to 0 can be "parent" nodes.
01964 //
01965   for ( i = (n/2)-1; 0 <= i; i-- )
01966   {
01967 //
01968 //  Copy the value out of the parent node.
01969 //  Position IFREE is now "open".
01970 //
01971     key = a[i];
01972     ifree = i;
01973 
01974     for ( ;; )
01975     {
01976 //
01977 //  Positions 2*IFREE + 1 and 2*IFREE + 2 are the descendants of position
01978 //  IFREE.  (One or both may not exist because they equal or exceed N.)
01979 //
01980       m = 2 * ifree + 1;
01981 //
01982 //  Does the first position exist?
01983 //
01984       if ( n <= m )
01985       {
01986         break;
01987       }
01988       else
01989       {
01990 //
01991 //  Does the second position exist?
01992 //
01993         if ( m + 1 < n )
01994         {
01995 //
01996 //  If both positions exist, take the larger of the two values,
01997 //  and update M if necessary.
01998 //
01999           if ( a[m] < a[m+1] )
02000           {
02001             m = m + 1;
02002           }
02003         }
02004 //
02005 //  If the large descendant is larger than KEY, move it up,
02006 //  and update IFREE, the location of the free position, and
02007 //  consider the descendants of THIS position.
02008 //
02009         if ( key < a[m] )
02010         {
02011           a[ifree] = a[m];
02012           ifree = m;
02013         }
02014         else
02015         {
02016           break;
02017         }
02018 
02019       }
02020 
02021     }
02022 //
02023 //  When you have stopped shifting items up, return the item you
02024 //  pulled out back to the heap.
02025 //
02026     a[ifree] = key;
02027 
02028   }
02029 
02030   return;
02031 }
02032 //******************************************************************************
02033 
02034 int *ivec_indicator ( int n )
02035 
02036 //******************************************************************************
02037 //
02038 //  Purpose:
02039 //
02040 //    IVEC_INDICATOR sets an integer vector to the indicator vector.
02041 //
02042 //  Modified:
02043 //
02044 //    13 January 2004
02045 //
02046 //  Author:
02047 //
02048 //    John Burkardt
02049 //
02050 //  Parameters:
02051 //
02052 //    Input, int N, the number of elements of A.
02053 //
02054 //    Output, int IVEC_INDICATOR(N), the initialized array.
02055 //
02056 {
02057   int *a;
02058   int i;
02059 
02060   a = new int[n];
02061 
02062   for ( i = 0; i < n; i++ )
02063   {
02064     a[i] = i + 1;
02065   }
02066 
02067   return a;
02068 }
02069 //********************************************************************
02070 
02071 void ivec_sort_heap_a ( int n, int a[] )
02072 
02073 //********************************************************************
02074 //
02075 //  Purpose:
02076 //
02077 //    IVEC_SORT_HEAP_A ascending sorts an array of integers using heap sort.
02078 //
02079 //  Reference:
02080 //
02081 //    Albert Nijenhuis, Herbert Wilf,
02082 //    Combinatorial Algorithms,
02083 //    Academic Press, 1978, second edition,
02084 //    ISBN 0-12-519260-6.
02085 //
02086 //  Modified:
02087 //
02088 //    30 April 1999
02089 //
02090 //  Author:
02091 //
02092 //    John Burkardt
02093 //
02094 //  Parameters:
02095 //
02096 //    Input, int N, the number of entries in the array.
02097 //
02098 //    Input/output, int A[N].
02099 //    On input, the array to be sorted;
02100 //    On output, the array has been sorted.
02101 //
02102 {
02103   int n1;
02104   int temp;
02105 
02106   if ( n <= 1 )
02107   {
02108     return;
02109   }
02110 //
02111 //  1: Put A into descending heap form.
02112 //
02113   ivec_heap_d ( n, a );
02114 //
02115 //  2: Sort A.
02116 //
02117 //  The largest object in the heap is in A[0].
02118 //  Move it to position A[N-1].
02119 //
02120   temp = a[0];
02121   a[0] = a[n-1];
02122   a[n-1] = temp;
02123 //
02124 //  Consider the diminished heap of size N1.
02125 //
02126   for ( n1 = n-1; 2 <= n1; n1-- )
02127   {
02128 //
02129 //  Restore the heap structure of the initial N1 entries of A.
02130 //
02131     ivec_heap_d ( n1, a );
02132 //
02133 //  Take the largest object from A[0] and move it to A[N1-1].
02134 //
02135     temp = a[0];
02136     a[0] = a[n1-1];
02137     a[n1-1] = temp;
02138 
02139   }
02140 
02141   return;
02142 }
02143 //******************************************************************************
02144 
02145 void ivec_sorted_unique ( int n, int a[], int *nuniq )
02146 
02147 //******************************************************************************
02148 //
02149 //  Purpose:
02150 //
02151 //    IVEC_SORTED_UNIQUE finds unique elements in a sorted integer array.
02152 //
02153 //  Modified:
02154 //
02155 //    02 September 2003
02156 //
02157 //  Author:
02158 //
02159 //    John Burkardt
02160 //
02161 //  Parameters:
02162 //
02163 //    Input, int N, the number of elements in A.
02164 //
02165 //    Input/output, int A[N].  On input, the sorted
02166 //    integer array.  On output, the unique elements in A.
02167 //
02168 //    Output, int *NUNIQ, the number of unique elements in A.
02169 //
02170 {
02171   int i;
02172 
02173   *nuniq = 0;
02174 
02175   if ( n <= 0 )
02176   {
02177     return;
02178   }
02179 
02180   *nuniq = 1;
02181 
02182   for ( i = 1; i < n; i++ )
02183   {
02184     if ( a[i] != a[*nuniq] )
02185     {
02186       *nuniq = *nuniq + 1;
02187       a[*nuniq] = a[i];
02188     }
02189 
02190   }
02191 
02192   return;
02193 }
02194 //******************************************************************************
02195 
02196 int lrline ( double xu, double yu, double xv1, double yv1, double xv2,
02197   double yv2, double dv )
02198 
02199 //******************************************************************************
02200 //
02201 //  Purpose:
02202 //
02203 //    LRLINE determines where a point lies in relation to a directed line.
02204 //
02205 //  Discussion:
02206 //
02207 //    LRLINE determines whether a point is to the left of, right of,
02208 //    or on a directed line parallel to a line through given points.
02209 //
02210 //  Modified:
02211 //
02212 //    28 August 2003
02213 //
02214 //  Author:
02215 //
02216 //    Barry Joe,
02217 //    Department of Computing Science,
02218 //    University of Alberta,
02219 //    Edmonton, Alberta, Canada  T6G 2H1
02220 //
02221 //  Reference:
02222 //
02223 //    Barry Joe,
02224 //    GEOMPACK - a software package for the generation of meshes
02225 //    using geometric algorithms,
02226 //    Advances in Engineering Software,
02227 //    Volume 13, pages 325-331, 1991.
02228 //
02229 //  Parameters:
02230 //
02231 //    Input, double XU, YU, XV1, YV1, XV2, YV2, are vertex coordinates; the
02232 //    directed line is parallel to and at signed distance DV to the left of
02233 //    the directed line from (XV1,YV1) to (XV2,YV2); (XU,YU) is the vertex for
02234 //    which the position relative to the directed line is to be determined.
02235 //
02236 //    Input, double DV, the signed distance, positive for left.
02237 //
02238 //    Output, int LRLINE, is +1, 0, or -1 depending on whether (XU,YU) is
02239 //    to the right of, on, or left of the directed line.  LRLINE is 0 if
02240 //    the line degenerates to a point.
02241 //
02242 {
02243   double dx;
02244   double dxu;
02245   double dy;
02246   double dyu;
02247   double t;
02248   double tol = 0.0000001;
02249   double tolabs;
02250   int value = 0;
02251 
02252   dx = xv2 - xv1;
02253   dy = yv2 - yv1;
02254   dxu = xu - xv1;
02255   dyu = yu - yv1;
02256 
02257   tolabs = tol * d_max ( fabs ( dx ),
02258                  d_max ( fabs ( dy ),
02259                  d_max ( fabs ( dxu ),
02260                  d_max ( fabs ( dyu ), fabs ( dv ) ) ) ) );
02261 
02262   t = dy * dxu - dx * dyu + dv * sqrt ( dx * dx + dy * dy );
02263 
02264   if ( tolabs < t )
02265   {
02266     value = 1;
02267   }
02268   else if ( -tolabs <= t )
02269   {
02270     value = 0;
02271   }
02272   else if ( t < -tolabs )
02273   {
02274     value = -1;
02275   }
02276 
02277   return value;
02278 }
02279 //******************************************************************************
02280 
02281 bool perm_check ( int n, int p[] )
02282 
02283 //******************************************************************************
02284 //
02285 //  Purpose:
02286 //
02287 //    PERM_CHECK checks that a vector represents a permutation.
02288 //
02289 //  Discussion:
02290 //
02291 //    The routine verifies that each of the integers from 1
02292 //    to N occurs among the N entries of the permutation.
02293 //
02294 //  Modified:
02295 //
02296 //    13 January 2004
02297 //
02298 //  Author:
02299 //
02300 //    John Burkardt
02301 //
02302 //  Parameters:
02303 //
02304 //    Input, int N, the number of entries.
02305 //
02306 //    Input, int P[N], the array to check.
02307 //
02308 //    Output, bool PERM_CHECK, is TRUE if the permutation is OK.
02309 //
02310 {
02311   bool found;
02312   int i;
02313   int seek;
02314 
02315   for ( seek = 1; seek <= n; seek++ )
02316   {
02317     found = false;
02318 
02319     for ( i = 0; i < n; i++ )
02320     {
02321       if ( p[i] == seek )
02322       {
02323         found = true;
02324         break;
02325       }
02326     }
02327 
02328     if ( !found )
02329     {
02330       return false;
02331     }
02332 
02333   }
02334 
02335   return true;
02336 }
02337 //******************************************************************************
02338 
02339 void perm_inv ( int n, int p[] )
02340 
02341 //******************************************************************************
02342 //
02343 //  Purpose:
02344 //
02345 //    PERM_INV inverts a permutation "in place".
02346 //
02347 //  Modified:
02348 //
02349 //    13 January 2004
02350 //
02351 //  Parameters:
02352 //
02353 //    Input, int N, the number of objects being permuted.
02354 //
02355 //    Input/output, int P[N], the permutation, in standard index form.
02356 //    On output, P describes the inverse permutation
02357 //
02358 {
02359   int i;
02360   int i0;
02361   int i1;
02362   int i2;
02363   int is;
02364 
02365   if ( n <= 0 )
02366   {
02367     cout << "\n";
02368     cout << "PERM_INV - Fatal error!\n";
02369     cout << "  Input value of N = " << n << "\n";
02370     exit ( 1 );
02371   }
02372 
02373   if ( !perm_check ( n, p ) )
02374   {
02375     cout << "\n";
02376     cout << "PERM_INV - Fatal error!\n";
02377     cout << "  The input array does not represent\n";
02378     cout << "  a proper permutation.\n";
02379     exit ( 1 );
02380   }
02381 
02382   is = 1;
02383 
02384   for ( i = 1; i <= n; i++ )
02385   {
02386     i1 = p[i-1];
02387 
02388     while ( i < i1 )
02389     {
02390       i2 = p[i1-1];
02391       p[i1-1] = -i2;
02392       i1 = i2;
02393     }
02394 
02395     is = - i_sign ( p[i-1] );
02396     p[i-1] = i_sign ( is ) * abs ( p[i-1] );
02397   }
02398 
02399   for ( i = 1; i <= n; i++ )
02400   {
02401     i1 = -p[i-1];
02402 
02403     if ( 0 <= i1 )
02404     {
02405       i0 = i;
02406 
02407       for ( ; ; )
02408       {
02409         i2 = p[i1-1];
02410         p[i1-1] = i0;
02411 
02412         if ( i2 < 0 )
02413         {
02414           break;
02415         }
02416         i0 = i1;
02417         i1 = i2;
02418       }
02419     }
02420   }
02421 
02422   return;
02423 }
02424 //********************************************************************
02425 
02426 int *points_delaunay_naive_2d ( int n, double p[], int *ntri )
02427 
02428 //********************************************************************
02429 //
02430 //  Purpose:
02431 //
02432 //    POINTS_DELAUNAY_NAIVE_2D computes the Delaunay triangulation in 2D.
02433 //
02434 //  Discussion:
02435 //
02436 //    A naive and inefficient (but extremely simple) method is used.
02437 //
02438 //    This routine is only suitable as a demonstration code for small
02439 //    problems.  Its running time is of order N^4.  Much faster algorithms
02440 //    are available.
02441 //
02442 //    Given a set of nodes in the plane, a triangulation is a set of
02443 //    triples of distinct nodes, forming triangles, so that every
02444 //    point with the convex hull of the set of  nodes is either one
02445 //    of the nodes, or lies on an edge of one or more triangles,
02446 //    or lies within exactly one triangle.
02447 //
02448 //  Modified:
02449 //
02450 //    05 February 2005
02451 //
02452 //  Author:
02453 //
02454 //    John Burkardt
02455 //
02456 //  Reference:
02457 //
02458 //    Joseph O'Rourke,
02459 //    Computational Geometry,
02460 //    Cambridge University Press,
02461 //    Second Edition, 1998, page 187.
02462 //
02463 //  Parameters:
02464 //
02465 //    Input, int N, the number of nodes.  N must be at least 3.
02466 //
02467 //    Input, double P[2*N], the coordinates of the nodes.
02468 //
02469 //    Output, int *NTRI, the number of triangles.
02470 //
02471 //    Output, int POINTS_DELAUNAY_NAIVE_2D[3*NTRI], the indices of the
02472 //    nodes making each triangle.
02473 //
02474 {
02475   int count;
02476   int flag;
02477   int i;
02478   int j;
02479   int k;
02480   int m;
02481   int pass;
02482   int *tri = NULL;
02483   double xn;
02484   double yn;
02485   double zn;
02486   double *z;
02487 
02488   count = 0;
02489 
02490   z = new double [ n ];
02491 
02492   for ( i = 0; i < n; i++ )
02493   {
02494     z[i] = p[0+i*2] * p[0+i*2] + p[1+i*2] * p[1+i*2];
02495   }
02496 //
02497 //  First pass counts triangles,
02498 //  Second pass allocates triangles and sets them.
02499 //
02500   for ( pass = 1; pass <= 2; pass++ )
02501   {
02502     if ( pass == 2 )
02503     {
02504       tri = new int[3*count];
02505     }
02506     count = 0;
02507 //
02508 //  For each triple (I,J,K):
02509 //
02510     for ( i = 0; i < n - 2; i++ )
02511     {
02512       for ( j = i+1; j < n; j++ )
02513       {
02514         for ( k = i+1; k < n; k++ )
02515         {
02516           if ( j != k )
02517           {
02518             xn = ( p[1+j*2] - p[1+i*2] ) * ( z[k] - z[i] )
02519                - ( p[1+k*2] - p[1+i*2] ) * ( z[j] - z[i] );
02520             yn = ( p[0+k*2] - p[0+i*2] ) * ( z[j] - z[i] )
02521                - ( p[0+j*2] - p[0+i*2] ) * ( z[k] - z[i] );
02522             zn = ( p[0+j*2] - p[0+i*2] ) * ( p[1+k*2] - p[1+i*2] )
02523                - ( p[0+k*2] - p[0+i*2] ) * ( p[1+j*2] - p[1+i*2] );
02524 
02525             flag = ( zn < 0 );
02526 
02527             if ( flag )
02528             {
02529               for ( m = 0; m < n; m++ )
02530               {
02531                 flag = flag && ( ( p[0+m*2] - p[0+i*2] ) * xn
02532                                + ( p[1+m*2] - p[1+i*2] ) * yn
02533                                + ( z[m] - z[i] ) * zn <= 0 );
02534               }
02535             }
02536 
02537             if ( flag )
02538             {
02539               if ( pass == 2 )
02540               {
02541                 tri[0+count*3] = i;
02542                 tri[1+count*3] = j;
02543                 tri[2+count*3] = k;
02544               }
02545               count = count + 1;
02546             }
02547 
02548           }
02549         }
02550       }
02551     }
02552   }
02553 
02554   *ntri = count;
02555   delete [] z;
02556 
02557   return tri;
02558 }
02559 //******************************************************************************
02560 
02561 int s_len_trim ( const char *s )
02562 
02563 //******************************************************************************
02564 //
02565 //  Purpose:
02566 //
02567 //    S_LEN_TRIM returns the length of a string to the last nonblank.
02568 //
02569 //  Modified:
02570 //
02571 //    26 April 2003
02572 //
02573 //  Author:
02574 //
02575 //    John Burkardt
02576 //
02577 //  Parameters:
02578 //
02579 //    Input, const char *S, a pointer to a string.
02580 //
02581 //    Output, int S_LEN_TRIM, the length of the string to the last nonblank.
02582 //    If S_LEN_TRIM is 0, then the string is entirely blank.
02583 //
02584 {
02585   int n;
02586   char* t;
02587 
02588   n = strlen ( s );
02589   t = const_cast<char*>(s) + n - 1;
02590 
02591   while ( 0 < n )
02592   {
02593     if ( *t != ' ' )
02594     {
02595       return n;
02596     }
02597     t--;
02598     n--;
02599   }
02600 
02601   return n;
02602 }
02603 //******************************************************************************
02604 
02605 int swapec ( int i, int *top, int *btri, int *bedg, int point_num,
02606   double point_xy[], int tri_num, int tri_vert[], int tri_nabe[],
02607   int stack[] )
02608 
02609 //******************************************************************************
02610 //
02611 //  Purpose:
02612 //
02613 //    SWAPEC swaps diagonal edges until all triangles are Delaunay.
02614 //
02615 //  Discussion:
02616 //
02617 //    The routine swaps diagonal edges in a 2D triangulation, based on
02618 //    the empty circumcircle criterion, until all triangles are Delaunay,
02619 //    given that I is the index of the new vertex added to the triangulation.
02620 //
02621 //  Modified:
02622 //
02623 //    03 September 2003
02624 //
02625 //  Author:
02626 //
02627 //    Barry Joe,
02628 //    Department of Computing Science,
02629 //    University of Alberta,
02630 //    Edmonton, Alberta, Canada  T6G 2H1
02631 //
02632 //  Reference:
02633 //
02634 //    Barry Joe,
02635 //    GEOMPACK - a software package for the generation of meshes
02636 //    using geometric algorithms,
02637 //    Advances in Engineering Software,
02638 //    Volume 13, pages 325-331, 1991.
02639 //
02640 //  Parameters:
02641 //
02642 //    Input, int I, the index of the new vertex.
02643 //
02644 //    Input/output, int *TOP, the index of the top of the stack.
02645 //    On output, TOP is zero.
02646 //
02647 //    Input/output, int *BTRI, *BEDG; on input, if positive, are the
02648 //    triangle and edge indices of a boundary edge whose updated indices
02649 //    must be recorded.  On output, these may be updated because of swaps.
02650 //
02651 //    Input, int POINT_NUM, the number of points.
02652 //
02653 //    Input, double POINT_XY[POINT_NUM*2], the coordinates of the points.
02654 //
02655 //    Input, int TRI_NUM, the number of triangles.
02656 //
02657 //    Input/output, int TRI_VERT[TRI_NUM*3], the triangle incidence list.
02658 //    May be updated on output because of swaps.
02659 //
02660 //    Input/output, int TRI_NABE[TRI_NUM*3], the triangle neighbor list;
02661 //    negative values are used for links of the counter-clockwise linked
02662 //    list of boundary edges;  May be updated on output because of swaps.
02663 //
02664 //      LINK = -(3*I + J-1) where I, J = triangle, edge index.
02665 //
02666 //    Workspace, int STACK[MAXST]; on input, entries 1 through TOP
02667 //    contain the indices of initial triangles (involving vertex I)
02668 //    put in stack; the edges opposite I should be in interior;  entries
02669 //    TOP+1 through MAXST are used as a stack.
02670 //
02671 //    Output, int SWAPEC, is set to 8 for abnormal return.
02672 //
02673 {
02674   int a;
02675   int b;
02676   int c;
02677   int e;
02678   int ee;
02679   int em1;
02680   int ep1;
02681   int f;
02682   int fm1;
02683   int fp1;
02684   int l;
02685   int r;
02686   int s;
02687   int swap;
02688   int t;
02689   int tt;
02690   int u;
02691   double x;
02692   double y;
02693 //
02694 //  Determine whether triangles in stack are Delaunay, and swap
02695 //  diagonal edge of convex quadrilateral if not.
02696 //
02697   x = point_xy[2*(i-1)+0];
02698   y = point_xy[2*(i-1)+1];
02699 
02700   for ( ; ; )
02701   {
02702     if ( *top <= 0 )
02703     {
02704       break;
02705     }
02706 
02707     t = stack[(*top)-1];
02708     *top = *top - 1;
02709 
02710     if ( tri_vert[3*(t-1)+0] == i )
02711     {
02712       e = 2;
02713       b = tri_vert[3*(t-1)+2];
02714     }
02715     else if ( tri_vert[3*(t-1)+1] == i )
02716     {
02717       e = 3;
02718       b = tri_vert[3*(t-1)+0];
02719     }
02720     else
02721     {
02722       e = 1;
02723       b = tri_vert[3*(t-1)+1];
02724     }
02725 
02726     a = tri_vert[3*(t-1)+e-1];
02727     u = tri_nabe[3*(t-1)+e-1];
02728 
02729     if ( tri_nabe[3*(u-1)+0] == t )
02730     {
02731       f = 1;
02732       c = tri_vert[3*(u-1)+2];
02733     }
02734     else if ( tri_nabe[3*(u-1)+1] == t )
02735     {
02736       f = 2;
02737       c = tri_vert[3*(u-1)+0];
02738     }
02739     else
02740     {
02741       f = 3;
02742       c = tri_vert[3*(u-1)+1];
02743     }
02744 
02745     swap = diaedg ( x, y,
02746       point_xy[2*(a-1)+0], point_xy[2*(a-1)+1],
02747       point_xy[2*(c-1)+0], point_xy[2*(c-1)+1],
02748       point_xy[2*(b-1)+0], point_xy[2*(b-1)+1] );
02749 
02750     if ( swap == 1 )
02751     {
02752       em1 = i_wrap ( e - 1, 1, 3 );
02753       ep1 = i_wrap ( e + 1, 1, 3 );
02754       fm1 = i_wrap ( f - 1, 1, 3 );
02755       fp1 = i_wrap ( f + 1, 1, 3 );
02756 
02757       tri_vert[3*(t-1)+ep1-1] = c;
02758       tri_vert[3*(u-1)+fp1-1] = i;
02759       r = tri_nabe[3*(t-1)+ep1-1];
02760       s = tri_nabe[3*(u-1)+fp1-1];
02761       tri_nabe[3*(t-1)+ep1-1] = u;
02762       tri_nabe[3*(u-1)+fp1-1] = t;
02763       tri_nabe[3*(t-1)+e-1] = s;
02764       tri_nabe[3*(u-1)+f-1] = r;
02765 
02766       if ( 0 < tri_nabe[3*(u-1)+fm1-1] )
02767       {
02768         *top = *top + 1;
02769         stack[(*top)-1] = u;
02770       }
02771 
02772       if ( 0 < s )
02773       {
02774         if ( tri_nabe[3*(s-1)+0] == u )
02775         {
02776           tri_nabe[3*(s-1)+0] = t;
02777         }
02778         else if ( tri_nabe[3*(s-1)+1] == u )
02779         {
02780           tri_nabe[3*(s-1)+1] = t;
02781         }
02782         else
02783         {
02784           tri_nabe[3*(s-1)+2] = t;
02785         }
02786 
02787         *top = *top + 1;
02788 
02789         if ( point_num < *top )
02790         {
02791           return 8;
02792         }
02793 
02794         stack[(*top)-1] = t;
02795       }
02796       else
02797       {
02798         if ( u == *btri && fp1 == *bedg )
02799         {
02800           *btri = t;
02801           *bedg = e;
02802         }
02803 
02804         l = - ( 3 * t + e - 1 );
02805         tt = t;
02806         ee = em1;
02807 
02808         while ( 0 < tri_nabe[3*(tt-1)+ee-1] )
02809         {
02810           tt = tri_nabe[3*(tt-1)+ee-1];
02811 
02812           if ( tri_vert[3*(tt-1)+0] == a )
02813           {
02814             ee = 3;
02815           }
02816           else if ( tri_vert[3*(tt-1)+1] == a )
02817           {
02818             ee = 1;
02819           }
02820           else
02821           {
02822             ee = 2;
02823           }
02824 
02825         }
02826 
02827         tri_nabe[3*(tt-1)+ee-1] = l;
02828 
02829       }
02830 
02831       if ( 0 < r )
02832       {
02833         if ( tri_nabe[3*(r-1)+0] == t )
02834         {
02835           tri_nabe[3*(r-1)+0] = u;
02836         }
02837         else if ( tri_nabe[3*(r-1)+1] == t )
02838         {
02839           tri_nabe[3*(r-1)+1] = u;
02840         }
02841         else
02842         {
02843           tri_nabe[3*(r-1)+2] = u;
02844         }
02845       }
02846       else
02847       {
02848         if ( t == *btri && ep1 == *bedg )
02849         {
02850           *btri = u;
02851           *bedg = f;
02852         }
02853 
02854         l = - ( 3 * u + f - 1 );
02855         tt = u;
02856         ee = fm1;
02857 
02858         while ( 0 < tri_nabe[3*(tt-1)+ee-1] )
02859         {
02860           tt = tri_nabe[3*(tt-1)+ee-1];
02861 
02862           if ( tri_vert[3*(tt-1)+0] == b )
02863           {
02864             ee = 3;
02865           }
02866           else if ( tri_vert[3*(tt-1)+1] == b )
02867           {
02868             ee = 1;
02869           }
02870           else
02871           {
02872             ee = 2;
02873           }
02874         }
02875         tri_nabe[3*(tt-1)+ee-1] = l;
02876       }
02877     }
02878   }
02879   return 0;
02880 }
02881 //**********************************************************************
02882 
02883 void timestamp ( void )
02884 
02885 //**********************************************************************
02886 //
02887 //  Purpose:
02888 //
02889 //    TIMESTAMP prints the current YMDHMS date as a time stamp.
02890 //
02891 //  Example:
02892 //
02893 //    May 31 2001 09:45:54 AM
02894 //
02895 //  Modified:
02896 //
02897 //    21 August 2002
02898 //
02899 //  Author:
02900 //
02901 //    John Burkardt
02902 //
02903 //  Parameters:
02904 //
02905 //    None
02906 //
02907 {
02908 # define TIME_SIZE 29
02909 
02910   static char time_buffer[TIME_SIZE];
02911   const struct tm *tm;
02912   size_t len;
02913   time_t now;
02914 
02915   now = time ( NULL );
02916   tm = localtime ( &now );
02917 
02918   len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
02919 
02920   if ( len != 0 )
02921   {
02922     cout << time_buffer << "\n";
02923   }
02924 
02925   return;
02926 # undef TIME_SIZE
02927 }
02928 //**********************************************************************
02929 
02930 char *timestring ( void )
02931 
02932 //**********************************************************************
02933 //
02934 //  Purpose:
02935 //
02936 //    TIMESTRING returns the current YMDHMS date as a string.
02937 //
02938 //  Example:
02939 //
02940 //    May 31 2001 09:45:54 AM
02941 //
02942 //  Modified:
02943 //
02944 //    13 June 2003
02945 //
02946 //  Author:
02947 //
02948 //    John Burkardt
02949 //
02950 //  Parameters:
02951 //
02952 //    Output, char *TIMESTRING, a string containing the current YMDHMS date.
02953 //
02954 {
02955 # define TIME_SIZE 29
02956 
02957   const struct tm *tm;
02958   size_t len;
02959   time_t now;
02960   char *s;
02961 
02962   now = time ( NULL );
02963   tm = localtime ( &now );
02964 
02965   s = new char[TIME_SIZE];
02966 
02967   len = strftime ( s, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
02968 
02969   return s;
02970 # undef TIME_SIZE
02971 }
02972 //******************************************************************************
02973 
02974 double *triangle_circumcenter_2d ( double t[] )
02975 
02976 //******************************************************************************
02977 //
02978 //  Purpose:
02979 //
02980 //    TRIANGLE_CIRCUMCENTER_2D computes the circumcenter of a triangle in 2D.
02981 //
02982 //  Discussion:
02983 //
02984 //    The circumcenter of a triangle is the center of the circumcircle, the
02985 //    circle that passes through the three vertices of the triangle.
02986 //
02987 //    The circumcircle contains the triangle, but it is not necessarily the
02988 //    smallest triangle to do so.
02989 //
02990 //    If all angles of the triangle are no greater than 90 degrees, then
02991 //    the center of the circumscribed circle will lie inside the triangle.
02992 //    Otherwise, the center will lie outside the circle.
02993 //
02994 //    The circumcenter is the intersection of the perpendicular bisectors
02995 //    of the sides of the triangle.
02996 //
02997 //    In geometry, the circumcenter of a triangle is often symbolized by "O".
02998 //
02999 //  Modified:
03000 //
03001 //    09 February 2005
03002 //
03003 //  Author:
03004 //
03005 //    John Burkardt
03006 //
03007 //  Parameters:
03008 //
03009 //    Input, double T[2*3], the triangle vertices.
03010 //
03011 //    Output, double *X, *Y, the coordinates of the circumcenter of the triangle.
03012 //
03013 {
03014 # define DIM_NUM 2
03015 
03016   double asq;
03017   double bot;
03018   double *center;
03019   double csq;
03020   double top1;
03021   double top2;
03022 
03023   center = new double[DIM_NUM];
03024 
03025   asq = ( t[0+1*2] - t[0+0*2] ) * ( t[0+1*2] - t[0+0*2] )
03026       + ( t[1+1*2] - t[1+0*2] ) * ( t[1+1*2] - t[1+0*2] );
03027 
03028   csq = ( t[0+2*2] - t[0+0*2] ) * ( t[0+2*2] - t[0+0*2] )
03029       + ( t[1+2*2] - t[1+0*2] ) * ( t[1+2*2] - t[1+0*2] );
03030 
03031   top1 =  ( t[1+1*2] - t[1+0*2] ) * csq - ( t[1+2*2] - t[1+0*2] ) * asq;
03032   top2 =  ( t[0+1*2] - t[0+0*2] ) * csq - ( t[0+2*2] - t[0+0*2] ) * asq;
03033 
03034   bot  =  ( t[1+1*2] - t[1+0*2] ) * ( t[0+2*2] - t[0+0*2] )
03035         - ( t[1+2*2] - t[1+0*2] ) * ( t[0+1*2] - t[0+0*2] );
03036 
03037   center[0] = t[0+0*2] + 0.5 * top1 / bot;
03038   center[1] = t[1+0*2] + 0.5 * top2 / bot;
03039 
03040   return center;
03041 
03042 # undef DIM_NUM
03043 }
03044 //******************************************************************************
03045 
03046 bool triangulation_plot_eps ( const char *file_out_name, int g_num, double g_xy[],
03047   int tri_num, int nod_tri[] )
03048 
03049 //******************************************************************************
03050 //
03051 //  Purpose:
03052 //
03053 //    TRIANGULATION_PLOT_EPS plots a triangulation of a pointset.
03054 //
03055 //  Discussion:
03056 //
03057 //    The triangulation is most usually a Delaunay triangulation,
03058 //    but this is not necessary.
03059 //
03060 //    The data can be generated by calling DTRIS2, but this is not
03061 //    necessary.
03062 //
03063 //  Modified:
03064 //
03065 //    08 September 2003
03066 //
03067 //  Author:
03068 //
03069 //    John Burkardt
03070 //
03071 //  Parameters:
03072 //
03073 //    Input, const char *FILE_OUT_NAME, the name of the output file.
03074 //
03075 //    Input, int G_NUM, the number of points.
03076 //
03077 //    Input, double G_XY[G_NUM,2], the coordinates of the points.
03078 //
03079 //    Input, int TRI_NUM, the number of triangles.
03080 //
03081 //    Input, int NOD_TRI[3,TRI_NUM], lists, for each triangle,
03082 //    the indices of the points that form the vertices of the triangle.
03083 //
03084 //    Output, bool TRIANGULATION_PLOT_EPS, is TRUE for success.
03085 //
03086 {
03087   char *date_time;
03088   int e;
03089   ofstream file_out;
03090   int g;
03091   int j;
03092   int k;
03093   int t;
03094   double x_max;
03095   double x_min;
03096   int x_ps;
03097   int x_ps_max = 576;
03098   int x_ps_max_clip = 594;
03099   int x_ps_min = 36;
03100   int x_ps_min_clip = 18;
03101   double y_max;
03102   double y_min;
03103   int y_ps;
03104   int y_ps_max = 666;
03105   int y_ps_max_clip = 684;
03106   int y_ps_min = 126;
03107   int y_ps_min_clip = 108;
03108 
03109   date_time = timestring ( );
03110 
03111   x_max = g_xy[0+0*2];
03112   x_min = g_xy[0+0*2];
03113   y_max = g_xy[1+0*2];
03114   y_min = g_xy[1+0*2];
03115 
03116   for ( g = 0; g < g_num; g++ )
03117   {
03118     x_max = d_max ( x_max, g_xy[0+g*2] );
03119     x_min = d_min ( x_min, g_xy[0+g*2] );
03120     y_max = d_max ( y_max, g_xy[1+g*2] );
03121     y_min = d_min ( y_min, g_xy[1+g*2] );
03122   }
03123 //
03124 //  Plot the Delaunay triangulation.
03125 //
03126 //
03127 //  Open the output file.
03128 //
03129   file_out.open ( file_out_name );
03130 
03131   if ( !file_out )
03132   {
03133     cout << "\n";
03134     cout << "TRIANGULATION_PLOT_EPS - Fatal error!\n";
03135     cout << "  Cannot open the output file \"" << file_out_name << "\".\n";
03136     return false;
03137   }
03138 
03139   file_out << "%!PS-Adobe-3.0 EPSF-3.0\n";
03140   file_out << "%%Creator: triangulation_plot_eps.cc\n";
03141   file_out << "%%Title: " << file_out_name << "\n";
03142   file_out << "%%CreationDate: " << date_time << "\n";
03143   file_out << "%%Pages: 1\n";
03144   file_out << "%%Bounding Box: " << x_ps_min << "  " << y_ps_min << "  "
03145            << x_ps_max << "  " << y_ps_max << "\n";
03146   file_out << "%%Document-Fonts: Times-Roman\n";
03147   file_out << "%%LanguageLevel: 1\n";
03148   file_out << "%%EndComments\n";
03149   file_out << "%%BeginProlog\n";
03150   file_out << "/inch {72 mul} def\n";
03151   file_out << "%%EndProlog\n";
03152   file_out << "%%Page: 1 1\n";
03153   file_out << "save\n";
03154   file_out << "%\n";
03155   file_out << "%  Set the RGB line color to very light gray.\n";
03156   file_out << "%\n";
03157   file_out << "0.900  0.900  0.900 setrgbcolor\n";
03158   file_out << "%\n";
03159   file_out << "%  Draw a gray border around the page.\n";
03160   file_out << "%\n";
03161   file_out << "newpath\n";
03162   file_out << "  " << x_ps_min << "  " << y_ps_min << " moveto\n";
03163   file_out << "  " << x_ps_max << "  " << y_ps_min << " lineto\n";
03164   file_out << "  " << x_ps_max << "  " << y_ps_max << " lineto\n";
03165   file_out << "  " << x_ps_min << "  " << y_ps_max << " lineto\n";
03166   file_out << "  " << x_ps_min << "  " << y_ps_min << " lineto\n";
03167   file_out << "stroke\n";
03168   file_out << "%\n";
03169   file_out << "%  Set the RGB line color to black.\n";
03170   file_out << "%\n";
03171   file_out << "0.000  0.000  0.000 setrgbcolor\n";
03172   file_out << "%\n";
03173   file_out << "%  Set the font and its size.\n";
03174   file_out << "%\n";
03175   file_out << "/Times-Roman findfont\n";
03176   file_out << "0.50 inch scalefont\n";
03177   file_out << "setfont\n";
03178   file_out << "%\n";
03179   file_out << "%  Print a title.\n";
03180   file_out << "%\n";
03181   file_out << "210  702  moveto\n";
03182   file_out << "(Triangulation)  show\n";
03183   file_out << "%\n";
03184   file_out << "%  Define a clipping polygon.\n";
03185   file_out << "%\n";
03186   file_out << "newpath\n";
03187   file_out << "  " << x_ps_min_clip << "  " << y_ps_min_clip << " moveto\n";
03188   file_out << "  " << x_ps_max_clip << "  " << y_ps_min_clip << " lineto\n";
03189   file_out << "  " << x_ps_max_clip << "  " << y_ps_max_clip << " lineto\n";
03190   file_out << "  " << x_ps_min_clip << "  " << y_ps_max_clip << " lineto\n";
03191   file_out << "  " << x_ps_min_clip << "  " << y_ps_min_clip << " lineto\n";
03192   file_out << "clip newpath\n";
03193   file_out << "%\n";
03194   file_out << "%  Set the RGB line color to green.\n";
03195   file_out << "%\n";
03196   file_out << "0.000  0.750  0.150 setrgbcolor\n";
03197   file_out << "%\n";
03198   file_out << "%  Draw the nodes.\n";
03199   file_out << "%\n";
03200 
03201   for ( g = 0; g < g_num; g++ )
03202   {
03203     x_ps = int(
03204       ( ( x_max - g_xy[0+g*2] ) * double( x_ps_min )
03205       + ( g_xy[0+g*2] - x_min ) * double( x_ps_max ) )
03206       / ( x_max - x_min ) );
03207 
03208     y_ps = int(
03209       ( ( y_max - g_xy[1+g*2] ) * double( y_ps_min )
03210       + ( g_xy[1+g*2] - y_min ) * double( y_ps_max ) )
03211       / ( y_max - y_min ) );
03212 
03213     file_out << "newpath " << x_ps << "  "
03214              << y_ps << " 5 0 360 arc closepath fill\n";
03215   }
03216 
03217   file_out << "%\n";
03218   file_out << "%  Set the RGB line color to red.\n";
03219   file_out << "%\n";
03220   file_out << "0.900  0.200  0.100 setrgbcolor\n";
03221   file_out << "%\n";
03222   file_out << "%  Draw the triangles.\n";
03223   file_out << "%\n";
03224 
03225   for ( t = 1; t <= tri_num; t++ )
03226   {
03227     file_out << "newpath\n";
03228 
03229     for ( j = 1; j <= 4; j++ )
03230     {
03231       e = i_wrap ( j, 1, 3 );
03232 
03233       k = nod_tri[3*(t-1)+e-1];
03234 
03235       x_ps = int(
03236         ( ( x_max - g_xy[0+(k-1)*2] ) * double( x_ps_min )
03237         + ( g_xy[0+(k-1)*2] - x_min ) * double( x_ps_max ) )
03238         / ( x_max - x_min ) );
03239 
03240       y_ps = int(
03241         ( ( y_max - g_xy[1+(k-1)*2] ) * double( y_ps_min )
03242         + ( g_xy[1+(k-1)*2] - y_min ) * double( y_ps_max ) )
03243         / ( y_max - y_min ) );
03244 
03245       if ( j == 1 )
03246       {
03247         file_out << x_ps << "  " << y_ps << " moveto\n";
03248       }
03249       else
03250       {
03251         file_out << x_ps << "  " << y_ps << " lineto\n";
03252       }
03253 
03254     }
03255 
03256     file_out << "stroke\n";
03257 
03258   }
03259 
03260   file_out << "restore  showpage\n";
03261   file_out << "%\n";
03262   file_out << "%  End of page.\n";
03263   file_out << "%\n";
03264   file_out << "%%Trailer\n";
03265   file_out << "%%EOF\n";
03266 
03267   file_out.close ( );
03268 
03269   return true;
03270 }
03271 //******************************************************************************
03272 
03273 void triangulation_print ( int point_num, double xc[], int tri_num,
03274   int tri_vert[], int tri_nabe[] )
03275 
03276 //******************************************************************************
03277 //
03278 //  Purpose:
03279 //
03280 //    TRIANGULATION_PRINT prints information defining a Delaunay triangulation.
03281 //
03282 //  Discussion:
03283 //
03284 //    Triangulations created by RTRIS include extra information encoded
03285 //    in the negative values of TRI_NABE.
03286 //
03287 //    Because some of the nodes counted in POINT_NUM may not actually be
03288 //    used in the triangulation, I needed to compute the true number
03289 //    of vertices.  I added this calculation on 13 October 2001.
03290 //
03291 //    Ernest Fasse pointed out an error in the indexing of VERTEX_LIST,
03292 //    which was corrected on 19 February 2004.
03293 //
03294 //  Modified:
03295 //
03296 //    19 February 2004
03297 //
03298 //  Author:
03299 //
03300 //    John Burkardt
03301 //
03302 //  Parameters:
03303 //
03304 //    Input, int POINT_NUM, the number of points.
03305 //
03306 //    Input, double XC[2*POINT_NUM], the point coordinates.
03307 //
03308 //    Input, int TRI_NUM, the number of triangles.
03309 //
03310 //    Input, int TRI_VERT[3*TRI_NUM], the nodes that make up the triangles.
03311 //
03312 //    Input, int TRI_NABE[3*TRI_NUM], the triangle neighbors on each side.
03313 //    If there is no triangle neighbor on a particular side, the value of
03314 //    TRI_NABE should be negative.  If the triangulation data was created by
03315 //    DTRIS2, then there is more information encoded in the negative values.
03316 //
03317 {
03318 # define DIM_NUM 2
03319 
03320   int boundary_num;
03321   int i;
03322   int j;
03323   int k;
03324   int n1;
03325   int n2;
03326   int s;
03327   int s1;
03328   int s2;
03329   bool skip;
03330   int t;
03331   int *vertex_list;
03332   int vertex_num;
03333 
03334   cout << "\n";
03335   cout << "TRIANGULATION_PRINT\n";
03336   cout << "  Information defining a triangulation.\n";
03337   cout << "\n";
03338   cout << "  The number of points is " << point_num << "\n";
03339 
03340   dmat_transpose_print ( DIM_NUM, point_num, xc, "  Point coordinates" );
03341 
03342   cout << "\n";
03343   cout << "  The number of triangles is " << tri_num << "\n";
03344   cout << "\n";
03345   cout << "  Sets of three points are used as vertices of\n";
03346   cout << "  the triangles.  For each triangle, the points\n";
03347   cout << "  are listed in counterclockwise order.\n";
03348 
03349   imat_transpose_print ( 3, tri_num, tri_vert, "  Triangle nodes" );
03350 
03351   cout << "\n";
03352   cout << "  On each side of a given triangle, there is either\n";
03353   cout << "  another triangle, or a piece of the convex hull.\n";
03354   cout << "  For each triangle, we list the indices of the three\n";
03355   cout << "  neighbors, or (if negative) the codes of the\n";
03356   cout << "  segments of the convex hull.\n";
03357 
03358   imat_transpose_print ( 3, tri_num, tri_nabe, "  Triangle neighbors" );
03359 //
03360 //  Determine VERTEX_NUM, the number of vertices.  This is not
03361 //  the same as the number of points!
03362 //
03363   vertex_list = new int[3*tri_num];
03364 
03365   k = 0;
03366   for ( t = 0; t < tri_num; t++ )
03367   {
03368     for ( s = 0; s < 3; s++ )
03369     {
03370       vertex_list[k] = tri_vert[s+t*3];
03371       k = k + 1;
03372     }
03373   }
03374 
03375   ivec_sort_heap_a ( 3*tri_num, vertex_list );
03376 
03377   ivec_sorted_unique ( 3*tri_num, vertex_list, &vertex_num );
03378 
03379   delete [] vertex_list;
03380 //
03381 //  Determine the number of boundary points.
03382 //
03383   boundary_num = 2 * vertex_num - tri_num - 2;
03384 
03385   cout << "\n";
03386   cout << "  The number of boundary points is " << boundary_num << "\n";
03387   cout << "\n";
03388   cout << "  The segments that make up the convex hull can be\n";
03389   cout << "  determined from the negative entries of the triangle\n";
03390   cout << "  neighbor list.\n";
03391   cout << "\n";
03392   cout << "  # Tri Side  N1  N2\n";
03393   cout << "\n";
03394 
03395   skip = false;
03396 
03397   k = 0;
03398 
03399   for ( i = 0; i < tri_num; i++ )
03400   {
03401     for ( j = 0; j < 3; j++ )
03402     {
03403       if ( tri_nabe[j+i*3] < 0 )
03404       {
03405         s = -tri_nabe[j+i*3];
03406         t = s / 3;
03407 
03408         if ( t < 1 || tri_num < t )
03409         {
03410           cout << "\n";
03411           cout << "  Sorry, this data does not use the DTRIS2\n";
03412           cout << "  convention for convex hull segments.\n";
03413           skip = true;
03414           break;
03415         }
03416 
03417         s1 = ( s % 3 ) + 1;
03418         s2 = i_wrap ( s1+1, 1, 3 );
03419         k = k + 1;
03420         n1 = tri_vert[s1-1+(t-1)*3];
03421         n2 = tri_vert[s2-1+(t-1)*3];
03422         cout << setw(4) << k  << "  "
03423              << setw(4) << t  << "  "
03424              << setw(4) << s1 << "  "
03425              << setw(4) << n1 << "  "
03426              << setw(4) << n2 << "\n";
03427       }
03428 
03429     }
03430 
03431     if ( skip )
03432     {
03433       break;
03434     }
03435 
03436   }
03437 
03438   return;
03439 # undef DIM_NUM
03440 }
03441 //******************************************************************************
03442 
03443 void vbedg ( double x, double y, int point_num, double point_xy[], int tri_num,
03444   int tri_vert[], int tri_nabe[], int *ltri, int *ledg, int *rtri, int *redg )
03445 
03446 //******************************************************************************
03447 //
03448 //  Purpose:
03449 //
03450 //    VBEDG determines which boundary edges are visible to a point.
03451 //
03452 //  Discussion:
03453 //
03454 //    The point (X,Y) is assumed to be outside the convex hull of the
03455 //    region covered by the 2D triangulation.
03456 //
03457 //  Author:
03458 //
03459 //    Barry Joe,
03460 //    Department of Computing Science,
03461 //    University of Alberta,
03462 //    Edmonton, Alberta, Canada  T6G 2H1
03463 //
03464 //  Reference:
03465 //
03466 //    Barry Joe,
03467 //    GEOMPACK - a software package for the generation of meshes
03468 //    using geometric algorithms,
03469 //    Advances in Engineering Software,
03470 //    Volume 13, pages 325-331, 1991.
03471 //
03472 //  Modified:
03473 //
03474 //    02 September 2003
03475 //
03476 //  Parameters:
03477 //
03478 //    Input, double X, Y, the coordinates of a point outside the convex hull
03479 //    of the current triangulation.
03480 //
03481 //    Input, int POINT_NUM, the number of points.
03482 //
03483 //    Input, double POINT_XY[POINT_NUM*2], the coordinates of the vertices.
03484 //
03485 //    Input, int TRI_NUM, the number of triangles.
03486 //
03487 //    Input, int TRI_VERT[TRI_NUM*3], the triangle incidence list.
03488 //
03489 //    Input, int TRI_NABE[TRI_NUM*3], the triangle neighbor list; negative
03490 //    values are used for links of a counter clockwise linked list of boundary
03491 //    edges;
03492 //      LINK = -(3*I + J-1) where I, J = triangle, edge index.
03493 //
03494 //    Input/output, int *LTRI, *LEDG.  If LTRI != 0 then these values are
03495 //    assumed to be already computed and are not changed, else they are updated.
03496 //    On output, LTRI is the index of boundary triangle to the left of the
03497 //    leftmost boundary triangle visible from (X,Y), and LEDG is the boundary
03498 //    edge of triangle LTRI to the left of the leftmost boundary edge visible
03499 //    from (X,Y).  1 <= LEDG <= 3.
03500 //
03501 //    Input/output, int *RTRI.  On input, the index of the boundary triangle
03502 //    to begin the search at.  On output, the index of the rightmost boundary
03503 //    triangle visible from (X,Y).
03504 //
03505 //    Input/output, int *REDG, the edge of triangle RTRI that is visible
03506 //    from (X,Y).  1 <= REDG <= 3.
03507 //
03508 {
03509   int a;
03510   double ax;
03511   double ay;
03512   int b;
03513   double bx;
03514   double by;
03515   bool done;
03516   int e;
03517   int l;
03518   int lr;
03519   int t;
03520 //
03521 //  Find the rightmost visible boundary edge using links, then possibly
03522 //  leftmost visible boundary edge using triangle neighbor information.
03523 //
03524   if ( *ltri == 0 )
03525   {
03526     done = false;
03527     *ltri = *rtri;
03528     *ledg = *redg;
03529   }
03530   else
03531   {
03532     done = true;
03533   }
03534 
03535   for ( ; ; )
03536   {
03537     l = -tri_nabe[3*((*rtri)-1)+(*redg)-1];
03538     t = l / 3;
03539     e = 1 + l % 3;
03540     a = tri_vert[3*(t-1)+e-1];
03541 
03542     if ( e <= 2 )
03543     {
03544       b = tri_vert[3*(t-1)+e];
03545     }
03546     else
03547     {
03548       b = tri_vert[3*(t-1)+0];
03549     }
03550 
03551     ax = point_xy[2*(a-1)+0];
03552     ay = point_xy[2*(a-1)+1];
03553 
03554     bx = point_xy[2*(b-1)+0];
03555     by = point_xy[2*(b-1)+1];
03556 
03557     lr = lrline ( x, y, ax, ay, bx, by, 0.0 );
03558 
03559     if ( lr <= 0 )
03560     {
03561       break;
03562     }
03563 
03564     *rtri = t;
03565     *redg = e;
03566 
03567   }
03568 
03569   if ( done )
03570   {
03571     return;
03572   }
03573 
03574   t = *ltri;
03575   e = *ledg;
03576 
03577   for ( ; ; )
03578   {
03579     b = tri_vert[3*(t-1)+e-1];
03580     e = i_wrap ( e-1, 1, 3 );
03581 
03582     while ( 0 < tri_nabe[3*(t-1)+e-1] )
03583     {
03584       t = tri_nabe[3*(t-1)+e-1];
03585 
03586       if ( tri_vert[3*(t-1)+0] == b )
03587       {
03588         e = 3;
03589       }
03590       else if ( tri_vert[3*(t-1)+1] == b )
03591       {
03592         e = 1;
03593       }
03594       else
03595       {
03596         e = 2;
03597       }
03598 
03599     }
03600 
03601     a = tri_vert[3*(t-1)+e-1];
03602     ax = point_xy[2*(a-1)+0];
03603     ay = point_xy[2*(a-1)+1];
03604 
03605     bx = point_xy[2*(b-1)+0];
03606     by = point_xy[2*(b-1)+1];
03607 
03608     lr = lrline ( x, y, ax, ay, bx, by, 0.0 );
03609 
03610     if ( lr <= 0 )
03611     {
03612       break;
03613     }
03614 
03615   }
03616 
03617   *ltri = t;
03618   *ledg = e;
03619 
03620   return;
03621 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines