util_sparx.cpp File Reference

#include <cstring>
#include <ctime>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <boost/format.hpp>
#include "emdata.h"
#include "util.h"
#include "fundamentals.h"
#include "lapackblas.h"
#include "lbfgsb.h"
#include "steepest.h"
#include "emassert.h"
#include "randnum.h"
#include <gsl/gsl_sf_bessel.h>
#include <cmath>

Include dependency graph for util_sparx.cpp:

Go to the source code of this file.

Classes

struct  ori_t
struct  cmpang
struct  tmpstruct
struct  stcom_
struct  ccf_point
struct  ccf_value
struct  point3d_t

Defines

#define fdata(i, j)   fdata[ i-1 + (j-1)*nxdata ]
#define fdata(i, j)   fdata[ i-1 + (j-1)*nxdata ]
#define circ(i)   circ[i-1]
#define numr(i, j)   numr[(j-1)*3 + i-1]
#define xim(i, j)   xim[(j-1)*nsam + i-1]
#define tab1(i)   tab1[i-1]
#define xcmplx(i, j)   xcmplx [(j-1)*2 + i-1]
#define br(i)   br[i-1]
#define bi(i)   bi[i-1]
#define b(i)   b[i-1]
#define circ1(i)   circ1[i-1]
#define circ2(i)   circ2[i-1]
#define t(i)   t[i-1]
#define q(i)   q[i-1]
#define b(i)   b[i-1]
#define t7(i)   t7[i-1]
#define dout(i, j)   dout[i+maxrin*j]
#define circ1b(i)   circ1b[i-1]
#define circ2b(i)   circ2b[i-1]
#define dout(i, j)   dout[i+maxrin*j]
#define circ1b(i)   circ1b[i-1]
#define circ2b(i)   circ2b[i-1]
#define QUADPI   3.141592653589793238462643383279502884197
#define PI2   2*QUADPI
#define QUADPI   3.141592653589793238462643383279502884197
#define PI2   QUADPI*2
#define deg_rad   QUADPI/180.0
#define rad_deg   180.0/QUADPI
#define old_ptr(i, j, k)   old_ptr[i+(j+(k*ny))*nx]
#define new_ptr(iptr, jptr, kptr)   new_ptr[iptr+(jptr+(kptr*new_ny))*new_nx]
#define inp(i, j, k)   inp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*ny))*nx]
#define outp(i, j, k)   outp[i+(j+(k*new_ny))*new_nx]
#define inp(i, j, k)   inp[i+(j+(k*ny))*nx]
#define outp(i, j, k)   outp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*new_ny))*new_nx]
#define QUADPI   3.141592653589793238462643383279502884197
#define DGR_TO_RAD   QUADPI/180
#define DM(I)   DM [I-1]
#define SS(I)   SS [I-1]
#define DM(I)   DM[I-1]
#define B(i, j)   Bptr[i-1+((j-1)*NSAM)]
#define CUBE(i, j, k)   CUBEptr[(i-1)+((j-1)+((k-1)*NY3D))*NX3D]
#define W(i, j)   Wptr [i-1+((j-1)*Wnx)]
#define PROJ(i, j)   PROJptr [i-1+((j-1)*NNNN)]
#define SS(I, J)   SS [I-1 + (J-1)*6]
#define W(i, j)   Wptr [i-1+((j-1)*Wnx)]
#define PROJ(i, j)   PROJptr [i-1+((j-1)*NNNN)]
#define SS(I, J)   SS [I-1 + (J-1)*6]
#define RI(i, j)   RI [(i-1) + ((j-1)*3)]
#define CC(i)   CC [i-1]
#define CP(i)   CP [i-1]
#define VP(i)   VP [i-1]
#define VV(i)   VV [i-1]
#define AMAX1(i, j)   i>j?i:j
#define AMIN1(i, j)   i<j?i:j
#define mymax(x, y)   (((x)>(y))?(x):(y))
#define mymin(x, y)   (((x)<(y))?(x):(y))
#define sign(x, y)   (((((y)>0)?(1):(-1))*(y!=0))*(x))
#define quadpi   3.141592653589793238462643383279502884197
#define dgr_to_rad   quadpi/180
#define deg_to_rad   quadpi/180
#define rad_to_deg   180/quadpi
#define rad_to_dgr   180/quadpi
#define TRUE   1
#define FALSE   0
#define theta(i)   theta [i-1]
#define phi(i)   phi [i-1]
#define weight(i)   weight [i-1]
#define lband(i)   lband [i-1]
#define ts(i)   ts [i-1]
#define thetast(i)   thetast [i-1]
#define key(i)   key [i-1]
#define TRUE_   (1)
#define FALSE_   (0)
#define abs(x)   ((x) >= 0 ? (x) : -(x))
#define img_ptr(i, j, k)   img_ptr[2*(i-1)+((j-1)+((k-1)*ny))*nxo]
#define img_ptr(i, j, k)   img_ptr[i+(j+(k*ny))*nx]
#define img2_ptr(i, j, k)   img2_ptr[i+(j+(k*ny))*nx]
#define cent(i)   out[i+N]
#define assign(i)   out[i]
#define data(i, j)   group[i*ny+j]

Functions

int i_dnnt (double *x)
int addnod_ (int *nst, int *k, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *lnew, int *ier)
double angle_ (double *v1, double *v2, double *v3)
double areas_ (double *v1, double *v2, double *v3)
double areav_new__ (int *k, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *ier)
int bdyadd_ (int *kk, int *i1, int *i2, int *list, int *lptr, int *lend, int *lnew)
int bnodes_ (int *n, int *list, int *lptr, int *lend, int *nodes, int *nb, int *na, int *nt)
int circle_ (int *k, double *xc, double *yc, int *ier)
int circum_ (double *v1, double *v2, double *v3, double *c__, int *ier)
int covsph_ (int *kk, int *n0, int *list, int *lptr, int *lend, int *lnew)
int crlist_ (int *n, int *ncol, double *x, double *y, double *z__, int *list, int *lend, int *lptr, int *lnew, int *ltri, int *listc, int *nb, double *xc, double *yc, double *zc, double *rc, int *ier)
int delarc_ (int *n, int *io1, int *io2, int *list, int *lptr, int *lend, int *lnew, int *ier)
int delnb_ (int *n0, int *nb, int *n, int *list, int *lptr, int *lend, int *lnew, int *lph)
int delnod_ (int *k, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *lnew, int *lwk, int *iwk, int *ier)
int drwarc_ (int *, double *p, double *q, double *tol, int *nseg)
int edge_ (int *in1, int *in2, double *x, double *y, double *z__, int *lwk, int *iwk, int *list, int *lptr, int *lend, int *ier)
int getnp_ (double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *l, int *npts, double *df, int *ier)
int insert_ (int *k, int *lp, int *list, int *lptr, int *lnew)
long int inside_ (double *p, int *lv, double *xv, double *yv, double *zv, int *nv, int *listv, int *ier)
int intadd_ (int *kk, int *i1, int *i2, int *i3, int *list, int *lptr, int *lend, int *lnew)
int intrsc_ (double *p1, double *p2, double *cn, double *p, int *ier)
int jrand_ (int *n, int *ix, int *iy, int *iz)
long int left_ (double *x1, double *y1, double *z1, double *x2, double *y2, double *z2, double *x0, double *y0, double *z0)
int lstptr_ (int *lpl, int *nb, int *list, int *lptr)
int nbcnt_ (int *lpl, int *lptr)
int nearnd_ (double *p, int *ist, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, double *al)
int optim_ (double *x, double *y, double *z__, int *na, int *list, int *lptr, int *lend, int *nit, int *iwk, int *ier)
int projct_ (double *px, double *py, double *pz, double *ox, double *oy, double *oz, double *ex, double *ey, double *ez, double *vx, double *vy, double *vz, long int *init, double *x, double *y, double *z__, int *ier)
int scoord_ (double *px, double *py, double *pz, double *plat, double *plon, double *pnrm)
double store_ (double *x)
int swap_ (int *in1, int *in2, int *io1, int *io2, int *list, int *lptr, int *lend, int *lp21)
long int swptst_ (int *n1, int *n2, int *n3, int *n4, double *x, double *y, double *z__)
int trans_ (int *n, double *rlat, double *rlon, double *x, double *y, double *z__)
int trfind_ (int *nst, double *p, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, double *b1, double *b2, double *b3, int *i1, int *i2, int *i3)
int trlist_ (int *n, int *list, int *lptr, int *lend, int *nrow, int *nt, int *ltri, int *ier)
int trlprt_ (int *n, double *x, double *y, double *z__, int *iflag, int *nrow, int *nt, int *ltri, int *lout)
int trmesh_ (int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *lnew, int *near__, int *next, double *dist, int *ier)
int trplot_ (int *lun, double *pltsiz, double *elat, double *elon, double *a, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, char *, long int *numbr, int *ier, short)
int trprnt_ (int *n, double *x, double *y, double *z__, int *iflag, int *list, int *lptr, int *lend, int *lout)
int vrplot_ (int *lun, double *pltsiz, double *elat, double *elon, double *a, int *n, double *x, double *y, double *z__, int *nt, int *listc, int *lptr, int *lend, double *xc, double *yc, double *zc, char *, long int *numbr, int *ier, short)
int random_ (int *ix, int *iy, int *iz, double *rannum)
int find_group (int ix, int iy, int iz, int grpid, EMData *mg, EMData *visited)

Variables

stcom_ stcom_1


Define Documentation

#define abs (  )     ((x) >= 0 ? (x) : -(x))

Definition at line 7502 of file util_sparx.cpp.

#define AMAX1 ( i,
 )     i>j?i:j

Definition at line 5617 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define AMIN1 ( i,
 )     i<j?i:j

Definition at line 5618 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define assign (  )     out[i]

Definition at line 18926 of file util_sparx.cpp.

Referenced by EMAN::Util::cluster_pairwise().

#define B ( i,
 )     Bptr[i-1+((j-1)*NSAM)]

#define b (  )     b[i-1]

Definition at line 3189 of file util_sparx.cpp.

#define b (  )     b[i-1]

#define bi (  )     bi[i-1]

#define br (  )     br[i-1]

#define CC (  )     CC [i-1]

Definition at line 5613 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define cent (  )     out[i+N]

Definition at line 18925 of file util_sparx.cpp.

Referenced by EMAN::Util::cluster_pairwise().

#define circ (  )     circ[i-1]

#define circ1 (  )     circ1[i-1]

#define circ1b (  )     circ1b[i-1]

Definition at line 3912 of file util_sparx.cpp.

#define circ1b (  )     circ1b[i-1]

#define circ2 (  )     circ2[i-1]

#define circ2b (  )     circ2b[i-1]

Definition at line 3913 of file util_sparx.cpp.

#define circ2b (  )     circ2b[i-1]

#define CP (  )     CP [i-1]

Definition at line 5614 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define CUBE ( i,
j,
 )     CUBEptr[(i-1)+((j-1)+((k-1)*NY3D))*NX3D]

Definition at line 5464 of file util_sparx.cpp.

Referenced by EMAN::Util::BPCQ().

#define data ( i,
 )     group[i*ny+j]

Definition at line 19232 of file util_sparx.cpp.

Referenced by EMAN::EMData::absi(), EMAN::EMData::add(), EMAN::file_store::add_image(), EMAN::EMData::addsquare(), EMAN::RotatePrecenterAligner::align(), EMAN::RotationalAligner::align_180_ambiguous(), EMAN::EMData::amplitude(), EMAN::EMData::apply_radial_func(), EMAN::EMData::calc_az_dist(), EMAN::EMData::calc_center_of_mass(), EMAN::EMData::calc_highest_locations(), EMAN::EMData::calc_hist(), EMAN::MaskEdgeMeanProcessor::calc_locals(), EMAN::EMData::calc_max_location(), EMAN::EMData::calc_min_location(), EMAN::EMData::calc_radial_dist(), circumference(), EMAN::BoxingTools::classify(), EMAN::EMData::common_lines(), EMAN::EMData::common_lines_real(), EMAN::Util::cyclicshift(), EMAN::PointArray::distmx(), EMAN::EMData::div(), EMAN::EMData::do_ift_inplace(), EMAN::EMData::EMData(), EMAN::EMData::get_attr(), EMAN::EMData::get_circle_mean(), get_data_as_vector(), EMAN::EMData::get_edge_mean(), EMAN::EMData::get_fft_amplitude(), EMAN::EMData::get_fft_phase(), EMAN::file_store::get_image(), EMAN::newfile_store::get_image(), EMAN::Util::histc(), EMAN::EMData::imag(), EMAN::EMData::insert_scaled_sum(), EMAN::SingleSpiderIO::is_valid(), EMAN::SpiderIO::is_valid(), EMAN::PifIO::is_valid(), EMAN::MrcIO::is_valid(), EMAN::ImagicIO::is_valid(), EMAN::IcosIO::is_valid(), EMAN::Gatan2IO::is_valid(), EMAN::EmIO::is_valid(), EMAN::EmimIO::is_valid(), EMAN::DM3IO::is_valid(), EMAN::EMData::little_big_dot(), EMAN::EMData::log(), EMAN::EMData::log10(), main(), EMAN::TestUtil::make_image_file_by_mode(), mpi_init(), mpi_start(), EMAN::EMData::mult(), EMAN::EMData::mult_complex_efficient(), EMAN::EMData::norm_pad(), EMAN::Util::Normalize_ring(), EMAN::EMData::operator=(), EMAN::PointArray::pdb2mrc_by_nfft(), EMAN::EMData::phase(), EMAN::XYZProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), EMAN::DiffBlockProcessor::process_inplace(), EMAN::BoxStatProcessor::process_inplace(), EMAN::AreaProcessor::process_inplace(), EMAN::ComplexPixelProcessor::process_inplace(), EMAN::CoordinateProcessor::process_inplace(), EMAN::RealPixelProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), EMAN::BoxMedianProcessor::process_pixel(), EMAN::GaussFFTProjector::project3d(), EMAN::PointArray::projection_by_nfft(), EMAN::Gatan::TagData::read_array_data(), EMAN::EMData::real(), EMAN::EMData::render_amp24(), EMAN::EMData::render_ap24(), EMAN::EMData::ri2ap(), EMAN::EMData::ri2inten(), EMAN::EMData::rot_scale_conv_new(), EMAN::EMData::rot_scale_conv_new_background(), EMAN::EMData::rotate_x(), EMAN::BoxSVDClassifier::setDims(), EMAN::EMData::setup4slice(), EMAN::EMData::sqrt(), EMAN::EMData::sub(), EMAN::EMData::subsquare(), EMAN::EMData::to_value(), EMAN::EMData::update_stat(), EMAN::Util::vareas(), EMAN::TestUtil::verify_image_file_by_mode(), EMAN::EMUtil::vertical_acf(), and EMAN::U3DWriter::write_clod_mesh_generator_node().

#define deg_rad   QUADPI/180.0

#define deg_to_rad   quadpi/180

Definition at line 6793 of file util_sparx.cpp.

#define dgr_to_rad   quadpi/180

#define DGR_TO_RAD   QUADPI/180

Definition at line 5415 of file util_sparx.cpp.

#define DM (  )     DM[I-1]

Definition at line 5462 of file util_sparx.cpp.

#define DM (  )     DM [I-1]

Definition at line 5462 of file util_sparx.cpp.

Referenced by EMAN::Util::BPCQ(), and EMAN::Util::CANG().

#define dout ( i,
 )     dout[i+maxrin*j]

Definition at line 3911 of file util_sparx.cpp.

#define dout ( i,
 )     dout[i+maxrin*j]

#define FALSE   0

Definition at line 6797 of file util_sparx.cpp.

#define FALSE_   (0)

Definition at line 7501 of file util_sparx.cpp.

#define fdata ( i,
 )     fdata[ i-1 + (j-1)*nxdata ]

Definition at line 709 of file util_sparx.cpp.

#define fdata ( i,
 )     fdata[ i-1 + (j-1)*nxdata ]

Definition at line 709 of file util_sparx.cpp.

Referenced by EMAN::Util::quadri(), quadri(), and EMAN::Util::quadri_background().

#define img2_ptr ( i,
j,
 )     img2_ptr[i+(j+(k*ny))*nx]

#define img_ptr ( i,
j,
 )     img_ptr[i+(j+(k*ny))*nx]

Definition at line 18549 of file util_sparx.cpp.

#define img_ptr ( i,
j,
 )     img_ptr[2*(i-1)+((j-1)+((k-1)*ny))*nxo]

#define inp ( i,
j,
 )     inp[i+(j+(k*ny))*nx]

Definition at line 5049 of file util_sparx.cpp.

#define inp ( i,
j,
 )     inp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*ny))*nx]

Definition at line 5049 of file util_sparx.cpp.

Referenced by EMAN::Util::pad(), and EMAN::Util::window().

#define key (  )     key [i-1]

#define lband (  )     lband [i-1]

Definition at line 6803 of file util_sparx.cpp.

#define mymax ( x,
 )     (((x)>(y))?(x):(y))

Definition at line 6786 of file util_sparx.cpp.

#define mymin ( x,
 )     (((x)<(y))?(x):(y))

Definition at line 6787 of file util_sparx.cpp.

#define new_ptr ( iptr,
jptr,
kptr   )     new_ptr[iptr+(jptr+(kptr*new_ny))*new_nx]

#define numr ( i,
 )     numr[(j-1)*3 + i-1]

#define old_ptr ( i,
j,
 )     old_ptr[i+(j+(k*ny))*nx]

Definition at line 4944 of file util_sparx.cpp.

Referenced by EMAN::Util::decimate().

#define outp ( i,
j,
 )     outp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*new_ny))*new_nx]

Definition at line 5050 of file util_sparx.cpp.

#define outp ( i,
j,
 )     outp[i+(j+(k*new_ny))*new_nx]

Definition at line 5050 of file util_sparx.cpp.

Referenced by EMAN::Util::pad(), and EMAN::Util::window().

#define phi (  )     phi [i-1]

#define PI2   QUADPI*2

Definition at line 4321 of file util_sparx.cpp.

#define PI2   2*QUADPI

#define PROJ ( i,
 )     PROJptr [i-1+((j-1)*NNNN)]

Definition at line 5610 of file util_sparx.cpp.

#define PROJ ( i,
 )     PROJptr [i-1+((j-1)*NNNN)]

Definition at line 5610 of file util_sparx.cpp.

Referenced by EMAN::Util::WTF(), and EMAN::Util::WTM().

#define q (  )     q[i-1]

#define quadpi   3.141592653589793238462643383279502884197

Definition at line 6791 of file util_sparx.cpp.

Referenced by apmq(), and aprq2d().

#define QUADPI   3.141592653589793238462643383279502884197

Definition at line 5414 of file util_sparx.cpp.

#define QUADPI   3.141592653589793238462643383279502884197

Definition at line 5414 of file util_sparx.cpp.

#define QUADPI   3.141592653589793238462643383279502884197

Definition at line 5414 of file util_sparx.cpp.

#define rad_deg   180.0/QUADPI

#define rad_to_deg   180/quadpi

Definition at line 6794 of file util_sparx.cpp.

#define rad_to_dgr   180/quadpi

Definition at line 6795 of file util_sparx.cpp.

#define RI ( i,
 )     RI [(i-1) + ((j-1)*3)]

Definition at line 5612 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define sign ( x,
 )     (((((y)>0)?(1):(-1))*(y!=0))*(x))

#define SS ( I,
 )     SS [I-1 + (J-1)*6]

Definition at line 5611 of file util_sparx.cpp.

#define SS ( I,
 )     SS [I-1 + (J-1)*6]

Definition at line 5611 of file util_sparx.cpp.

#define SS (  )     SS [I-1]

Definition at line 5611 of file util_sparx.cpp.

Referenced by EMAN::Util::CANG(), EMAN::Util::WTF(), and EMAN::Util::WTM().

#define t (  )     t[i-1]

Definition at line 3187 of file util_sparx.cpp.

Referenced by EMAN::OrientationGenerator::add_orientation(), EMAN::Util::ali2d_ccf_list(), EMAN::RT3DSphereAligner::align(), EMAN::RT3DGridAligner::align(), EMAN::Refine3DAligner::align(), EMAN::RefineAligner::align(), EMAN::RTFSlowExhaustiveAligner::align(), EMAN::RTFExhaustiveAligner::align(), EMAN::RotateFlipAligner::align(), EMAN::RotateTranslateFlipAligner::align(), EMAN::RotateTranslateAligner::align(), EMAN::TranslationalAligner::align(), bmv_(), EMAN::Util::BPCQ(), EMAN::Symmetry3D::cache_au_planes(), EMAN::EMData::calc_max_location(), EMAN::EMData::calc_min_location(), EMAN::EMData::calc_mutual_correlation(), EMAN::EMData::common_lines_real(), EMAN::HighpassButterworthProcessor::create_radial_func(), crlist_(), EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_vec(), EMAN::EMData::cut_slice(), EMAN::EMData::do_radon(), EMAN::EMData::dot_rotate_translate(), dpofa_(), EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), fftr_q(), formk_(), EMAN::RandomOrientationGenerator::gen_orientations(), EMAN::TetrahedralSym::get_asym_unit_points(), EMAN::PlatonicSym::get_asym_unit_points(), EMAN::EMData::get_attr(), EMAN::EMData::get_pixel_filtered(), EMAN::Transform3D::get_sym_type(), EMAN::Util::get_time_label(), EMAN::Transform::icos_5_to_2(), intrsc_(), EMAN::Transform::inverse(), EMAN::Vec2< Type >::length(), EMAN::Vec3< int >::length(), main(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::Transform::negate(), EMAN::FloatPoint::operator vector< float >(), EMAN::FloatSize::operator vector< float >(), EMAN::Util::point_is_in_triangle_2d(), EMAN::PawelProjector::prepcubes(), EMAN::Randnum::print_generator_type(), EMAN::ScaleTransformProcessor::process(), EMAN::TransformProcessor::process(), EMAN::TomoTiltEdgeMaskProcessor::process_inplace(), EMAN::TestTomoImage::process_inplace(), EMAN::Rotate180Processor::process_inplace(), EMAN::ScaleTransformProcessor::process_inplace(), EMAN::TransformProcessor::process_inplace(), EMAN::TestImageEllipse::process_inplace(), EMAN::TestImageHollowEllipse::process_inplace(), EMAN::IterBinMaskProcessor::process_inplace(), EMAN::AutoMask3DProcessor::process_inplace(), EMAN::SymSearchProcessor::process_inplace(), EMAN::ACFCenterProcessor::process_inplace(), EMAN::PhaseToMassCenterProcessor::process_inplace(), EMAN::ToMassCenterProcessor::process_inplace(), EMAN::FlipProcessor::process_inplace(), EMAN::NormalizeToLeastSquareProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), EMAN::BoxMedianProcessor::process_pixel(), EMAN::StandardProjector::project3d(), refalifn(), refalifn3d(), EMAN::EMData::render_amp24(), EMAN::EMData::render_ap24(), EMAN::EMData::rot_scale_conv(), EMAN::EMData::rot_scale_conv7(), EMAN::EMData::rot_scale_conv_new(), EMAN::EMData::rot_scale_conv_new_background(), EMAN::EMData::rot_scale_trans(), EMAN::EMData::rot_scale_trans_background(), EMAN::EMData::rotate(), EMAN::Util::rotate_phase_origin(), EMAN::EMData::rotate_translate(), EMAN::Matrix4::rotation(), EMAN::EMData::scale(), EMAN::EMData::set_attr_python(), setulb_(), slaed2_(), slaed8_(), slamch_(), slasq2_(), slasq3_(), slasv2_(), sormlq_(), sormqr_(), subsm_(), EMAN::MarchingCubes::surface_face_z(), test_shared_pointer(), EMAN::Transform::tet_3_to_2(), EMAN::Gatan::to_em_datatype(), EMAN::EMData::translate(), EMAN::Transform::transpose(), trplot_(), EMAN::EMData::unwrap(), varmx(), vrplot_(), EMAN::SpiderIO::write_single_header(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().

#define t7 (  )     t7[i-1]

#define tab1 (  )     tab1[i-1]

#define theta (  )     theta [i-1]

#define thetast (  )     thetast [i-1]

Definition at line 6805 of file util_sparx.cpp.

#define TRUE   1

Definition at line 6796 of file util_sparx.cpp.

#define TRUE_   (1)

Definition at line 7500 of file util_sparx.cpp.

#define ts (  )     ts [i-1]

Definition at line 6804 of file util_sparx.cpp.

#define VP (  )     VP [i-1]

Definition at line 5615 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define VV (  )     VV [i-1]

Definition at line 5616 of file util_sparx.cpp.

Referenced by EMAN::Util::WTM().

#define W ( i,
 )     Wptr [i-1+((j-1)*Wnx)]

Definition at line 5609 of file util_sparx.cpp.

#define W ( i,
 )     Wptr [i-1+((j-1)*Wnx)]

#define weight (  )     weight [i-1]

#define xcmplx ( i,
 )     xcmplx [(j-1)*2 + i-1]

Definition at line 2640 of file util_sparx.cpp.

Referenced by EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), and fftr_q().

#define xim ( i,
 )     xim[(j-1)*nsam + i-1]


Function Documentation

int addnod_ ( int *  nst,
int *  k,
double *  x,
double *  y,
double *  z__,
int *  list,
int *  lptr,
int *  lend,
int *  lnew,
int *  ier 
)

Definition at line 7954 of file util_sparx.cpp.

References abs, bdyadd_(), covsph_(), intadd_(), lstptr_(), swap_(), swptst_(), and trfind_().

Referenced by trmesh_(), and EMAN::Util::trmsh3_().

07957 {
07958     /* Initialized data */
07959 
07960     static double tol = 0.;
07961 
07962     /* System generated locals */
07963     int i__1;
07964 
07965     /* Local variables */
07966     static int l;
07967     static double p[3], b1, b2, b3;
07968     static int i1, i2, i3, kk, lp, in1, io1, io2, km1, lpf, ist, lpo1;
07969     extern /* Subroutine */ int swap_(int *, int *, int *,
07970             int *, int *, int *, int *, int *);
07971     static int lpo1s;
07972     extern /* Subroutine */ int bdyadd_(int *, int *, int *,
07973             int *, int *, int *, int *), intadd_(int *,
07974             int *, int *, int *, int *, int *, int *,
07975             int *), trfind_(int *, double *, int *,
07976             double *, double *, double *, int *, int *,
07977             int *, double *, double *, double *, int *,
07978             int *, int *), covsph_(int *, int *, int *,
07979             int *, int *, int *);
07980     extern int lstptr_(int *, int *, int *, int *);
07981     extern long int swptst_(int *, int *, int *, int *,
07982             double *, double *, double *);
07983 
07984 
07985 /* *********************************************************** */
07986 
07987 /*                                              From STRIPACK */
07988 /*                                            Robert J. Renka */
07989 /*                                  Dept. of Computer Science */
07990 /*                                       Univ. of North Texas */
07991 /*                                           renka@cs.unt.edu */
07992 /*                                                   01/08/03 */
07993 
07994 /*   This subroutine adds node K to a triangulation of the */
07995 /* convex hull of nodes 1,...,K-1, producing a triangulation */
07996 /* of the convex hull of nodes 1,...,K. */
07997 
07998 /*   The algorithm consists of the following steps:  node K */
07999 /* is located relative to the triangulation (TRFIND), its */
08000 /* index is added to the data structure (INTADD or BDYADD), */
08001 /* and a sequence of swaps (SWPTST and SWAP) are applied to */
08002 /* the arcs opposite K so that all arcs incident on node K */
08003 /* and opposite node K are locally optimal (satisfy the cir- */
08004 /* cumcircle test).  Thus, if a Delaunay triangulation is */
08005 /* input, a Delaunay triangulation will result. */
08006 
08007 
08008 /* On input: */
08009 
08010 /*       NST = Index of a node at which TRFIND begins its */
08011 /*             search.  Search time depends on the proximity */
08012 /*             of this node to K.  If NST < 1, the search is */
08013 /*             begun at node K-1. */
08014 
08015 /*       K = Nodal index (index for X, Y, Z, and LEND) of the */
08016 /*           new node to be added.  K .GE. 4. */
08017 
08018 /*       X,Y,Z = Arrays of length .GE. K containing Car- */
08019 /*               tesian coordinates of the nodes. */
08020 /*               (X(I),Y(I),Z(I)) defines node I for */
08021 /*               I = 1,...,K. */
08022 
08023 /* The above parameters are not altered by this routine. */
08024 
08025 /*       LIST,LPTR,LEND,LNEW = Data structure associated with */
08026 /*                             the triangulation of nodes 1 */
08027 /*                             to K-1.  The array lengths are */
08028 /*                             assumed to be large enough to */
08029 /*                             add node K.  Refer to Subrou- */
08030 /*                             tine TRMESH. */
08031 
08032 /* On output: */
08033 
08034 /*       LIST,LPTR,LEND,LNEW = Data structure updated with */
08035 /*                             the addition of node K as the */
08036 /*                             last entry unless IER .NE. 0 */
08037 /*                             and IER .NE. -3, in which case */
08038 /*                             the arrays are not altered. */
08039 
08040 /*       IER = Error indicator: */
08041 /*             IER =  0 if no errors were encountered. */
08042 /*             IER = -1 if K is outside its valid range */
08043 /*                      on input. */
08044 /*             IER = -2 if all nodes (including K) are col- */
08045 /*                      linear (lie on a common geodesic). */
08046 /*             IER =  L if nodes L and K coincide for some */
08047 /*                      L < K.  Refer to TOL below. */
08048 
08049 /* Modules required by ADDNOD:  BDYADD, COVSPH, INSERT, */
08050 /*                                INTADD, JRAND, LSTPTR, */
08051 /*                                STORE, SWAP, SWPTST, */
08052 /*                                TRFIND */
08053 
08054 /* Intrinsic function called by ADDNOD:  ABS */
08055 
08056 /* *********************************************************** */
08057 
08058 
08059 /* Local parameters: */
08060 
08061 /* B1,B2,B3 = Unnormalized barycentric coordinates returned */
08062 /*              by TRFIND. */
08063 /* I1,I2,I3 = Vertex indexes of a triangle containing K */
08064 /* IN1 =      Vertex opposite K:  first neighbor of IO2 */
08065 /*              that precedes IO1.  IN1,IO1,IO2 are in */
08066 /*              counterclockwise order. */
08067 /* IO1,IO2 =  Adjacent neighbors of K defining an arc to */
08068 /*              be tested for a swap */
08069 /* IST =      Index of node at which TRFIND begins its search */
08070 /* KK =       Local copy of K */
08071 /* KM1 =      K-1 */
08072 /* L =        Vertex index (I1, I2, or I3) returned in IER */
08073 /*              if node K coincides with a vertex */
08074 /* LP =       LIST pointer */
08075 /* LPF =      LIST pointer to the first neighbor of K */
08076 /* LPO1 =     LIST pointer to IO1 */
08077 /* LPO1S =    Saved value of LPO1 */
08078 /* P =        Cartesian coordinates of node K */
08079 /* TOL =      Tolerance defining coincident nodes:  bound on */
08080 /*              the deviation from 1 of the cosine of the */
08081 /*              angle between the nodes. */
08082 /*              Note that |1-cos(A)| is approximately A*A/2. */
08083 
08084     /* Parameter adjustments */
08085     --lend;
08086     --z__;
08087     --y;
08088     --x;
08089     --list;
08090     --lptr;
08091 
08092     /* Function Body */
08093 
08094     kk = *k;
08095     if (kk < 4) {
08096         goto L3;
08097     }
08098 
08099 /* Initialization: */
08100     km1 = kk - 1;
08101     ist = *nst;
08102     if (ist < 1) {
08103         ist = km1;
08104     }
08105     p[0] = x[kk];
08106     p[1] = y[kk];
08107     p[2] = z__[kk];
08108 
08109 /* Find a triangle (I1,I2,I3) containing K or the rightmost */
08110 /*   (I1) and leftmost (I2) visible boundary nodes as viewed */
08111 /*   from node K. */
08112     trfind_(&ist, p, &km1, &x[1], &y[1], &z__[1], &list[1], &lptr[1], &lend[1]
08113             , &b1, &b2, &b3, &i1, &i2, &i3);
08114 
08115 /*   Test for collinear or (nearly) duplicate nodes. */
08116 
08117     if (i1 == 0) {
08118         goto L4;
08119     }
08120     l = i1;
08121     if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) {
08122         goto L5;
08123     }
08124     l = i2;
08125     if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) {
08126         goto L5;
08127     }
08128     if (i3 != 0) {
08129         l = i3;
08130         if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) {
08131             goto L5;
08132         }
08133         intadd_(&kk, &i1, &i2, &i3, &list[1], &lptr[1], &lend[1], lnew);
08134     } else {
08135         if (i1 != i2) {
08136             bdyadd_(&kk, &i1, &i2, &list[1], &lptr[1], &lend[1], lnew);
08137         } else {
08138             covsph_(&kk, &i1, &list[1], &lptr[1], &lend[1], lnew);
08139         }
08140     }
08141     *ier = 0;
08142 
08143 /* Initialize variables for optimization of the */
08144 /*   triangulation. */
08145     lp = lend[kk];
08146     lpf = lptr[lp];
08147     io2 = list[lpf];
08148     lpo1 = lptr[lpf];
08149     io1 = (i__1 = list[lpo1], abs(i__1));
08150 
08151 /* Begin loop:  find the node opposite K. */
08152 
08153 L1:
08154     lp = lstptr_(&lend[io1], &io2, &list[1], &lptr[1]);
08155     if (list[lp] < 0) {
08156         goto L2;
08157     }
08158     lp = lptr[lp];
08159     in1 = (i__1 = list[lp], abs(i__1));
08160 
08161 /* Swap test:  if a swap occurs, two new arcs are */
08162 /*             opposite K and must be tested. */
08163 
08164     lpo1s = lpo1;
08165     if (! swptst_(&in1, &kk, &io1, &io2, &x[1], &y[1], &z__[1])) {
08166         goto L2;
08167     }
08168     swap_(&in1, &kk, &io1, &io2, &list[1], &lptr[1], &lend[1], &lpo1);
08169     if (lpo1 == 0) {
08170 
08171 /*   A swap is not possible because KK and IN1 are already */
08172 /*     adjacent.  This error in SWPTST only occurs in the */
08173 /*     neutral case and when there are nearly duplicate */
08174 /*     nodes. */
08175 
08176         lpo1 = lpo1s;
08177         goto L2;
08178     }
08179     io1 = in1;
08180     goto L1;
08181 
08182 /* No swap occurred.  Test for termination and reset */
08183 /*   IO2 and IO1. */
08184 
08185 L2:
08186     if (lpo1 == lpf || list[lpo1] < 0) {
08187         return 0;
08188     }
08189     io2 = io1;
08190     lpo1 = lptr[lpo1];
08191     io1 = (i__1 = list[lpo1], abs(i__1));
08192     goto L1;
08193 
08194 /* KK < 4. */
08195 
08196 L3:
08197     *ier = -1;
08198     return 0;
08199 
08200 /* All nodes are collinear. */
08201 
08202 L4:
08203     *ier = -2;
08204     return 0;
08205 
08206 /* Nodes L and K coincide. */
08207 
08208 L5:
08209     *ier = l;
08210     return 0;
08211 } /* addnod_ */

double angle_ ( double *  v1,
double *  v2,
double *  v3 
)

Definition at line 8213 of file util_sparx.cpp.

References left_(), and sqrt().

Referenced by areav_new__().

08214 {
08215     /* System generated locals */
08216     double ret_val;
08217 
08218     /* Builtin functions */
08219     //double sqrt(double), acos(double);
08220 
08221     /* Local variables */
08222     static double a;
08223     static int i__;
08224     static double ca, s21, s23, u21[3], u23[3];
08225     extern long int left_(double *, double *, double *, double
08226             *, double *, double *, double *, double *,
08227             double *);
08228 
08229 
08230 /* *********************************************************** */
08231 
08232 /*                                              From STRIPACK */
08233 /*                                            Robert J. Renka */
08234 /*                                  Dept. of Computer Science */
08235 /*                                       Univ. of North Texas */
08236 /*                                           renka@cs.unt.edu */
08237 /*                                                   06/03/03 */
08238 
08239 /*   Given a sequence of three nodes (V1,V2,V3) on the sur- */
08240 /* face of the unit sphere, this function returns the */
08241 /* interior angle at V2 -- the dihedral angle between the */
08242 /* plane defined by V2 and V3 (and the origin) and the plane */
08243 /* defined by V2 and V1 or, equivalently, the angle between */
08244 /* the normals V2 X V3 and V2 X V1.  Note that the angle is */
08245 /* in the range 0 to Pi if V3 Left V1->V2, Pi to 2*Pi other- */
08246 /* wise.  The surface area of a spherical polygon with CCW- */
08247 /* ordered vertices V1, V2, ..., Vm is Asum - (m-2)*Pi, where */
08248 /* Asum is the sum of the m interior angles computed from the */
08249 /* sequences (Vm,V1,V2), (V1,V2,V3), (V2,V3,V4), ..., */
08250 /* (Vm-1,Vm,V1). */
08251 
08252 
08253 /* On input: */
08254 
08255 /*       V1,V2,V3 = Arrays of length 3 containing the Carte- */
08256 /*                  sian coordinates of unit vectors.  These */
08257 /*                  vectors, if nonzero, are implicitly */
08258 /*                  scaled to have length 1. */
08259 
08260 /* Input parameters are not altered by this function. */
08261 
08262 /* On output: */
08263 
08264 /*       ANGLE = Angle defined above, or 0 if V2 X V1 = 0 or */
08265 /*               V2 X V3 = 0. */
08266 
08267 /* Module required by ANGLE:  LEFT */
08268 
08269 /* Intrinsic functions called by ANGLE:  ACOS, SQRT */
08270 
08271 /* *********************************************************** */
08272 
08273 
08274 /* Local parameters: */
08275 
08276 /* A =       Interior angle at V2 */
08277 /* CA =      cos(A) */
08278 /* I =       DO-loop index and index for U21 and U23 */
08279 /* S21,S23 = Sum of squared components of U21 and U23 */
08280 /* U21,U23 = Unit normal vectors to the planes defined by */
08281 /*             pairs of triangle vertices */
08282 
08283 
08284 /* Compute cross products U21 = V2 X V1 and U23 = V2 X V3. */
08285 
08286     /* Parameter adjustments */
08287     --v3;
08288     --v2;
08289     --v1;
08290 
08291     /* Function Body */
08292     u21[0] = v2[2] * v1[3] - v2[3] * v1[2];
08293     u21[1] = v2[3] * v1[1] - v2[1] * v1[3];
08294     u21[2] = v2[1] * v1[2] - v2[2] * v1[1];
08295 
08296     u23[0] = v2[2] * v3[3] - v2[3] * v3[2];
08297     u23[1] = v2[3] * v3[1] - v2[1] * v3[3];
08298     u23[2] = v2[1] * v3[2] - v2[2] * v3[1];
08299 
08300 /* Normalize U21 and U23 to unit vectors. */
08301 
08302     s21 = 0.;
08303     s23 = 0.;
08304     for (i__ = 1; i__ <= 3; ++i__) {
08305         s21 += u21[i__ - 1] * u21[i__ - 1];
08306         s23 += u23[i__ - 1] * u23[i__ - 1];
08307 /* L1: */
08308     }
08309 
08310 /* Test for a degenerate triangle associated with collinear */
08311 /*   vertices. */
08312 
08313     if (s21 == 0. || s23 == 0.) {
08314         ret_val = 0.;
08315         return ret_val;
08316     }
08317     s21 = sqrt(s21);
08318     s23 = sqrt(s23);
08319     for (i__ = 1; i__ <= 3; ++i__) {
08320         u21[i__ - 1] /= s21;
08321         u23[i__ - 1] /= s23;
08322 /* L2: */
08323     }
08324 
08325 /* Compute the angle A between normals: */
08326 
08327 /*   CA = cos(A) = <U21,U23> */
08328 
08329     ca = u21[0] * u23[0] + u21[1] * u23[1] + u21[2] * u23[2];
08330     if (ca < -1.) {
08331         ca = -1.;
08332     }
08333     if (ca > 1.) {
08334         ca = 1.;
08335     }
08336     a = acos(ca);
08337 
08338 /* Adjust A to the interior angle:  A > Pi iff */
08339 /*   V3 Right V1->V2. */
08340 
08341     if (! left_(&v1[1], &v1[2], &v1[3], &v2[1], &v2[2], &v2[3], &v3[1], &v3[2]
08342             , &v3[3])) {
08343         a = acos(-1.) * 2. - a;
08344     }
08345     ret_val = a;
08346     return ret_val;
08347 } /* angle_ */

double areas_ ( double *  v1,
double *  v2,
double *  v3 
)

Definition at line 8349 of file util_sparx.cpp.

References sqrt().

Referenced by EMAN::Util::areav_().

08350 {
08351     /* System generated locals */
08352     double ret_val;
08353 
08354     /* Builtin functions */
08355     //double sqrt(double), acos(double);
08356 
08357     /* Local variables */
08358     static int i__;
08359     static double a1, a2, a3, s12, s31, s23, u12[3], u23[3], u31[3], ca1,
08360             ca2, ca3;
08361 
08362 
08363 /* *********************************************************** */
08364 
08365 /*                                              From STRIPACK */
08366 /*                                            Robert J. Renka */
08367 /*                                  Dept. of Computer Science */
08368 /*                                       Univ. of North Texas */
08369 /*                                           renka@cs.unt.edu */
08370 /*                                                   06/22/98 */
08371 
08372 /*   This function returns the area of a spherical triangle */
08373 /* on the unit sphere. */
08374 
08375 
08376 /* On input: */
08377 
08378 /*       V1,V2,V3 = Arrays of length 3 containing the Carte- */
08379 /*                  sian coordinates of unit vectors (the */
08380 /*                  three triangle vertices in any order). */
08381 /*                  These vectors, if nonzero, are implicitly */
08382 /*                  scaled to have length 1. */
08383 
08384 /* Input parameters are not altered by this function. */
08385 
08386 /* On output: */
08387 
08388 /*       AREAS = Area of the spherical triangle defined by */
08389 /*               V1, V2, and V3 in the range 0 to 2*PI (the */
08390 /*               area of a hemisphere).  AREAS = 0 (or 2*PI) */
08391 /*               if and only if V1, V2, and V3 lie in (or */
08392 /*               close to) a plane containing the origin. */
08393 
08394 /* Modules required by AREAS:  None */
08395 
08396 /* Intrinsic functions called by AREAS:  ACOS, SQRT */
08397 
08398 /* *********************************************************** */
08399 
08400 
08401 /* Local parameters: */
08402 
08403 /* A1,A2,A3 =    Interior angles of the spherical triangle */
08404 /* CA1,CA2,CA3 = cos(A1), cos(A2), and cos(A3), respectively */
08405 /* I =           DO-loop index and index for Uij */
08406 /* S12,S23,S31 = Sum of squared components of U12, U23, U31 */
08407 /* U12,U23,U31 = Unit normal vectors to the planes defined by */
08408 /*                 pairs of triangle vertices */
08409 
08410 
08411 /* Compute cross products Uij = Vi X Vj. */
08412 
08413     /* Parameter adjustments */
08414     --v3;
08415     --v2;
08416     --v1;
08417 
08418     /* Function Body */
08419     u12[0] = v1[2] * v2[3] - v1[3] * v2[2];
08420     u12[1] = v1[3] * v2[1] - v1[1] * v2[3];
08421     u12[2] = v1[1] * v2[2] - v1[2] * v2[1];
08422 
08423     u23[0] = v2[2] * v3[3] - v2[3] * v3[2];
08424     u23[1] = v2[3] * v3[1] - v2[1] * v3[3];
08425     u23[2] = v2[1] * v3[2] - v2[2] * v3[1];
08426 
08427     u31[0] = v3[2] * v1[3] - v3[3] * v1[2];
08428     u31[1] = v3[3] * v1[1] - v3[1] * v1[3];
08429     u31[2] = v3[1] * v1[2] - v3[2] * v1[1];
08430 
08431 /* Normalize Uij to unit vectors. */
08432 
08433     s12 = 0.;
08434     s23 = 0.;
08435     s31 = 0.;
08436     for (i__ = 1; i__ <= 3; ++i__) {
08437         s12 += u12[i__ - 1] * u12[i__ - 1];
08438         s23 += u23[i__ - 1] * u23[i__ - 1];
08439         s31 += u31[i__ - 1] * u31[i__ - 1];
08440 /* L2: */
08441     }
08442 
08443 /* Test for a degenerate triangle associated with collinear */
08444 /*   vertices. */
08445 
08446     if (s12 == 0. || s23 == 0. || s31 == 0.) {
08447         ret_val = 0.;
08448         return ret_val;
08449     }
08450     s12 = sqrt(s12);
08451     s23 = sqrt(s23);
08452     s31 = sqrt(s31);
08453     for (i__ = 1; i__ <= 3; ++i__) {
08454         u12[i__ - 1] /= s12;
08455         u23[i__ - 1] /= s23;
08456         u31[i__ - 1] /= s31;
08457 /* L3: */
08458     }
08459 
08460 /* Compute interior angles Ai as the dihedral angles between */
08461 /*   planes: */
08462 /*           CA1 = cos(A1) = -<U12,U31> */
08463 /*           CA2 = cos(A2) = -<U23,U12> */
08464 /*           CA3 = cos(A3) = -<U31,U23> */
08465 
08466     ca1 = -u12[0] * u31[0] - u12[1] * u31[1] - u12[2] * u31[2];
08467     ca2 = -u23[0] * u12[0] - u23[1] * u12[1] - u23[2] * u12[2];
08468     ca3 = -u31[0] * u23[0] - u31[1] * u23[1] - u31[2] * u23[2];
08469     if (ca1 < -1.) {
08470         ca1 = -1.;
08471     }
08472     if (ca1 > 1.) {
08473         ca1 = 1.;
08474     }
08475     if (ca2 < -1.) {
08476         ca2 = -1.;
08477     }
08478     if (ca2 > 1.) {
08479         ca2 = 1.;
08480     }
08481     if (ca3 < -1.) {
08482         ca3 = -1.;
08483     }
08484     if (ca3 > 1.) {
08485         ca3 = 1.;
08486     }
08487     a1 = acos(ca1);
08488     a2 = acos(ca2);
08489     a3 = acos(ca3);
08490 
08491 /* Compute AREAS = A1 + A2 + A3 - PI. */
08492 
08493     ret_val = a1 + a2 + a3 - acos(-1.);
08494     if (ret_val < 0.) {
08495         ret_val = 0.;
08496     }
08497     return ret_val;
08498 } /* areas_ */

double areav_new__ ( int *  k,
int *  n,
double *  x,
double *  y,
double *  z__,
int *  list,
int *  lptr,
int *  lend,
int *  ier 
)

Definition at line 8704 of file util_sparx.cpp.

References angle_(), circum_(), and ierr.

08707 {
08708     /* System generated locals */
08709     double ret_val = 0;
08710 
08711     /* Builtin functions */
08712     //double acos(double);
08713 
08714     /* Local variables */
08715     static int m;
08716     static double c1[3], c2[3], c3[3];
08717     static int n1, n2, n3;
08718     static double v1[3], v2[3], v3[3];
08719     static int lp;
08720     static double c1s[3], c2s[3];
08721     static int lpl, ierr;
08722     static double asum;
08723     extern double angle_(double *, double *, double *);
08724     static float areav;
08725     extern /* Subroutine */ int circum_(double *, double *,
08726             double *, double *, int *);
08727 
08728 
08729 /* *********************************************************** */
08730 
08731 /*                                            Robert J. Renka */
08732 /*                                  Dept. of Computer Science */
08733 /*                                       Univ. of North Texas */
08734 /*                                           renka@cs.unt.edu */
08735 /*                                                   06/03/03 */
08736 
08737 /*   Given a Delaunay triangulation and the index K of an */
08738 /* interior node, this subroutine returns the (surface) area */
08739 /* of the Voronoi region associated with node K.  The Voronoi */
08740 /* region is the polygon whose vertices are the circumcenters */
08741 /* of the triangles that contain node K, where a triangle */
08742 /* circumcenter is the point (unit vector) lying at the same */
08743 /* angular distance from the three vertices and contained in */
08744 /* the same hemisphere as the vertices.  The Voronoi region */
08745 /* area is computed as Asum-(m-2)*Pi, where m is the number */
08746 /* of Voronoi vertices (neighbors of K) and Asum is the sum */
08747 /* of interior angles at the vertices. */
08748 
08749 
08750 /* On input: */
08751 
08752 /*       K = Nodal index in the range 1 to N. */
08753 
08754 /*       N = Number of nodes in the triangulation.  N > 3. */
08755 
08756 /*       X,Y,Z = Arrays of length N containing the Cartesian */
08757 /*               coordinates of the nodes (unit vectors). */
08758 
08759 /*       LIST,LPTR,LEND = Data structure defining the trian- */
08760 /*                        gulation.  Refer to Subroutine */
08761 /*                        TRMESH. */
08762 
08763 /* Input parameters are not altered by this function. */
08764 
08765 /* On output: */
08766 
08767 /*       AREAV = Area of Voronoi region K unless IER > 0, */
08768 /*               in which case AREAV = 0. */
08769 
08770 /*       IER = Error indicator: */
08771 /*             IER = 0 if no errors were encountered. */
08772 /*             IER = 1 if K or N is outside its valid range */
08773 /*                     on input. */
08774 /*             IER = 2 if K indexes a boundary node. */
08775 /*             IER = 3 if an error flag is returned by CIRCUM */
08776 /*                     (null triangle). */
08777 
08778 /* Modules required by AREAV:  ANGLE, CIRCUM */
08779 
08780 /* Intrinsic functions called by AREAV:  ACOS, DBLE */
08781 
08782 /* *********************************************************** */
08783 
08784 
08785 /* Test for invalid input. */
08786 
08787     /* Parameter adjustments */
08788     --lend;
08789     --z__;
08790     --y;
08791     --x;
08792     --list;
08793     --lptr;
08794 
08795     /* Function Body */
08796     if (*k < 1 || *k > *n || *n <= 3) {
08797         goto L11;
08798     }
08799 
08800 /* Initialization:  Set N3 to the last neighbor of N1 = K. */
08801 /*   The number of neighbors and the sum of interior angles */
08802 /*   are accumulated in M and ASUM, respectively. */
08803 
08804     n1 = *k;
08805     v1[0] = x[n1];
08806     v1[1] = y[n1];
08807     v1[2] = z__[n1];
08808     lpl = lend[n1];
08809     n3 = list[lpl];
08810     if (n3 < 0) {
08811         goto L12;
08812     }
08813     lp = lpl;
08814     m = 0;
08815     asum = 0.;
08816 
08817 /* Loop on triangles (N1,N2,N3) containing N1 = K. */
08818 
08819 L1:
08820     ++m;
08821     n2 = n3;
08822     lp = lptr[lp];
08823     n3 = list[lp];
08824     v2[0] = x[n2];
08825     v2[1] = y[n2];
08826     v2[2] = z__[n2];
08827     v3[0] = x[n3];
08828     v3[1] = y[n3];
08829     v3[2] = z__[n3];
08830     if (m == 1) {
08831 
08832 /* First triangle:  compute the circumcenter C2 and save a */
08833 /*   copy in C1S. */
08834 
08835         circum_(v1, v2, v3, c2, &ierr);
08836         if (ierr != 0) {
08837             goto L13;
08838         }
08839         c1s[0] = c2[0];
08840         c1s[1] = c2[1];
08841         c1s[2] = c2[2];
08842     } else if (m == 2) {
08843 
08844 /* Second triangle:  compute the circumcenter C3 and save a */
08845 /*   copy in C2S. */
08846 
08847         circum_(v1, v2, v3, c3, &ierr);
08848         if (ierr != 0) {
08849             goto L13;
08850         }
08851         c2s[0] = c3[0];
08852         c2s[1] = c3[1];
08853         c2s[2] = c3[2];
08854     } else {
08855 
08856 /* Set C1 to C2, set C2 to C3, compute the new circumcenter */
08857 /*   C3, and compute the interior angle at C2 from the */
08858 /*   sequence of vertices (C1,C2,C3). */
08859 
08860         c1[0] = c2[0];
08861         c1[1] = c2[1];
08862         c1[2] = c2[2];
08863         c2[0] = c3[0];
08864         c2[1] = c3[1];
08865         c2[2] = c3[2];
08866         circum_(v1, v2, v3, c3, &ierr);
08867         if (ierr != 0) {
08868             goto L13;
08869         }
08870         asum += angle_(c1, c2, c3);
08871     }
08872 
08873 /* Bottom on loop on neighbors of K. */
08874 
08875     if (lp != lpl) {
08876         goto L1;
08877     }
08878 
08879 /* C3 is the last vertex.  Compute its interior angle from */
08880 /*   the sequence (C2,C3,C1S). */
08881 
08882     asum += angle_(c2, c3, c1s);
08883 
08884 /* Compute the interior angle at C1S from */
08885 /*   the sequence (C3,C1S,C2S). */
08886 
08887     asum += angle_(c3, c1s, c2s);
08888 
08889 /* No error encountered. */
08890 
08891     *ier = 0;
08892     ret_val = asum - (double) (m - 2) * acos(-1.);
08893     return ret_val;
08894 
08895 /* Invalid input. */
08896 
08897 L11:
08898     *ier = 1;
08899     areav = 0.f;
08900     return ret_val;
08901 
08902 /* K indexes a boundary node. */
08903 
08904 L12:
08905     *ier = 2;
08906     areav = 0.f;
08907     return ret_val;
08908 
08909 /* Error in CIRCUM. */
08910 
08911 L13:
08912     *ier = 3;
08913     areav = 0.f;
08914     return ret_val;
08915 } /* areav_new__ */

int bdyadd_ ( int *  kk,
int *  i1,
int *  i2,
int *  list,
int *  lptr,
int *  lend,
int *  lnew 
)

Definition at line 8917 of file util_sparx.cpp.

References insert_().

Referenced by addnod_().

08919 {
08920     static int k, n1, n2, lp, lsav, nsav, next;
08921     extern /* Subroutine */ int insert_(int *, int *, int *,
08922             int *, int *);
08923 
08924 
08925 /* *********************************************************** */
08926 
08927 /*                                              From STRIPACK */
08928 /*                                            Robert J. Renka */
08929 /*                                  Dept. of Computer Science */
08930 /*                                       Univ. of North Texas */
08931 /*                                           renka@cs.unt.edu */
08932 /*                                                   07/11/96 */
08933 
08934 /*   This subroutine adds a boundary node to a triangulation */
08935 /* of a set of KK-1 points on the unit sphere.  The data */
08936 /* structure is updated with the insertion of node KK, but no */
08937 /* optimization is performed. */
08938 
08939 /*   This routine is identical to the similarly named routine */
08940 /* in TRIPACK. */
08941 
08942 
08943 /* On input: */
08944 
08945 /*       KK = Index of a node to be connected to the sequence */
08946 /*            of all visible boundary nodes.  KK .GE. 1 and */
08947 /*            KK must not be equal to I1 or I2. */
08948 
08949 /*       I1 = First (rightmost as viewed from KK) boundary */
08950 /*            node in the triangulation that is visible from */
08951 /*            node KK (the line segment KK-I1 intersects no */
08952 /*            arcs. */
08953 
08954 /*       I2 = Last (leftmost) boundary node that is visible */
08955 /*            from node KK.  I1 and I2 may be determined by */
08956 /*            Subroutine TRFIND. */
08957 
08958 /* The above parameters are not altered by this routine. */
08959 
08960 /*       LIST,LPTR,LEND,LNEW = Triangulation data structure */
08961 /*                             created by Subroutine TRMESH. */
08962 /*                             Nodes I1 and I2 must be in- */
08963 /*                             cluded in the triangulation. */
08964 
08965 /* On output: */
08966 
08967 /*       LIST,LPTR,LEND,LNEW = Data structure updated with */
08968 /*                             the addition of node KK.  Node */
08969 /*                             KK is connected to I1, I2, and */
08970 /*                             all boundary nodes in between. */
08971 
08972 /* Module required by BDYADD:  INSERT */
08973 
08974 /* *********************************************************** */
08975 
08976 
08977 /* Local parameters: */
08978 
08979 /* K =     Local copy of KK */
08980 /* LP =    LIST pointer */
08981 /* LSAV =  LIST pointer */
08982 /* N1,N2 = Local copies of I1 and I2, respectively */
08983 /* NEXT =  Boundary node visible from K */
08984 /* NSAV =  Boundary node visible from K */
08985 
08986     /* Parameter adjustments */
08987     --lend;
08988     --lptr;
08989     --list;
08990 
08991     /* Function Body */
08992     k = *kk;
08993     n1 = *i1;
08994     n2 = *i2;
08995 
08996 /* Add K as the last neighbor of N1. */
08997 
08998     lp = lend[n1];
08999     lsav = lptr[lp];
09000     lptr[lp] = *lnew;
09001     list[*lnew] = -k;
09002     lptr[*lnew] = lsav;
09003     lend[n1] = *lnew;
09004     ++(*lnew);
09005     next = -list[lp];
09006     list[lp] = next;
09007     nsav = next;
09008 
09009 /* Loop on the remaining boundary nodes between N1 and N2, */
09010 /*   adding K as the first neighbor. */
09011 
09012 L1:
09013     lp = lend[next];
09014     insert_(&k, &lp, &list[1], &lptr[1], lnew);
09015     if (next == n2) {
09016         goto L2;
09017     }
09018     next = -list[lp];
09019     list[lp] = next;
09020     goto L1;
09021 
09022 /* Add the boundary nodes between N1 and N2 as neighbors */
09023 /*   of node K. */
09024 
09025 L2:
09026     lsav = *lnew;
09027     list[*lnew] = n1;
09028     lptr[*lnew] = *lnew + 1;
09029     ++(*lnew);
09030     next = nsav;
09031 
09032 L3:
09033     if (next == n2) {
09034         goto L4;
09035     }
09036     list[*lnew] = next;
09037     lptr[*lnew] = *lnew + 1;
09038     ++(*lnew);
09039     lp = lend[next];
09040     next = list[lp];
09041     goto L3;
09042 
09043 L4:
09044     list[*lnew] = -n2;
09045     lptr[*lnew] = lsav;
09046     lend[k] = *lnew;
09047     ++(*lnew);
09048     return 0;
09049 } /* bdyadd_ */

int bnodes_ ( int *  n,
int *  list,
int *  lptr,
int *  lend,
int *  nodes,
int *  nb,
int *  na,
int *  nt 
)

Definition at line 9051 of file util_sparx.cpp.

References nn().

09053 {
09054     /* System generated locals */
09055     int i__1;
09056 
09057     /* Local variables */
09058     static int k, n0, lp, nn, nst;
09059 
09060 
09061 /* *********************************************************** */
09062 
09063 /*                                              From STRIPACK */
09064 /*                                            Robert J. Renka */
09065 /*                                  Dept. of Computer Science */
09066 /*                                       Univ. of North Texas */
09067 /*                                           renka@cs.unt.edu */
09068 /*                                                   06/26/96 */
09069 
09070 /*   Given a triangulation of N nodes on the unit sphere */
09071 /* created by Subroutine TRMESH, this subroutine returns an */
09072 /* array containing the indexes (if any) of the counterclock- */
09073 /* wise-ordered sequence of boundary nodes -- the nodes on */
09074 /* the boundary of the convex hull of the set of nodes.  (The */
09075 /* boundary is empty if the nodes do not lie in a single */
09076 /* hemisphere.)  The numbers of boundary nodes, arcs, and */
09077 /* triangles are also returned. */
09078 
09079 
09080 /* On input: */
09081 
09082 /*       N = Number of nodes in the triangulation.  N .GE. 3. */
09083 
09084 /*       LIST,LPTR,LEND = Data structure defining the trian- */
09085 /*                        gulation.  Refer to Subroutine */
09086 /*                        TRMESH. */
09087 
09088 /* The above parameters are not altered by this routine. */
09089 
09090 /*       NODES = int array of length at least NB */
09091 /*               (NB .LE. N). */
09092 
09093 /* On output: */
09094 
09095 /*       NODES = Ordered sequence of boundary node indexes */
09096 /*               in the range 1 to N (in the first NB loca- */
09097 /*               tions). */
09098 
09099 /*       NB = Number of boundary nodes. */
09100 
09101 /*       NA,NT = Number of arcs and triangles, respectively, */
09102 /*               in the triangulation. */
09103 
09104 /* Modules required by BNODES:  None */
09105 
09106 /* *********************************************************** */
09107 
09108 
09109 /* Local parameters: */
09110 
09111 /* K =   NODES index */
09112 /* LP =  LIST pointer */
09113 /* N0 =  Boundary node to be added to NODES */
09114 /* NN =  Local copy of N */
09115 /* NST = First element of nodes (arbitrarily chosen to be */
09116 /*         the one with smallest index) */
09117 
09118     /* Parameter adjustments */
09119     --lend;
09120     --list;
09121     --lptr;
09122     --nodes;
09123 
09124     /* Function Body */
09125     nn = *n;
09126 
09127 /* Search for a boundary node. */
09128 
09129     i__1 = nn;
09130     for (nst = 1; nst <= i__1; ++nst) {
09131         lp = lend[nst];
09132         if (list[lp] < 0) {
09133             goto L2;
09134         }
09135 /* L1: */
09136     }
09137 
09138 /* The triangulation contains no boundary nodes. */
09139 
09140     *nb = 0;
09141     *na = (nn - 2) * 3;
09142     *nt = nn - (2<<1);
09143     return 0;
09144 
09145 /* NST is the first boundary node encountered.  Initialize */
09146 /*   for traversal of the boundary. */
09147 
09148 L2:
09149     nodes[1] = nst;
09150     k = 1;
09151     n0 = nst;
09152 
09153 /* Traverse the boundary in counterclockwise order. */
09154 
09155 L3:
09156     lp = lend[n0];
09157     lp = lptr[lp];
09158     n0 = list[lp];
09159     if (n0 == nst) {
09160         goto L4;
09161     }
09162     ++k;
09163     nodes[k] = n0;
09164     goto L3;
09165 
09166 /* Store the counts. */
09167 
09168 L4:
09169     *nb = k;
09170     *nt = (*n << 1) - *nb - 2;
09171     *na = *nt + *n - 1;
09172     return 0;
09173 } /* bnodes_ */

int circle_ ( int *  k,
double *  xc,
double *  yc,
int *  ier 
)

Definition at line 9175 of file util_sparx.cpp.

09177 {
09178     /* System generated locals */
09179     int i__1;
09180 
09181     /* Builtin functions */
09182     //double atan(double), cos(double), sin(double);
09183 
09184     /* Local variables */
09185     static double a, c__;
09186     static int i__;
09187     static double s;
09188     static int k2, k3;
09189     static double x0, y0;
09190     static int kk, np1;
09191 
09192 
09193 /* *********************************************************** */
09194 
09195 /*                                              From STRIPACK */
09196 /*                                            Robert J. Renka */
09197 /*                                  Dept. of Computer Science */
09198 /*                                       Univ. of North Texas */
09199 /*                                           renka@cs.unt.edu */
09200 /*                                                   04/06/90 */
09201 
09202 /*   This subroutine computes the coordinates of a sequence */
09203 /* of N equally spaced points on the unit circle centered at */
09204 /* (0,0).  An N-sided polygonal approximation to the circle */
09205 /* may be plotted by connecting (XC(I),YC(I)) to (XC(I+1), */
09206 /* YC(I+1)) for I = 1,...,N, where XC(N+1) = XC(1) and */
09207 /* YC(N+1) = YC(1).  A reasonable value for N in this case */
09208 /* is 2*PI*R, where R is the radius of the circle in device */
09209 /* coordinates. */
09210 
09211 
09212 /* On input: */
09213 
09214 /*       K = Number of points in each quadrant, defining N as */
09215 /*           4K.  K .GE. 1. */
09216 
09217 /*       XC,YC = Arrays of length at least N+1 = 4K+1. */
09218 
09219 /* K is not altered by this routine. */
09220 
09221 /* On output: */
09222 
09223 /*       XC,YC = Cartesian coordinates of the points on the */
09224 /*               unit circle in the first N+1 locations. */
09225 /*               XC(I) = cos(A*(I-1)), YC(I) = sin(A*(I-1)), */
09226 /*               where A = 2*PI/N.  Note that XC(N+1) = XC(1) */
09227 /*               and YC(N+1) = YC(1). */
09228 
09229 /*       IER = Error indicator: */
09230 /*             IER = 0 if no errors were encountered. */
09231 /*             IER = 1 if K < 1 on input. */
09232 
09233 /* Modules required by CIRCLE:  None */
09234 
09235 /* Intrinsic functions called by CIRCLE:  ATAN, COS, DBLE, */
09236 /*                                          SIN */
09237 
09238 /* *********************************************************** */
09239 
09240 
09241 /* Local parameters: */
09242 
09243 /* I =     DO-loop index and index for XC and YC */
09244 /* KK =    Local copy of K */
09245 /* K2 =    K*2 */
09246 /* K3 =    K*3 */
09247 /* NP1 =   N+1 = 4*K + 1 */
09248 /* A =     Angular separation between adjacent points */
09249 /* C,S =   Cos(A) and sin(A), respectively, defining a */
09250 /*           rotation through angle A */
09251 /* X0,Y0 = Cartesian coordinates of a point on the unit */
09252 /*           circle in the first quadrant */
09253 
09254     /* Parameter adjustments */
09255     --yc;
09256     --xc;
09257 
09258     /* Function Body */
09259     kk = *k;
09260     k2 = kk << 1;
09261     k3 = kk * 3;
09262     np1 = (kk << 2) + 1;
09263 
09264 /* Test for invalid input, compute A, C, and S, and */
09265 /*   initialize (X0,Y0) to (1,0). */
09266 
09267     if (kk < 1) {
09268         goto L2;
09269     }
09270     a = atan(1.) * 2. / (double) kk;
09271     c__ = cos(a);
09272     s = sin(a);
09273     x0 = 1.;
09274     y0 = 0.;
09275 
09276 /* Loop on points (X0,Y0) in the first quadrant, storing */
09277 /*   the point and its reflections about the x axis, the */
09278 /*   y axis, and the line y = -x. */
09279 
09280     i__1 = kk;
09281     for (i__ = 1; i__ <= i__1; ++i__) {
09282         xc[i__] = x0;
09283         yc[i__] = y0;
09284         xc[i__ + kk] = -y0;
09285         yc[i__ + kk] = x0;
09286         xc[i__ + k2] = -x0;
09287         yc[i__ + k2] = -y0;
09288         xc[i__ + k3] = y0;
09289         yc[i__ + k3] = -x0;
09290 
09291 /*   Rotate (X0,Y0) counterclockwise through angle A. */
09292 
09293         x0 = c__ * x0 - s * y0;
09294         y0 = s * x0 + c__ * y0;
09295 /* L1: */
09296     }
09297 
09298 /* Store the coordinates of the first point as the last */
09299 /*   point. */
09300 
09301     xc[np1] = xc[1];
09302     yc[np1] = yc[1];
09303     *ier = 0;
09304     return 0;
09305 
09306 /* K < 1. */
09307 
09308 L2:
09309     *ier = 1;
09310     return 0;
09311 } /* circle_ */

int circum_ ( double *  v1,
double *  v2,
double *  v3,
double *  c__,
int *  ier 
)

Definition at line 9313 of file util_sparx.cpp.

References sqrt().

Referenced by EMAN::Util::areav_(), areav_new__(), and crlist_().

09315 {
09316     /* Builtin functions */
09317     //double sqrt(double);
09318 
09319     /* Local variables */
09320     static int i__;
09321     static double e1[3], e2[3], cu[3], cnorm;
09322 
09323 
09324 /* *********************************************************** */
09325 
09326 /*                                              From STRIPACK */
09327 /*                                            Robert J. Renka */
09328 /*                                  Dept. of Computer Science */
09329 /*                                       Univ. of North Texas */
09330 /*                                           renka@cs.unt.edu */
09331 /*                                                   10/27/02 */
09332 
09333 /*   This subroutine returns the circumcenter of a spherical */
09334 /* triangle on the unit sphere:  the point on the sphere sur- */
09335 /* face that is equally distant from the three triangle */
09336 /* vertices and lies in the same hemisphere, where distance */
09337 /* is taken to be arc-length on the sphere surface. */
09338 
09339 
09340 /* On input: */
09341 
09342 /*       V1,V2,V3 = Arrays of length 3 containing the Carte- */
09343 /*                  sian coordinates of the three triangle */
09344 /*                  vertices (unit vectors) in CCW order. */
09345 
09346 /* The above parameters are not altered by this routine. */
09347 
09348 /*       C = Array of length 3. */
09349 
09350 /* On output: */
09351 
09352 /*       C = Cartesian coordinates of the circumcenter unless */
09353 /*           IER > 0, in which case C is not defined.  C = */
09354 /*           (V2-V1) X (V3-V1) normalized to a unit vector. */
09355 
09356 /*       IER = Error indicator: */
09357 /*             IER = 0 if no errors were encountered. */
09358 /*             IER = 1 if V1, V2, and V3 lie on a common */
09359 /*                     line:  (V2-V1) X (V3-V1) = 0. */
09360 /*             (The vertices are not tested for validity.) */
09361 
09362 /* Modules required by CIRCUM:  None */
09363 
09364 /* Intrinsic function called by CIRCUM:  SQRT */
09365 
09366 /* *********************************************************** */
09367 
09368 
09369 /* Local parameters: */
09370 
09371 /* CNORM = Norm of CU:  used to compute C */
09372 /* CU =    Scalar multiple of C:  E1 X E2 */
09373 /* E1,E2 = Edges of the underlying planar triangle: */
09374 /*           V2-V1 and V3-V1, respectively */
09375 /* I =     DO-loop index */
09376 
09377     /* Parameter adjustments */
09378     --c__;
09379     --v3;
09380     --v2;
09381     --v1;
09382 
09383     /* Function Body */
09384     for (i__ = 1; i__ <= 3; ++i__) {
09385         e1[i__ - 1] = v2[i__] - v1[i__];
09386         e2[i__ - 1] = v3[i__] - v1[i__];
09387 /* L1: */
09388     }
09389 
09390 /* Compute CU = E1 X E2 and CNORM**2. */
09391 
09392     cu[0] = e1[1] * e2[2] - e1[2] * e2[1];
09393     cu[1] = e1[2] * e2[0] - e1[0] * e2[2];
09394     cu[2] = e1[0] * e2[1] - e1[1] * e2[0];
09395     cnorm = cu[0] * cu[0] + cu[1] * cu[1] + cu[2] * cu[2];
09396 
09397 /* The vertices lie on a common line if and only if CU is */
09398 /*   the zero vector. */
09399 
09400     if (cnorm != 0.) {
09401 
09402 /*   No error:  compute C. */
09403 
09404         cnorm = sqrt(cnorm);
09405         for (i__ = 1; i__ <= 3; ++i__) {
09406             c__[i__] = cu[i__ - 1] / cnorm;
09407 /* L2: */
09408         }
09409 
09410 /* If the vertices are nearly identical, the problem is */
09411 /*   ill-conditioned and it is possible for the computed */
09412 /*   value of C to be 180 degrees off:  <C,V1> near -1 */
09413 /*   when it should be positive. */
09414 
09415         if (c__[1] * v1[1] + c__[2] * v1[2] + c__[3] * v1[3] < -.5) {
09416             c__[1] = -c__[1];
09417             c__[2] = -c__[2];
09418             c__[3] = -c__[3];
09419         }
09420         *ier = 0;
09421     } else {
09422 
09423 /*   CU = 0. */
09424 
09425         *ier = 1;
09426     }
09427     return 0;
09428 } /* circum_ */

int covsph_ ( int *  kk,
int *  n0,
int *  list,
int *  lptr,
int *  lend,
int *  lnew 
)

Definition at line 9430 of file util_sparx.cpp.

References insert_().

Referenced by addnod_().

09432 {
09433     static int k, lp, nst, lsav, next;
09434     extern /* Subroutine */ int insert_(int *, int *, int *,
09435             int *, int *);
09436 
09437 
09438 /* *********************************************************** */
09439 
09440 /*                                              From STRIPACK */
09441 /*                                            Robert J. Renka */
09442 /*                                  Dept. of Computer Science */
09443 /*                                       Univ. of North Texas */
09444 /*                                           renka@cs.unt.edu */
09445 /*                                                   07/17/96 */
09446 
09447 /*   This subroutine connects an exterior node KK to all */
09448 /* boundary nodes of a triangulation of KK-1 points on the */
09449 /* unit sphere, producing a triangulation that covers the */
09450 /* sphere.  The data structure is updated with the addition */
09451 /* of node KK, but no optimization is performed.  All boun- */
09452 /* dary nodes must be visible from node KK. */
09453 
09454 
09455 /* On input: */
09456 
09457 /*       KK = Index of the node to be connected to the set of */
09458 /*            all boundary nodes.  KK .GE. 4. */
09459 
09460 /*       N0 = Index of a boundary node (in the range 1 to */
09461 /*            KK-1).  N0 may be determined by Subroutine */
09462 /*            TRFIND. */
09463 
09464 /* The above parameters are not altered by this routine. */
09465 
09466 /*       LIST,LPTR,LEND,LNEW = Triangulation data structure */
09467 /*                             created by Subroutine TRMESH. */
09468 /*                             Node N0 must be included in */
09469 /*                             the triangulation. */
09470 
09471 /* On output: */
09472 
09473 /*       LIST,LPTR,LEND,LNEW = Data structure updated with */
09474 /*                             the addition of node KK as the */
09475 /*                             last entry.  The updated */
09476 /*                             triangulation contains no */
09477 /*                             boundary nodes. */
09478 
09479 /* Module required by COVSPH:  INSERT */
09480 
09481 /* *********************************************************** */
09482 
09483 
09484 /* Local parameters: */
09485 
09486 /* K =     Local copy of KK */
09487 /* LP =    LIST pointer */
09488 /* LSAV =  LIST pointer */
09489 /* NEXT =  Boundary node visible from K */
09490 /* NST =   Local copy of N0 */
09491 
09492     /* Parameter adjustments */
09493     --lend;
09494     --lptr;
09495     --list;
09496 
09497     /* Function Body */
09498     k = *kk;
09499     nst = *n0;
09500 
09501 /* Traverse the boundary in clockwise order, inserting K as */
09502 /*   the first neighbor of each boundary node, and converting */
09503 /*   the boundary node to an interior node. */
09504 
09505     next = nst;
09506 L1:
09507     lp = lend[next];
09508     insert_(&k, &lp, &list[1], &lptr[1], lnew);
09509     next = -list[lp];
09510     list[lp] = next;
09511     if (next != nst) {
09512         goto L1;
09513     }
09514 
09515 /* Traverse the boundary again, adding each node to K's */
09516 /*   adjacency list. */
09517 
09518     lsav = *lnew;
09519 L2:
09520     lp = lend[next];
09521     list[*lnew] = next;
09522     lptr[*lnew] = *lnew + 1;
09523     ++(*lnew);
09524     next = list[lp];
09525     if (next != nst) {
09526         goto L2;
09527     }
09528 
09529     lptr[*lnew - 1] = lsav;
09530     lend[k] = *lnew - 1;
09531     return 0;
09532 } /* covsph_ */

int crlist_ ( int *  n,
int *  ncol,
double *  x,
double *  y,
double *  z__,
int *  list,
int *  lend,
int *  lptr,
int *  lnew,
int *  ltri,
int *  listc,
int *  nb,
double *  xc,
double *  yc,
double *  zc,
double *  rc,
int *  ier 
)

Definition at line 9534 of file util_sparx.cpp.

References abs, circum_(), FALSE_, ierr, lstptr_(), nn(), swptst_(), t, and TRUE_.

09539 {
09540     /* System generated locals */
09541     int i__1, i__2;
09542 
09543     /* Builtin functions */
09544     //double acos(double);
09545 
09546     /* Local variables */
09547     static double c__[3], t;
09548     static int i1, i2, i3, i4, n0, n1, n2, n3, n4;
09549     static double v1[3], v2[3], v3[3];
09550     static int lp, kt, nn, nt, nm2, kt1, kt2, kt11, kt12, kt21, kt22, lpl,
09551              lpn;
09552     static long int swp;
09553     static int ierr;
09554     extern /* Subroutine */ int circum_(double *, double *,
09555             double *, double *, int *);
09556     extern int lstptr_(int *, int *, int *, int *);
09557     extern long int swptst_(int *, int *, int *, int *,
09558             double *, double *, double *);
09559 
09560 
09561 /* *********************************************************** */
09562 
09563 /*                                              From STRIPACK */
09564 /*                                            Robert J. Renka */
09565 /*                                  Dept. of Computer Science */
09566 /*                                       Univ. of North Texas */
09567 /*                                           renka@cs.unt.edu */
09568 /*                                                   03/05/03 */
09569 
09570 /*   Given a Delaunay triangulation of nodes on the surface */
09571 /* of the unit sphere, this subroutine returns the set of */
09572 /* triangle circumcenters corresponding to Voronoi vertices, */
09573 /* along with the circumradii and a list of triangle indexes */
09574 /* LISTC stored in one-to-one correspondence with LIST/LPTR */
09575 /* entries. */
09576 
09577 /*   A triangle circumcenter is the point (unit vector) lying */
09578 /* at the same angular distance from the three vertices and */
09579 /* contained in the same hemisphere as the vertices.  (Note */
09580 /* that the negative of a circumcenter is also equidistant */
09581 /* from the vertices.)  If the triangulation covers the sur- */
09582 /* face, the Voronoi vertices are the circumcenters of the */
09583 /* triangles in the Delaunay triangulation.  LPTR, LEND, and */
09584 /* LNEW are not altered in this case. */
09585 
09586 /*   On the other hand, if the nodes are contained in a sin- */
09587 /* gle hemisphere, the triangulation is implicitly extended */
09588 /* to the entire surface by adding pseudo-arcs (of length */
09589 /* greater than 180 degrees) between boundary nodes forming */
09590 /* pseudo-triangles whose 'circumcenters' are included in the */
09591 /* list.  This extension to the triangulation actually con- */
09592 /* sists of a triangulation of the set of boundary nodes in */
09593 /* which the swap test is reversed (a non-empty circumcircle */
09594 /* test).  The negative circumcenters are stored as the */
09595 /* pseudo-triangle 'circumcenters'.  LISTC, LPTR, LEND, and */
09596 /* LNEW contain a data structure corresponding to the ex- */
09597 /* tended triangulation (Voronoi diagram), but LIST is not */
09598 /* altered in this case.  Thus, if it is necessary to retain */
09599 /* the original (unextended) triangulation data structure, */
09600 /* copies of LPTR and LNEW must be saved before calling this */
09601 /* routine. */
09602 
09603 
09604 /* On input: */
09605 
09606 /*       N = Number of nodes in the triangulation.  N .GE. 3. */
09607 /*           Note that, if N = 3, there are only two Voronoi */
09608 /*           vertices separated by 180 degrees, and the */
09609 /*           Voronoi regions are not well defined. */
09610 
09611 /*       NCOL = Number of columns reserved for LTRI.  This */
09612 /*              must be at least NB-2, where NB is the number */
09613 /*              of boundary nodes. */
09614 
09615 /*       X,Y,Z = Arrays of length N containing the Cartesian */
09616 /*               coordinates of the nodes (unit vectors). */
09617 
09618 /*       LIST = int array containing the set of adjacency */
09619 /*              lists.  Refer to Subroutine TRMESH. */
09620 
09621 /*       LEND = Set of pointers to ends of adjacency lists. */
09622 /*              Refer to Subroutine TRMESH. */
09623 
09624 /* The above parameters are not altered by this routine. */
09625 
09626 /*       LPTR = Array of pointers associated with LIST.  Re- */
09627 /*              fer to Subroutine TRMESH. */
09628 
09629 /*       LNEW = Pointer to the first empty location in LIST */
09630 /*              and LPTR (list length plus one). */
09631 
09632 /*       LTRI = int work space array dimensioned 6 by */
09633 /*              NCOL, or unused dummy parameter if NB = 0. */
09634 
09635 /*       LISTC = int array of length at least 3*NT, where */
09636 /*               NT = 2*N-4 is the number of triangles in the */
09637 /*               triangulation (after extending it to cover */
09638 /*               the entire surface if necessary). */
09639 
09640 /*       XC,YC,ZC,RC = Arrays of length NT = 2*N-4. */
09641 
09642 /* On output: */
09643 
09644 /*       LPTR = Array of pointers associated with LISTC: */
09645 /*              updated for the addition of pseudo-triangles */
09646 /*              if the original triangulation contains */
09647 /*              boundary nodes (NB > 0). */
09648 
09649 /*       LNEW = Pointer to the first empty location in LISTC */
09650 /*              and LPTR (list length plus one).  LNEW is not */
09651 /*              altered if NB = 0. */
09652 
09653 /*       LTRI = Triangle list whose first NB-2 columns con- */
09654 /*              tain the indexes of a clockwise-ordered */
09655 /*              sequence of vertices (first three rows) */
09656 /*              followed by the LTRI column indexes of the */
09657 /*              triangles opposite the vertices (or 0 */
09658 /*              denoting the exterior region) in the last */
09659 /*              three rows.  This array is not generally of */
09660 /*              any use. */
09661 
09662 /*       LISTC = Array containing triangle indexes (indexes */
09663 /*               to XC, YC, ZC, and RC) stored in 1-1 corres- */
09664 /*               pondence with LIST/LPTR entries (or entries */
09665 /*               that would be stored in LIST for the */
09666 /*               extended triangulation):  the index of tri- */
09667 /*               angle (N1,N2,N3) is stored in LISTC(K), */
09668 /*               LISTC(L), and LISTC(M), where LIST(K), */
09669 /*               LIST(L), and LIST(M) are the indexes of N2 */
09670 /*               as a neighbor of N1, N3 as a neighbor of N2, */
09671 /*               and N1 as a neighbor of N3.  The Voronoi */
09672 /*               region associated with a node is defined by */
09673 /*               the CCW-ordered sequence of circumcenters in */
09674 /*               one-to-one correspondence with its adjacency */
09675 /*               list (in the extended triangulation). */
09676 
09677 /*       NB = Number of boundary nodes unless IER = 1. */
09678 
09679 /*       XC,YC,ZC = Arrays containing the Cartesian coordi- */
09680 /*                  nates of the triangle circumcenters */
09681 /*                  (Voronoi vertices).  XC(I)**2 + YC(I)**2 */
09682 /*                  + ZC(I)**2 = 1.  The first NB-2 entries */
09683 /*                  correspond to pseudo-triangles if NB > 0. */
09684 
09685 /*       RC = Array containing circumradii (the arc lengths */
09686 /*            or angles between the circumcenters and associ- */
09687 /*            ated triangle vertices) in 1-1 correspondence */
09688 /*            with circumcenters. */
09689 
09690 /*       IER = Error indicator: */
09691 /*             IER = 0 if no errors were encountered. */
09692 /*             IER = 1 if N < 3. */
09693 /*             IER = 2 if NCOL < NB-2. */
09694 /*             IER = 3 if a triangle is degenerate (has ver- */
09695 /*                     tices lying on a common geodesic). */
09696 
09697 /* Modules required by CRLIST:  CIRCUM, LSTPTR, SWPTST */
09698 
09699 /* Intrinsic functions called by CRLIST:  ABS, ACOS */
09700 
09701 /* *********************************************************** */
09702 
09703 
09704 /* Local parameters: */
09705 
09706 /* C =         Circumcenter returned by Subroutine CIRCUM */
09707 /* I1,I2,I3 =  Permutation of (1,2,3):  LTRI row indexes */
09708 /* I4 =        LTRI row index in the range 1 to 3 */
09709 /* IERR =      Error flag for calls to CIRCUM */
09710 /* KT =        Triangle index */
09711 /* KT1,KT2 =   Indexes of a pair of adjacent pseudo-triangles */
09712 /* KT11,KT12 = Indexes of the pseudo-triangles opposite N1 */
09713 /*               and N2 as vertices of KT1 */
09714 /* KT21,KT22 = Indexes of the pseudo-triangles opposite N1 */
09715 /*               and N2 as vertices of KT2 */
09716 /* LP,LPN =    LIST pointers */
09717 /* LPL =       LIST pointer of the last neighbor of N1 */
09718 /* N0 =        Index of the first boundary node (initial */
09719 /*               value of N1) in the loop on boundary nodes */
09720 /*               used to store the pseudo-triangle indexes */
09721 /*               in LISTC */
09722 /* N1,N2,N3 =  Nodal indexes defining a triangle (CCW order) */
09723 /*               or pseudo-triangle (clockwise order) */
09724 /* N4 =        Index of the node opposite N2 -> N1 */
09725 /* NM2 =       N-2 */
09726 /* NN =        Local copy of N */
09727 /* NT =        Number of pseudo-triangles:  NB-2 */
09728 /* SWP =       long int variable set to TRUE in each optimiza- */
09729 /*               tion loop (loop on pseudo-arcs) iff a swap */
09730 /*               is performed */
09731 /* V1,V2,V3 =  Vertices of triangle KT = (N1,N2,N3) sent to */
09732 /*               Subroutine CIRCUM */
09733 
09734     /* Parameter adjustments */
09735     --lend;
09736     --z__;
09737     --y;
09738     --x;
09739     ltri -= 7;
09740     --list;
09741     --lptr;
09742     --listc;
09743     --xc;
09744     --yc;
09745     --zc;
09746     --rc;
09747 
09748     /* Function Body */
09749     nn = *n;
09750     *nb = 0;
09751     nt = 0;
09752     if (nn < 3) {
09753         goto L21;
09754     }
09755 
09756 /* Search for a boundary node N1. */
09757 
09758     i__1 = nn;
09759     for (n1 = 1; n1 <= i__1; ++n1) {
09760         lp = lend[n1];
09761         if (list[lp] < 0) {
09762             goto L2;
09763         }
09764 /* L1: */
09765     }
09766 
09767 /* The triangulation already covers the sphere. */
09768 
09769     goto L9;
09770 
09771 /* There are NB .GE. 3 boundary nodes.  Add NB-2 pseudo- */
09772 /*   triangles (N1,N2,N3) by connecting N3 to the NB-3 */
09773 /*   boundary nodes to which it is not already adjacent. */
09774 
09775 /*   Set N3 and N2 to the first and last neighbors, */
09776 /*     respectively, of N1. */
09777 
09778 L2:
09779     n2 = -list[lp];
09780     lp = lptr[lp];
09781     n3 = list[lp];
09782 
09783 /*   Loop on boundary arcs N1 -> N2 in clockwise order, */
09784 /*     storing triangles (N1,N2,N3) in column NT of LTRI */
09785 /*     along with the indexes of the triangles opposite */
09786 /*     the vertices. */
09787 
09788 L3:
09789     ++nt;
09790     if (nt <= *ncol) {
09791         ltri[nt * 6 + 1] = n1;
09792         ltri[nt * 6 + 2] = n2;
09793         ltri[nt * 6 + 3] = n3;
09794         ltri[nt * 6 + 4] = nt + 1;
09795         ltri[nt * 6 + 5] = nt - 1;
09796         ltri[nt * 6 + 6] = 0;
09797     }
09798     n1 = n2;
09799     lp = lend[n1];
09800     n2 = -list[lp];
09801     if (n2 != n3) {
09802         goto L3;
09803     }
09804 
09805     *nb = nt + 2;
09806     if (*ncol < nt) {
09807         goto L22;
09808     }
09809     ltri[nt * 6 + 4] = 0;
09810     if (nt == 1) {
09811         goto L7;
09812     }
09813 
09814 /* Optimize the exterior triangulation (set of pseudo- */
09815 /*   triangles) by applying swaps to the pseudo-arcs N1-N2 */
09816 /*   (pairs of adjacent pseudo-triangles KT1 and KT2 > KT1). */
09817 /*   The loop on pseudo-arcs is repeated until no swaps are */
09818 /*   performed. */
09819 
09820 L4:
09821     swp = FALSE_;
09822     i__1 = nt - 1;
09823     for (kt1 = 1; kt1 <= i__1; ++kt1) {
09824         for (i3 = 1; i3 <= 3; ++i3) {
09825             kt2 = ltri[i3 + 3 + kt1 * 6];
09826             if (kt2 <= kt1) {
09827                 goto L5;
09828             }
09829 
09830 /*   The LTRI row indexes (I1,I2,I3) of triangle KT1 = */
09831 /*     (N1,N2,N3) are a cyclical permutation of (1,2,3). */
09832 
09833             if (i3 == 1) {
09834                 i1 = 2;
09835                 i2 = 3;
09836             } else if (i3 == 2) {
09837                 i1 = 3;
09838                 i2 = 1;
09839             } else {
09840                 i1 = 1;
09841                 i2 = 2;
09842             }
09843             n1 = ltri[i1 + kt1 * 6];
09844             n2 = ltri[i2 + kt1 * 6];
09845             n3 = ltri[i3 + kt1 * 6];
09846 
09847 /*   KT2 = (N2,N1,N4) for N4 = LTRI(I,KT2), where */
09848 /*     LTRI(I+3,KT2) = KT1. */
09849 
09850             if (ltri[kt2 * 6 + 4] == kt1) {
09851                 i4 = 1;
09852             } else if (ltri[kt2 * 6 + 5] == kt1) {
09853                 i4 = 2;
09854             } else {
09855                 i4 = 3;
09856             }
09857             n4 = ltri[i4 + kt2 * 6];
09858 
09859 /*   The empty circumcircle test is reversed for the pseudo- */
09860 /*     triangles.  The reversal is implicit in the clockwise */
09861 /*     ordering of the vertices. */
09862 
09863             if (! swptst_(&n1, &n2, &n3, &n4, &x[1], &y[1], &z__[1])) {
09864                 goto L5;
09865             }
09866 
09867 /*   Swap arc N1-N2 for N3-N4.  KTij is the triangle opposite */
09868 /*     Nj as a vertex of KTi. */
09869 
09870             swp = TRUE_;
09871             kt11 = ltri[i1 + 3 + kt1 * 6];
09872             kt12 = ltri[i2 + 3 + kt1 * 6];
09873             if (i4 == 1) {
09874                 i2 = 2;
09875                 i1 = 3;
09876             } else if (i4 == 2) {
09877                 i2 = 3;
09878                 i1 = 1;
09879             } else {
09880                 i2 = 1;
09881                 i1 = 2;
09882             }
09883             kt21 = ltri[i1 + 3 + kt2 * 6];
09884             kt22 = ltri[i2 + 3 + kt2 * 6];
09885             ltri[kt1 * 6 + 1] = n4;
09886             ltri[kt1 * 6 + 2] = n3;
09887             ltri[kt1 * 6 + 3] = n1;
09888             ltri[kt1 * 6 + 4] = kt12;
09889             ltri[kt1 * 6 + 5] = kt22;
09890             ltri[kt1 * 6 + 6] = kt2;
09891             ltri[kt2 * 6 + 1] = n3;
09892             ltri[kt2 * 6 + 2] = n4;
09893             ltri[kt2 * 6 + 3] = n2;
09894             ltri[kt2 * 6 + 4] = kt21;
09895             ltri[kt2 * 6 + 5] = kt11;
09896             ltri[kt2 * 6 + 6] = kt1;
09897 
09898 /*   Correct the KT11 and KT22 entries that changed. */
09899 
09900             if (kt11 != 0) {
09901                 i4 = 4;
09902                 if (ltri[kt11 * 6 + 4] != kt1) {
09903                     i4 = 5;
09904                     if (ltri[kt11 * 6 + 5] != kt1) {
09905                         i4 = 6;
09906                     }
09907                 }
09908                 ltri[i4 + kt11 * 6] = kt2;
09909             }
09910             if (kt22 != 0) {
09911                 i4 = 4;
09912                 if (ltri[kt22 * 6 + 4] != kt2) {
09913                     i4 = 5;
09914                     if (ltri[kt22 * 6 + 5] != kt2) {
09915                         i4 = 6;
09916                     }
09917                 }
09918                 ltri[i4 + kt22 * 6] = kt1;
09919             }
09920 L5:
09921             ;
09922         }
09923 /* L6: */
09924     }
09925     if (swp) {
09926         goto L4;
09927     }
09928 
09929 /* Compute and store the negative circumcenters and radii of */
09930 /*   the pseudo-triangles in the first NT positions. */
09931 
09932 L7:
09933     i__1 = nt;
09934     for (kt = 1; kt <= i__1; ++kt) {
09935         n1 = ltri[kt * 6 + 1];
09936         n2 = ltri[kt * 6 + 2];
09937         n3 = ltri[kt * 6 + 3];
09938         v1[0] = x[n1];
09939         v1[1] = y[n1];
09940         v1[2] = z__[n1];
09941         v2[0] = x[n2];
09942         v2[1] = y[n2];
09943         v2[2] = z__[n2];
09944         v3[0] = x[n3];
09945         v3[1] = y[n3];
09946         v3[2] = z__[n3];
09947         circum_(v2, v1, v3, c__, &ierr);
09948         if (ierr != 0) {
09949             goto L23;
09950         }
09951 
09952 /*   Store the negative circumcenter and radius (computed */
09953 /*     from <V1,C>). */
09954 
09955         xc[kt] = -c__[0];
09956         yc[kt] = -c__[1];
09957         zc[kt] = -c__[2];
09958         t = -(v1[0] * c__[0] + v1[1] * c__[1] + v1[2] * c__[2]);
09959         if (t < -1.) {
09960             t = -1.;
09961         }
09962         if (t > 1.) {
09963             t = 1.;
09964         }
09965         rc[kt] = acos(t);
09966 /* L8: */
09967     }
09968 
09969 /* Compute and store the circumcenters and radii of the */
09970 /*   actual triangles in positions KT = NT+1, NT+2, ... */
09971 /*   Also, store the triangle indexes KT in the appropriate */
09972 /*   LISTC positions. */
09973 
09974 L9:
09975     kt = nt;
09976 
09977 /*   Loop on nodes N1. */
09978 
09979     nm2 = nn - 2;
09980     i__1 = nm2;
09981     for (n1 = 1; n1 <= i__1; ++n1) {
09982         lpl = lend[n1];
09983         lp = lpl;
09984         n3 = list[lp];
09985 
09986 /*   Loop on adjacent neighbors N2,N3 of N1 for which N2 > N1 */
09987 /*     and N3 > N1. */
09988 
09989 L10:
09990         lp = lptr[lp];
09991         n2 = n3;
09992         n3 = (i__2 = list[lp], abs(i__2));
09993         if (n2 <= n1 || n3 <= n1) {
09994             goto L11;
09995         }
09996         ++kt;
09997 
09998 /*   Compute the circumcenter C of triangle KT = (N1,N2,N3). */
09999 
10000         v1[0] = x[n1];
10001         v1[1] = y[n1];
10002         v1[2] = z__[n1];
10003         v2[0] = x[n2];
10004         v2[1] = y[n2];
10005         v2[2] = z__[n2];
10006         v3[0] = x[n3];
10007         v3[1] = y[n3];
10008         v3[2] = z__[n3];
10009         circum_(v1, v2, v3, c__, &ierr);
10010         if (ierr != 0) {
10011             goto L23;
10012         }
10013 
10014 /*   Store the circumcenter, radius and triangle index. */
10015 
10016         xc[kt] = c__[0];
10017         yc[kt] = c__[1];
10018         zc[kt] = c__[2];
10019         t = v1[0] * c__[0] + v1[1] * c__[1] + v1[2] * c__[2];
10020         if (t < -1.) {
10021             t = -1.;
10022         }
10023         if (t > 1.) {
10024             t = 1.;
10025         }
10026         rc[kt] = acos(t);
10027 
10028 /*   Store KT in LISTC(LPN), where Abs(LIST(LPN)) is the */
10029 /*     index of N2 as a neighbor of N1, N3 as a neighbor */
10030 /*     of N2, and N1 as a neighbor of N3. */
10031 
10032         lpn = lstptr_(&lpl, &n2, &list[1], &lptr[1]);
10033         listc[lpn] = kt;
10034         lpn = lstptr_(&lend[n2], &n3, &list[1], &lptr[1]);
10035         listc[lpn] = kt;
10036         lpn = lstptr_(&lend[n3], &n1, &list[1], &lptr[1]);
10037         listc[lpn] = kt;
10038 L11:
10039         if (lp != lpl) {
10040             goto L10;
10041         }
10042 /* L12: */
10043     }
10044     if (nt == 0) {
10045         goto L20;
10046     }
10047 
10048 /* Store the first NT triangle indexes in LISTC. */
10049 
10050 /*   Find a boundary triangle KT1 = (N1,N2,N3) with a */
10051 /*     boundary arc opposite N3. */
10052 
10053     kt1 = 0;
10054 L13:
10055     ++kt1;
10056     if (ltri[kt1 * 6 + 4] == 0) {
10057         i1 = 2;
10058         i2 = 3;
10059         i3 = 1;
10060         goto L14;
10061     } else if (ltri[kt1 * 6 + 5] == 0) {
10062         i1 = 3;
10063         i2 = 1;
10064         i3 = 2;
10065         goto L14;
10066     } else if (ltri[kt1 * 6 + 6] == 0) {
10067         i1 = 1;
10068         i2 = 2;
10069         i3 = 3;
10070         goto L14;
10071     }
10072     goto L13;
10073 L14:
10074     n1 = ltri[i1 + kt1 * 6];
10075     n0 = n1;
10076 
10077 /*   Loop on boundary nodes N1 in CCW order, storing the */
10078 /*     indexes of the clockwise-ordered sequence of triangles */
10079 /*     that contain N1.  The first triangle overwrites the */
10080 /*     last neighbor position, and the remaining triangles, */
10081 /*     if any, are appended to N1's adjacency list. */
10082 
10083 /*   A pointer to the first neighbor of N1 is saved in LPN. */
10084 
10085 L15:
10086     lp = lend[n1];
10087     lpn = lptr[lp];
10088     listc[lp] = kt1;
10089 
10090 /*   Loop on triangles KT2 containing N1. */
10091 
10092 L16:
10093     kt2 = ltri[i2 + 3 + kt1 * 6];
10094     if (kt2 != 0) {
10095 
10096 /*   Append KT2 to N1's triangle list. */
10097 
10098         lptr[lp] = *lnew;
10099         lp = *lnew;
10100         listc[lp] = kt2;
10101         ++(*lnew);
10102 
10103 /*   Set KT1 to KT2 and update (I1,I2,I3) such that */
10104 /*     LTRI(I1,KT1) = N1. */
10105 
10106         kt1 = kt2;
10107         if (ltri[kt1 * 6 + 1] == n1) {
10108             i1 = 1;
10109             i2 = 2;
10110             i3 = 3;
10111         } else if (ltri[kt1 * 6 + 2] == n1) {
10112             i1 = 2;
10113             i2 = 3;
10114             i3 = 1;
10115         } else {
10116             i1 = 3;
10117             i2 = 1;
10118             i3 = 2;
10119         }
10120         goto L16;
10121     }
10122 
10123 /*   Store the saved first-triangle pointer in LPTR(LP), set */
10124 /*     N1 to the next boundary node, test for termination, */
10125 /*     and permute the indexes:  the last triangle containing */
10126 /*     a boundary node is the first triangle containing the */
10127 /*     next boundary node. */
10128 
10129     lptr[lp] = lpn;
10130     n1 = ltri[i3 + kt1 * 6];
10131     if (n1 != n0) {
10132         i4 = i3;
10133         i3 = i2;
10134         i2 = i1;
10135         i1 = i4;
10136         goto L15;
10137     }
10138 
10139 /* No errors encountered. */
10140 
10141 L20:
10142     *ier = 0;
10143     return 0;
10144 
10145 /* N < 3. */
10146 
10147 L21:
10148     *ier = 1;
10149     return 0;
10150 
10151 /* Insufficient space reserved for LTRI. */
10152 
10153 L22:
10154     *ier = 2;
10155     return 0;
10156 
10157 /* Error flag returned by CIRCUM: KT indexes a null triangle. */
10158 
10159 L23:
10160     *ier = 3;
10161     return 0;
10162 } /* crlist_ */

int delarc_ ( int *  n,
int *  io1,
int *  io2,
int *  list,
int *  lptr,
int *  lend,
int *  lnew,
int *  ier 
)

Definition at line 10164 of file util_sparx.cpp.

References abs, delnb_(), and lstptr_().

10166 {
10167     /* System generated locals */
10168     int i__1;
10169 
10170     /* Local variables */
10171     static int n1, n2, n3, lp, lph, lpl;
10172     extern /* Subroutine */ int delnb_(int *, int *, int *,
10173             int *, int *, int *, int *, int *);
10174     extern int lstptr_(int *, int *, int *, int *);
10175 
10176 
10177 /* *********************************************************** */
10178 
10179 /*                                              From STRIPACK */
10180 /*                                            Robert J. Renka */
10181 /*                                  Dept. of Computer Science */
10182 /*                                       Univ. of North Texas */
10183 /*                                           renka@cs.unt.edu */
10184 /*                                                   07/17/96 */
10185 
10186 /*   This subroutine deletes a boundary arc from a triangula- */
10187 /* tion.  It may be used to remove a null triangle from the */
10188 /* convex hull boundary.  Note, however, that if the union of */
10189 /* triangles is rendered nonconvex, Subroutines DELNOD, EDGE, */
10190 /* and TRFIND (and hence ADDNOD) may fail.  Also, Function */
10191 /* NEARND should not be called following an arc deletion. */
10192 
10193 /*   This routine is identical to the similarly named routine */
10194 /* in TRIPACK. */
10195 
10196 
10197 /* On input: */
10198 
10199 /*       N = Number of nodes in the triangulation.  N .GE. 4. */
10200 
10201 /*       IO1,IO2 = Indexes (in the range 1 to N) of a pair of */
10202 /*                 adjacent boundary nodes defining the arc */
10203 /*                 to be removed. */
10204 
10205 /* The above parameters are not altered by this routine. */
10206 
10207 /*       LIST,LPTR,LEND,LNEW = Triangulation data structure */
10208 /*                             created by Subroutine TRMESH. */
10209 
10210 /* On output: */
10211 
10212 /*       LIST,LPTR,LEND,LNEW = Data structure updated with */
10213 /*                             the removal of arc IO1-IO2 */
10214 /*                             unless IER > 0. */
10215 
10216 /*       IER = Error indicator: */
10217 /*             IER = 0 if no errors were encountered. */
10218 /*             IER = 1 if N, IO1, or IO2 is outside its valid */
10219 /*                     range, or IO1 = IO2. */
10220 /*             IER = 2 if IO1-IO2 is not a boundary arc. */
10221 /*             IER = 3 if the node opposite IO1-IO2 is al- */
10222 /*                     ready a boundary node, and thus IO1 */
10223 /*                     or IO2 has only two neighbors or a */
10224 /*                     deletion would result in two triangu- */
10225 /*                     lations sharing a single node. */
10226 /*             IER = 4 if one of the nodes is a neighbor of */
10227 /*                     the other, but not vice versa, imply- */
10228 /*                     ing an invalid triangulation data */
10229 /*                     structure. */
10230 
10231 /* Module required by DELARC:  DELNB, LSTPTR */
10232 
10233 /* Intrinsic function called by DELARC:  ABS */
10234 
10235 /* *********************************************************** */
10236 
10237 
10238 /* Local parameters: */
10239 
10240 /* LP =       LIST pointer */
10241 /* LPH =      LIST pointer or flag returned by DELNB */
10242 /* LPL =      Pointer to the last neighbor of N1, N2, or N3 */
10243 /* N1,N2,N3 = Nodal indexes of a triangle such that N1->N2 */
10244 /*              is the directed boundary edge associated */
10245 /*              with IO1-IO2 */
10246 
10247     /* Parameter adjustments */
10248     --lend;
10249     --list;
10250     --lptr;
10251 
10252     /* Function Body */
10253     n1 = *io1;
10254     n2 = *io2;
10255 
10256 /* Test for errors, and set N1->N2 to the directed boundary */
10257 /*   edge associated with IO1-IO2:  (N1,N2,N3) is a triangle */
10258 /*   for some N3. */
10259 
10260     if (*n < 4 || n1 < 1 || n1 > *n || n2 < 1 || n2 > *n || n1 == n2) {
10261         *ier = 1;
10262         return 0;
10263     }
10264 
10265     lpl = lend[n2];
10266     if (-list[lpl] != n1) {
10267         n1 = n2;
10268         n2 = *io1;
10269         lpl = lend[n2];
10270         if (-list[lpl] != n1) {
10271             *ier = 2;
10272             return 0;
10273         }
10274     }
10275 
10276 /* Set N3 to the node opposite N1->N2 (the second neighbor */
10277 /*   of N1), and test for error 3 (N3 already a boundary */
10278 /*   node). */
10279 
10280     lpl = lend[n1];
10281     lp = lptr[lpl];
10282     lp = lptr[lp];
10283     n3 = (i__1 = list[lp], abs(i__1));
10284     lpl = lend[n3];
10285     if (list[lpl] <= 0) {
10286         *ier = 3;
10287         return 0;
10288     }
10289 
10290 /* Delete N2 as a neighbor of N1, making N3 the first */
10291 /*   neighbor, and test for error 4 (N2 not a neighbor */
10292 /*   of N1).  Note that previously computed pointers may */
10293 /*   no longer be valid following the call to DELNB. */
10294 
10295     delnb_(&n1, &n2, n, &list[1], &lptr[1], &lend[1], lnew, &lph);
10296     if (lph < 0) {
10297         *ier = 4;
10298         return 0;
10299     }
10300 
10301 /* Delete N1 as a neighbor of N2, making N3 the new last */
10302 /*   neighbor. */
10303 
10304     delnb_(&n2, &n1, n, &list[1], &lptr[1], &lend[1], lnew, &lph);
10305 
10306 /* Make N3 a boundary node with first neighbor N2 and last */
10307 /*   neighbor N1. */
10308 
10309     lp = lstptr_(&lend[n3], &n1, &list[1], &lptr[1]);
10310     lend[n3] = lp;
10311     list[lp] = -n1;
10312 
10313 /* No errors encountered. */
10314 
10315     *ier = 0;
10316     return 0;
10317 } /* delarc_ */

int delnb_ ( int *  n0,
int *  nb,
int *  n,
int *  list,
int *  lptr,
int *  lend,
int *  lnew,
int *  lph 
)

Definition at line 10319 of file util_sparx.cpp.

References abs, and nn().

Referenced by delarc_(), and delnod_().

10321 {
10322     /* System generated locals */
10323     int i__1;
10324 
10325     /* Local variables */
10326     static int i__, lp, nn, lpb, lpl, lpp, lnw;
10327 
10328 
10329 /* *********************************************************** */
10330 
10331 /*                                              From STRIPACK */
10332 /*                                            Robert J. Renka */
10333 /*                                  Dept. of Computer Science */
10334 /*                                       Univ. of North Texas */
10335 /*                                           renka@cs.unt.edu */
10336 /*                                                   07/29/98 */
10337 
10338 /*   This subroutine deletes a neighbor NB from the adjacency */
10339 /* list of node N0 (but N0 is not deleted from the adjacency */
10340 /* list of NB) and, if NB is a boundary node, makes N0 a */
10341 /* boundary node.  For pointer (LIST index) LPH to NB as a */
10342 /* neighbor of N0, the empty LIST,LPTR location LPH is filled */
10343 /* in with the values at LNEW-1, pointer LNEW-1 (in LPTR and */
10344 /* possibly in LEND) is changed to LPH, and LNEW is decremen- */
10345 /* ted.  This requires a search of LEND and LPTR entailing an */
10346 /* expected operation count of O(N). */
10347 
10348 /*   This routine is identical to the similarly named routine */
10349 /* in TRIPACK. */
10350 
10351 
10352 /* On input: */
10353 
10354 /*       N0,NB = Indexes, in the range 1 to N, of a pair of */
10355 /*               nodes such that NB is a neighbor of N0. */
10356 /*               (N0 need not be a neighbor of NB.) */
10357 
10358 /*       N = Number of nodes in the triangulation.  N .GE. 3. */
10359 
10360 /* The above parameters are not altered by this routine. */
10361 
10362 /*       LIST,LPTR,LEND,LNEW = Data structure defining the */
10363 /*                             triangulation. */
10364 
10365 /* On output: */
10366 
10367 /*       LIST,LPTR,LEND,LNEW = Data structure updated with */
10368 /*                             the removal of NB from the ad- */
10369 /*                             jacency list of N0 unless */
10370 /*                             LPH < 0. */
10371 
10372 /*       LPH = List pointer to the hole (NB as a neighbor of */
10373 /*             N0) filled in by the values at LNEW-1 or error */
10374 /*             indicator: */
10375 /*             LPH > 0 if no errors were encountered. */
10376 /*             LPH = -1 if N0, NB, or N is outside its valid */
10377 /*                      range. */
10378 /*             LPH = -2 if NB is not a neighbor of N0. */
10379 
10380 /* Modules required by DELNB:  None */
10381 
10382 /* Intrinsic function called by DELNB:  ABS */
10383 
10384 /* *********************************************************** */
10385 
10386 
10387 /* Local parameters: */
10388 
10389 /* I =   DO-loop index */
10390 /* LNW = LNEW-1 (output value of LNEW) */
10391 /* LP =  LIST pointer of the last neighbor of NB */
10392 /* LPB = Pointer to NB as a neighbor of N0 */
10393 /* LPL = Pointer to the last neighbor of N0 */
10394 /* LPP = Pointer to the neighbor of N0 that precedes NB */
10395 /* NN =  Local copy of N */
10396 
10397     /* Parameter adjustments */
10398     --lend;
10399     --list;
10400     --lptr;
10401 
10402     /* Function Body */
10403     nn = *n;
10404 
10405 /* Test for error 1. */
10406 
10407     if (*n0 < 1 || *n0 > nn || *nb < 1 || *nb > nn || nn < 3) {
10408         *lph = -1;
10409         return 0;
10410     }
10411 
10412 /*   Find pointers to neighbors of N0: */
10413 
10414 /*     LPL points to the last neighbor, */
10415 /*     LPP points to the neighbor NP preceding NB, and */
10416 /*     LPB points to NB. */
10417 
10418     lpl = lend[*n0];
10419     lpp = lpl;
10420     lpb = lptr[lpp];
10421 L1:
10422     if (list[lpb] == *nb) {
10423         goto L2;
10424     }
10425     lpp = lpb;
10426     lpb = lptr[lpp];
10427     if (lpb != lpl) {
10428         goto L1;
10429     }
10430 
10431 /*   Test for error 2 (NB not found). */
10432 
10433     if ((i__1 = list[lpb], abs(i__1)) != *nb) {
10434         *lph = -2;
10435         return 0;
10436     }
10437 
10438 /*   NB is the last neighbor of N0.  Make NP the new last */
10439 /*     neighbor and, if NB is a boundary node, then make N0 */
10440 /*     a boundary node. */
10441 
10442     lend[*n0] = lpp;
10443     lp = lend[*nb];
10444     if (list[lp] < 0) {
10445         list[lpp] = -list[lpp];
10446     }
10447     goto L3;
10448 
10449 /*   NB is not the last neighbor of N0.  If NB is a boundary */
10450 /*     node and N0 is not, then make N0 a boundary node with */
10451 /*     last neighbor NP. */
10452 
10453 L2:
10454     lp = lend[*nb];
10455     if (list[lp] < 0 && list[lpl] > 0) {
10456         lend[*n0] = lpp;
10457         list[lpp] = -list[lpp];
10458     }
10459 
10460 /*   Update LPTR so that the neighbor following NB now fol- */
10461 /*     lows NP, and fill in the hole at location LPB. */
10462 
10463 L3:
10464     lptr[lpp] = lptr[lpb];
10465     lnw = *lnew - 1;
10466     list[lpb] = list[lnw];
10467     lptr[lpb] = lptr[lnw];
10468     for (i__ = nn; i__ >= 1; --i__) {
10469         if (lend[i__] == lnw) {
10470             lend[i__] = lpb;
10471             goto L5;
10472         }
10473 /* L4: */
10474     }
10475 
10476 L5:
10477     i__1 = lnw - 1;
10478     for (i__ = 1; i__ <= i__1; ++i__) {
10479         if (lptr[i__] == lnw) {
10480             lptr[i__] = lpb;
10481         }
10482 /* L6: */
10483     }
10484 
10485 /* No errors encountered. */
10486 
10487     *lnew = lnw;
10488     *lph = lpb;
10489     return 0;
10490 } /* delnb_ */

int delnod_ ( int *  k,
int *  n,
double *  x,
double *  y,
double *  z__,
int *  list,
int *  lptr,
int *  lend,
int *  lnew,
int *  lwk,
int *  iwk,
int *  ier 
)

Definition at line 10492 of file util_sparx.cpp.

References abs, delnb_(), FALSE_, ierr, left_(), lstptr_(), nbcnt_(), nn(), optim_(), swap_(), and TRUE_.

10495 {
10496     /* System generated locals */
10497     int i__1;
10498 
10499     /* Local variables */
10500     static int i__, j, n1, n2;
10501     static double x1, x2, y1, y2, z1, z2;
10502     static int nl, lp, nn, nr;
10503     static double xl, yl, zl, xr, yr, zr;
10504     static int nnb, lp21, lpf, lph, lpl, lpn, iwl, nit, lnw, lpl2;
10505     extern long int left_(double *, double *, double *, double
10506             *, double *, double *, double *, double *,
10507             double *);
10508     static long int bdry;
10509     static int ierr, lwkl;
10510     extern /* Subroutine */ int swap_(int *, int *, int *,
10511             int *, int *, int *, int *, int *), delnb_(
10512             int *, int *, int *, int *, int *, int *,
10513             int *, int *);
10514     extern int nbcnt_(int *, int *);
10515     extern /* Subroutine */ int optim_(double *, double *, double
10516             *, int *, int *, int *, int *, int *, int
10517             *, int *);
10518     static int nfrst;
10519     extern int lstptr_(int *, int *, int *, int *);
10520 
10521 
10522 /* *********************************************************** */
10523 
10524 /*                                              From STRIPACK */
10525 /*                                            Robert J. Renka */
10526 /*                                  Dept. of Computer Science */
10527 /*                                       Univ. of North Texas */
10528 /*                                           renka@cs.unt.edu */
10529 /*                                                   11/30/99 */
10530 
10531 /*   This subroutine deletes node K (along with all arcs */
10532 /* incident on node K) from a triangulation of N nodes on the */
10533 /* unit sphere, and inserts arcs as necessary to produce a */
10534 /* triangulation of the remaining N-1 nodes.  If a Delaunay */
10535 /* triangulation is input, a Delaunay triangulation will */
10536 /* result, and thus, DELNOD reverses the effect of a call to */
10537 /* Subroutine ADDNOD. */
10538 
10539 
10540 /* On input: */
10541 
10542 /*       K = Index (for X, Y, and Z) of the node to be */
10543 /*           deleted.  1 .LE. K .LE. N. */
10544 
10545 /* K is not altered by this routine. */
10546 
10547 /*       N = Number of nodes in the triangulation on input. */
10548 /*           N .GE. 4.  Note that N will be decremented */
10549 /*           following the deletion. */
10550 
10551 /*       X,Y,Z = Arrays of length N containing the Cartesian */
10552 /*               coordinates of the nodes in the triangula- */
10553 /*               tion. */
10554 
10555 /*       LIST,LPTR,LEND,LNEW = Data structure defining the */
10556 /*                             triangulation.  Refer to Sub- */
10557 /*                             routine TRMESH. */
10558 
10559 /*       LWK = Number of columns reserved for IWK.  LWK must */
10560 /*             be at least NNB-3, where NNB is the number of */
10561 /*             neighbors of node K, including an extra */
10562 /*             pseudo-node if K is a boundary node. */
10563 
10564 /*       IWK = int work array dimensioned 2 by LWK (or */
10565 /*             array of length .GE. 2*LWK). */
10566 
10567 /* On output: */
10568 
10569 /*       N = Number of nodes in the triangulation on output. */
10570 /*           The input value is decremented unless 1 .LE. IER */
10571 /*           .LE. 4. */
10572 
10573 /*       X,Y,Z = Updated arrays containing nodal coordinates */
10574 /*               (with elements K+1,...,N+1 shifted up one */
10575 /*               position, thus overwriting element K) unless */
10576 /*               1 .LE. IER .LE. 4. */
10577 
10578 /*       LIST,LPTR,LEND,LNEW = Updated triangulation data */
10579 /*                             structure reflecting the dele- */
10580 /*                             tion unless 1 .LE. IER .LE. 4. */
10581 /*                             Note that the data structure */
10582 /*                             may have been altered if IER > */
10583 /*                             3. */
10584 
10585 /*       LWK = Number of IWK columns required unless IER = 1 */
10586 /*             or IER = 3. */
10587 
10588 /*       IWK = Indexes of the endpoints of the new arcs added */
10589 /*             unless LWK = 0 or 1 .LE. IER .LE. 4.  (Arcs */
10590 /*             are associated with columns, or pairs of */
10591 /*             adjacent elements if IWK is declared as a */
10592 /*             singly-subscripted array.) */
10593 
10594 /*       IER = Error indicator: */
10595 /*             IER = 0 if no errors were encountered. */
10596 /*             IER = 1 if K or N is outside its valid range */
10597 /*                     or LWK < 0 on input. */
10598 /*             IER = 2 if more space is required in IWK. */
10599 /*                     Refer to LWK. */
10600 /*             IER = 3 if the triangulation data structure is */
10601 /*                     invalid on input. */
10602 /*             IER = 4 if K indexes an interior node with */
10603 /*                     four or more neighbors, none of which */
10604 /*                     can be swapped out due to collineari- */
10605 /*                     ty, and K cannot therefore be deleted. */
10606 /*             IER = 5 if an error flag (other than IER = 1) */
10607 /*                     was returned by OPTIM.  An error */
10608 /*                     message is written to the standard */
10609 /*                     output unit in this case. */
10610 /*             IER = 6 if error flag 1 was returned by OPTIM. */
10611 /*                     This is not necessarily an error, but */
10612 /*                     the arcs may not be optimal. */
10613 
10614 /*   Note that the deletion may result in all remaining nodes */
10615 /* being collinear.  This situation is not flagged. */
10616 
10617 /* Modules required by DELNOD:  DELNB, LEFT, LSTPTR, NBCNT, */
10618 /*                                OPTIM, SWAP, SWPTST */
10619 
10620 /* Intrinsic function called by DELNOD:  ABS */
10621 
10622 /* *********************************************************** */
10623 
10624 
10625 /* Local parameters: */
10626 
10627 /* BDRY =    long int variable with value TRUE iff N1 is a */
10628 /*             boundary node */
10629 /* I,J =     DO-loop indexes */
10630 /* IERR =    Error flag returned by OPTIM */
10631 /* IWL =     Number of IWK columns containing arcs */
10632 /* LNW =     Local copy of LNEW */
10633 /* LP =      LIST pointer */
10634 /* LP21 =    LIST pointer returned by SWAP */
10635 /* LPF,LPL = Pointers to the first and last neighbors of N1 */
10636 /* LPH =     Pointer (or flag) returned by DELNB */
10637 /* LPL2 =    Pointer to the last neighbor of N2 */
10638 /* LPN =     Pointer to a neighbor of N1 */
10639 /* LWKL =    Input value of LWK */
10640 /* N1 =      Local copy of K */
10641 /* N2 =      Neighbor of N1 */
10642 /* NFRST =   First neighbor of N1:  LIST(LPF) */
10643 /* NIT =     Number of iterations in OPTIM */
10644 /* NR,NL =   Neighbors of N1 preceding (to the right of) and */
10645 /*             following (to the left of) N2, respectively */
10646 /* NN =      Number of nodes in the triangulation */
10647 /* NNB =     Number of neighbors of N1 (including a pseudo- */
10648 /*             node representing the boundary if N1 is a */
10649 /*             boundary node) */
10650 /* X1,Y1,Z1 = Coordinates of N1 */
10651 /* X2,Y2,Z2 = Coordinates of N2 */
10652 /* XL,YL,ZL = Coordinates of NL */
10653 /* XR,YR,ZR = Coordinates of NR */
10654 
10655 
10656 /* Set N1 to K and NNB to the number of neighbors of N1 (plus */
10657 /*   one if N1 is a boundary node), and test for errors.  LPF */
10658 /*   and LPL are LIST indexes of the first and last neighbors */
10659 /*   of N1, IWL is the number of IWK columns containing arcs, */
10660 /*   and BDRY is TRUE iff N1 is a boundary node. */
10661 
10662     /* Parameter adjustments */
10663     iwk -= 3;
10664     --lend;
10665     --lptr;
10666     --list;
10667     --z__;
10668     --y;
10669     --x;
10670 
10671     /* Function Body */
10672     n1 = *k;
10673     nn = *n;
10674     if (n1 < 1 || n1 > nn || nn < 4 || *lwk < 0) {
10675         goto L21;
10676     }
10677     lpl = lend[n1];
10678     lpf = lptr[lpl];
10679     nnb = nbcnt_(&lpl, &lptr[1]);
10680     bdry = list[lpl] < 0;
10681     if (bdry) {
10682         ++nnb;
10683     }
10684     if (nnb < 3) {
10685         goto L23;
10686     }
10687     lwkl = *lwk;
10688     *lwk = nnb - 3;
10689     if (lwkl < *lwk) {
10690         goto L22;
10691     }
10692     iwl = 0;
10693     if (nnb == 3) {
10694         goto L3;
10695     }
10696 
10697 /* Initialize for loop on arcs N1-N2 for neighbors N2 of N1, */
10698 /*   beginning with the second neighbor.  NR and NL are the */
10699 /*   neighbors preceding and following N2, respectively, and */
10700 /*   LP indexes NL.  The loop is exited when all possible */
10701 /*   swaps have been applied to arcs incident on N1. */
10702 
10703     x1 = x[n1];
10704     y1 = y[n1];
10705     z1 = z__[n1];
10706     nfrst = list[lpf];
10707     nr = nfrst;
10708     xr = x[nr];
10709     yr = y[nr];
10710     zr = z__[nr];
10711     lp = lptr[lpf];
10712     n2 = list[lp];
10713     x2 = x[n2];
10714     y2 = y[n2];
10715     z2 = z__[n2];
10716     lp = lptr[lp];
10717 
10718 /* Top of loop:  set NL to the neighbor following N2. */
10719 
10720 L1:
10721     nl = (i__1 = list[lp], abs(i__1));
10722     if (nl == nfrst && bdry) {
10723         goto L3;
10724     }
10725     xl = x[nl];
10726     yl = y[nl];
10727     zl = z__[nl];
10728 
10729 /*   Test for a convex quadrilateral.  To avoid an incorrect */
10730 /*     test caused by collinearity, use the fact that if N1 */
10731 /*     is a boundary node, then N1 LEFT NR->NL and if N2 is */
10732 /*     a boundary node, then N2 LEFT NL->NR. */
10733 
10734     lpl2 = lend[n2];
10735     if (! ((bdry || left_(&xr, &yr, &zr, &xl, &yl, &zl, &x1, &y1, &z1)) && (
10736             list[lpl2] < 0 || left_(&xl, &yl, &zl, &xr, &yr, &zr, &x2, &y2, &
10737             z2)))) {
10738 
10739 /*   Nonconvex quadrilateral -- no swap is possible. */
10740 
10741         nr = n2;
10742         xr = x2;
10743         yr = y2;
10744         zr = z2;
10745         goto L2;
10746     }
10747 
10748 /*   The quadrilateral defined by adjacent triangles */
10749 /*     (N1,N2,NL) and (N2,N1,NR) is convex.  Swap in */
10750 /*     NL-NR and store it in IWK unless NL and NR are */
10751 /*     already adjacent, in which case the swap is not */
10752 /*     possible.  Indexes larger than N1 must be decremented */
10753 /*     since N1 will be deleted from X, Y, and Z. */
10754 
10755     swap_(&nl, &nr, &n1, &n2, &list[1], &lptr[1], &lend[1], &lp21);
10756     if (lp21 == 0) {
10757         nr = n2;
10758         xr = x2;
10759         yr = y2;
10760         zr = z2;
10761         goto L2;
10762     }
10763     ++iwl;
10764     if (nl <= n1) {
10765         iwk[(iwl << 1) + 1] = nl;
10766     } else {
10767         iwk[(iwl << 1) + 1] = nl - 1;
10768     }
10769     if (nr <= n1) {
10770         iwk[(iwl << 1) + 2] = nr;
10771     } else {
10772         iwk[(iwl << 1) + 2] = nr - 1;
10773     }
10774 
10775 /*   Recompute the LIST indexes and NFRST, and decrement NNB. */
10776 
10777     lpl = lend[n1];
10778     --nnb;
10779     if (nnb == 3) {
10780         goto L3;
10781     }
10782     lpf = lptr[lpl];
10783     nfrst = list[lpf];
10784     lp = lstptr_(&lpl, &nl, &list[1], &lptr[1]);
10785     if (nr == nfrst) {
10786         goto L2;
10787     }
10788 
10789 /*   NR is not the first neighbor of N1. */
10790 /*     Back up and test N1-NR for a swap again:  Set N2 to */
10791 /*     NR and NR to the previous neighbor of N1 -- the */
10792 /*     neighbor of NR which follows N1.  LP21 points to NL */
10793 /*     as a neighbor of NR. */
10794 
10795     n2 = nr;
10796     x2 = xr;
10797     y2 = yr;
10798     z2 = zr;
10799     lp21 = lptr[lp21];
10800     lp21 = lptr[lp21];
10801     nr = (i__1 = list[lp21], abs(i__1));
10802     xr = x[nr];
10803     yr = y[nr];
10804     zr = z__[nr];
10805     goto L1;
10806 
10807 /*   Bottom of loop -- test for termination of loop. */
10808 
10809 L2:
10810     if (n2 == nfrst) {
10811         goto L3;
10812     }
10813     n2 = nl;
10814     x2 = xl;
10815     y2 = yl;
10816     z2 = zl;
10817     lp = lptr[lp];
10818     goto L1;
10819 
10820 /* Delete N1 and all its incident arcs.  If N1 is an interior */
10821 /*   node and either NNB > 3 or NNB = 3 and N2 LEFT NR->NL, */
10822 /*   then N1 must be separated from its neighbors by a plane */
10823 /*   containing the origin -- its removal reverses the effect */
10824 /*   of a call to COVSPH, and all its neighbors become */
10825 /*   boundary nodes.  This is achieved by treating it as if */
10826 /*   it were a boundary node (setting BDRY to TRUE, changing */
10827 /*   a sign in LIST, and incrementing NNB). */
10828 
10829 L3:
10830     if (! bdry) {
10831         if (nnb > 3) {
10832             bdry = TRUE_;
10833         } else {
10834             lpf = lptr[lpl];
10835             nr = list[lpf];
10836             lp = lptr[lpf];
10837             n2 = list[lp];
10838             nl = list[lpl];
10839             bdry = left_(&x[nr], &y[nr], &z__[nr], &x[nl], &y[nl], &z__[nl], &
10840                     x[n2], &y[n2], &z__[n2]);
10841         }
10842         if (bdry) {
10843 
10844 /*   IF a boundary node already exists, then N1 and its */
10845 /*     neighbors cannot be converted to boundary nodes. */
10846 /*     (They must be collinear.)  This is a problem if */
10847 /*     NNB > 3. */
10848 
10849             i__1 = nn;
10850             for (i__ = 1; i__ <= i__1; ++i__) {
10851                 if (list[lend[i__]] < 0) {
10852                     bdry = FALSE_;
10853                     goto L5;
10854                 }
10855 /* L4: */
10856             }
10857             list[lpl] = -list[lpl];
10858             ++nnb;
10859         }
10860     }
10861 L5:
10862     if (! bdry && nnb > 3) {
10863         goto L24;
10864     }
10865 
10866 /* Initialize for loop on neighbors.  LPL points to the last */
10867 /*   neighbor of N1.  LNEW is stored in local variable LNW. */
10868 
10869     lp = lpl;
10870     lnw = *lnew;
10871 
10872 /* Loop on neighbors N2 of N1, beginning with the first. */
10873 
10874 L6:
10875     lp = lptr[lp];
10876     n2 = (i__1 = list[lp], abs(i__1));
10877     delnb_(&n2, &n1, n, &list[1], &lptr[1], &lend[1], &lnw, &lph);
10878     if (lph < 0) {
10879         goto L23;
10880     }
10881 
10882 /*   LP and LPL may require alteration. */
10883 
10884     if (lpl == lnw) {
10885         lpl = lph;
10886     }
10887     if (lp == lnw) {
10888         lp = lph;
10889     }
10890     if (lp != lpl) {
10891         goto L6;
10892     }
10893 
10894 /* Delete N1 from X, Y, Z, and LEND, and remove its adjacency */
10895 /*   list from LIST and LPTR.  LIST entries (nodal indexes) */
10896 /*   which are larger than N1 must be decremented. */
10897 
10898     --nn;
10899     if (n1 > nn) {
10900         goto L9;
10901     }
10902     i__1 = nn;
10903     for (i__ = n1; i__ <= i__1; ++i__) {
10904         x[i__] = x[i__ + 1];
10905         y[i__] = y[i__ + 1];
10906         z__[i__] = z__[i__ + 1];
10907         lend[i__] = lend[i__ + 1];
10908 /* L7: */
10909     }
10910 
10911     i__1 = lnw - 1;
10912     for (i__ = 1; i__ <= i__1; ++i__) {
10913         if (list[i__] > n1) {
10914             --list[i__];
10915         }
10916         if (list[i__] < -n1) {
10917             ++list[i__];
10918         }
10919 /* L8: */
10920     }
10921 
10922 /*   For LPN = first to last neighbors of N1, delete the */
10923 /*     preceding neighbor (indexed by LP). */
10924 
10925 /*   Each empty LIST,LPTR location LP is filled in with the */
10926 /*     values at LNW-1, and LNW is decremented.  All pointers */
10927 /*     (including those in LPTR and LEND) with value LNW-1 */
10928 /*     must be changed to LP. */
10929 
10930 /*  LPL points to the last neighbor of N1. */
10931 
10932 L9:
10933     if (bdry) {
10934         --nnb;
10935     }
10936     lpn = lpl;
10937     i__1 = nnb;
10938     for (j = 1; j <= i__1; ++j) {
10939         --lnw;
10940         lp = lpn;
10941         lpn = lptr[lp];
10942         list[lp] = list[lnw];
10943         lptr[lp] = lptr[lnw];
10944         if (lptr[lpn] == lnw) {
10945             lptr[lpn] = lp;
10946         }
10947         if (lpn == lnw) {
10948             lpn = lp;
10949         }
10950         for (i__ = nn; i__ >= 1; --i__) {
10951             if (lend[i__] == lnw) {
10952                 lend[i__] = lp;
10953                 goto L11;
10954             }
10955 /* L10: */
10956         }
10957 
10958 L11:
10959         for (i__ = lnw - 1; i__ >= 1; --i__) {
10960             if (lptr[i__] == lnw) {
10961                 lptr[i__] = lp;
10962             }
10963 /* L12: */
10964         }
10965 /* L13: */
10966     }
10967 
10968 /* Update N and LNEW, and optimize the patch of triangles */
10969 /*   containing K (on input) by applying swaps to the arcs */
10970 /*   in IWK. */
10971 
10972     *n = nn;
10973     *lnew = lnw;
10974     if (iwl > 0) {
10975         nit = iwl << 2;
10976         optim_(&x[1], &y[1], &z__[1], &iwl, &list[1], &lptr[1], &lend[1], &
10977                 nit, &iwk[3], &ierr);
10978         if (ierr != 0 && ierr != 1) {
10979             goto L25;
10980         }
10981         if (ierr == 1) {
10982             goto L26;
10983         }
10984     }
10985 
10986 /* Successful termination. */
10987 
10988     *ier = 0;
10989     return 0;
10990 
10991 /* Invalid input parameter. */
10992 
10993 L21:
10994     *ier = 1;
10995     return 0;
10996 
10997 /* Insufficient space reserved for IWK. */
10998 
10999 L22:
11000     *ier = 2;
11001     return 0;
11002 
11003 /* Invalid triangulation data structure.  NNB < 3 on input or */
11004 /*   N2 is a neighbor of N1 but N1 is not a neighbor of N2. */
11005 
11006 L23:
11007     *ier = 3;
11008     return 0;
11009 
11010 /* N1 is interior but NNB could not be reduced to 3. */
11011 
11012 L24:
11013     *ier = 4;
11014     return 0;
11015 
11016 /* Error flag (other than 1) returned by OPTIM. */
11017 
11018 L25:
11019     *ier = 5;
11020 /*      WRITE (*,100) NIT, IERR */
11021 /*  100 FORMAT (//5X,'*** Error in OPTIM (called from ', */
11022 /*     .        'DELNOD):  NIT = ',I4,', IER = ',I1,' ***'/) */
11023     return 0;
11024 
11025 /* Error flag 1 returned by OPTIM. */
11026 
11027 L26:
11028     *ier = 6;
11029     return 0;
11030 } /* delnod_ */

int drwarc_ ( int *  ,
double *  p,
double *  q,
double *  tol,
int *  nseg 
)

Definition at line 11032 of file util_sparx.cpp.

References abs, and sqrt().

Referenced by trplot_(), and vrplot_().

11034 {
11035     /* System generated locals */
11036     int i__1;
11037     double d__1;
11038 
11039     /* Builtin functions */
11040     //double sqrt(double);
11041 
11042     /* Local variables */
11043     static int i__, k;
11044     static double s, p1[3], p2[3], u1, u2, v1, v2;
11045     static int na;
11046     static double dp[3], du, dv, pm[3], um, vm, err, enrm;
11047 
11048 
11049 /* *********************************************************** */
11050 
11051 /*                                              From STRIPACK */
11052 /*                                            Robert J. Renka */
11053 /*                                  Dept. of Computer Science */
11054 /*                                       Univ. of North Texas */
11055 /*                                           renka@cs.unt.edu */
11056 /*                                                   03/04/03 */
11057 
11058 /*   Given unit vectors P and Q corresponding to northern */
11059 /* hemisphere points (with positive third components), this */
11060 /* subroutine draws a polygonal line which approximates the */
11061 /* projection of arc P-Q onto the plane containing the */
11062 /* equator. */
11063 
11064 /*   The line segment is drawn by writing a sequence of */
11065 /* 'moveto' and 'lineto' Postscript commands to unit LUN.  It */
11066 /* is assumed that an open file is attached to the unit, */
11067 /* header comments have been written to the file, a window- */
11068 /* to-viewport mapping has been established, etc. */
11069 
11070 /* On input: */
11071 
11072 /*       LUN = long int unit number in the range 0 to 99. */
11073 
11074 /*       P,Q = Arrays of length 3 containing the endpoints of */
11075 /*             the arc to be drawn. */
11076 
11077 /*       TOL = Maximum distance in world coordinates between */
11078 /*             the projected arc and polygonal line. */
11079 
11080 /* Input parameters are not altered by this routine. */
11081 
11082 /* On output: */
11083 
11084 /*       NSEG = Number of line segments in the polygonal */
11085 /*              approximation to the projected arc.  This is */
11086 /*              a decreasing function of TOL.  NSEG = 0 and */
11087 /*              no drawing is performed if P = Q or P = -Q */
11088 /*              or an error is encountered in writing to unit */
11089 /*              LUN. */
11090 
11091 /* STRIPACK modules required by DRWARC:  None */
11092 
11093 /* Intrinsic functions called by DRWARC:  ABS, DBLE, SQRT */
11094 
11095 /* *********************************************************** */
11096 
11097 
11098 /* Local parameters: */
11099 
11100 /* DP =    (Q-P)/NSEG */
11101 /* DU,DV = Components of the projection Q'-P' of arc P->Q */
11102 /*           onto the projection plane */
11103 /* ENRM =  Euclidean norm (or squared norm) of Q'-P' or PM */
11104 /* ERR =   Orthogonal distance from the projected midpoint */
11105 /*           PM' to the line defined by P' and Q': */
11106 /*           |Q'-P' X PM'-P'|/|Q'-P'| */
11107 /* I,K =   DO-loop indexes */
11108 /* NA =    Number of arcs (segments) in the partition of P-Q */
11109 /* P1,P2 = Pairs of adjacent points in a uniform partition of */
11110 /*           arc P-Q into NSEG segments; obtained by normal- */
11111 /*           izing PM values */
11112 /* PM =    Midpoint of arc P-Q or a point P + k*DP in a */
11113 /*           uniform partition of the line segment P-Q into */
11114 /*           NSEG segments */
11115 /* S =     Scale factor 1/NA */
11116 /* U1,V1 = Components of P' */
11117 /* U2,V2 = Components of Q' */
11118 /* UM,VM = Components of the midpoint PM' */
11119 
11120 
11121 /* Compute the midpoint PM of arc P-Q. */
11122 
11123     /* Parameter adjustments */
11124     --q;
11125     --p;
11126 
11127     /* Function Body */
11128     enrm = 0.;
11129     for (i__ = 1; i__ <= 3; ++i__) {
11130         pm[i__ - 1] = p[i__] + q[i__];
11131         enrm += pm[i__ - 1] * pm[i__ - 1];
11132 /* L1: */
11133     }
11134     if (enrm == 0.) {
11135         goto L5;
11136     }
11137     enrm = sqrt(enrm);
11138     pm[0] /= enrm;
11139     pm[1] /= enrm;
11140     pm[2] /= enrm;
11141 
11142 /* Project P, Q, and PM to P' = (U1,V1), Q' = (U2,V2), and */
11143 /*   PM' = (UM,VM), respectively. */
11144 
11145     u1 = p[1];
11146     v1 = p[2];
11147     u2 = q[1];
11148     v2 = q[2];
11149     um = pm[0];
11150     vm = pm[1];
11151 
11152 /* Compute the orthogonal distance ERR from PM' to the line */
11153 /*   defined by P' and Q'.  This is the maximum deviation */
11154 /*   between the projected arc and the line segment.  It is */
11155 /*   undefined if P' = Q'. */
11156 
11157     du = u2 - u1;
11158     dv = v2 - v1;
11159     enrm = du * du + dv * dv;
11160     if (enrm == 0.) {
11161         goto L5;
11162     }
11163     err = (d__1 = du * (vm - v1) - (um - u1) * dv, abs(d__1)) / sqrt(enrm);
11164 
11165 /* Compute the number of arcs into which P-Q will be parti- */
11166 /*   tioned (the number of line segments to be drawn): */
11167 /*   NA = ERR/TOL. */
11168 
11169     na = (int) (err / *tol + 1.);
11170 
11171 /* Initialize for loop on arcs P1-P2, where the intermediate */
11172 /*   points are obtained by normalizing PM = P + k*DP for */
11173 /*   DP = (Q-P)/NA */
11174 
11175     s = 1. / (double) na;
11176     for (i__ = 1; i__ <= 3; ++i__) {
11177         dp[i__ - 1] = s * (q[i__] - p[i__]);
11178         pm[i__ - 1] = p[i__];
11179         p1[i__ - 1] = p[i__];
11180 /* L2: */
11181     }
11182 
11183 /* Loop on arcs P1-P2, drawing the line segments associated */
11184 /*   with the projected endpoints. */
11185 
11186     i__1 = na - 1;
11187     for (k = 1; k <= i__1; ++k) {
11188         enrm = 0.;
11189         for (i__ = 1; i__ <= 3; ++i__) {
11190             pm[i__ - 1] += dp[i__ - 1];
11191             enrm += pm[i__ - 1] * pm[i__ - 1];
11192 /* L3: */
11193         }
11194         if (enrm == 0.) {
11195             goto L5;
11196         }
11197         enrm = sqrt(enrm);
11198         p2[0] = pm[0] / enrm;
11199         p2[1] = pm[1] / enrm;
11200         p2[2] = pm[2] / enrm;
11201 /*        WRITE (LUN,100,ERR=5) P1(1), P1(2), P2(1), P2(2) */
11202 /*  100   FORMAT (2F12.6,' moveto',2F12.6,' lineto') */
11203         p1[0] = p2[0];
11204         p1[1] = p2[1];
11205         p1[2] = p2[2];
11206 /* L4: */
11207     }
11208 /*      WRITE (LUN,100,ERR=5) P1(1), P1(2), Q(1), Q(2) */
11209 
11210 /* No error encountered. */
11211 
11212     *nseg = na;
11213     return 0;
11214 
11215 /* Invalid input value of P or Q. */
11216 
11217 L5:
11218     *nseg = 0;
11219     return 0;
11220 } /* drwarc_ */

int edge_ ( int *  in1,
int *  in2,
double *  x,
double *  y,
double *  z__,
int *  lwk,
int *  iwk,
int *  list,
int *  lptr,
int *  lend,
int *  ier 
)

Definition at line 11222 of file util_sparx.cpp.

References abs, ierr, left_(), optim_(), and swap_().

11225 {
11226     /* System generated locals */
11227     int i__1;
11228 
11229     /* Local variables */
11230     static int i__, n0, n1, n2;
11231     static double x0, x1, x2, y0, y1, y2, z0, z1, z2;
11232     static int nl, lp, nr;
11233     static double dp12;
11234     static int lp21, iwc, iwf, lft, lpl, iwl, nit;
11235     static double dp1l, dp2l, dp1r, dp2r;
11236     extern long int left_(double *, double *, double *, double
11237             *, double *, double *, double *, double *,
11238             double *);
11239     static int ierr;
11240     extern /* Subroutine */ int swap_(int *, int *, int *,
11241             int *, int *, int *, int *, int *);
11242     static int next, iwcp1, n1lst, iwend;
11243     extern /* Subroutine */ int optim_(double *, double *, double
11244             *, int *, int *, int *, int *, int *, int
11245             *, int *);
11246     static int n1frst;
11247 
11248 
11249 /* *********************************************************** */
11250 
11251 /*                                              From STRIPACK */
11252 /*                                            Robert J. Renka */
11253 /*                                  Dept. of Computer Science */
11254 /*                                       Univ. of North Texas */
11255 /*                                           renka@cs.unt.edu */
11256 /*                                                   07/30/98 */
11257 
11258 /*   Given a triangulation of N nodes and a pair of nodal */
11259 /* indexes IN1 and IN2, this routine swaps arcs as necessary */
11260 /* to force IN1 and IN2 to be adjacent.  Only arcs which */
11261 /* intersect IN1-IN2 are swapped out.  If a Delaunay triangu- */
11262 /* lation is input, the resulting triangulation is as close */
11263 /* as possible to a Delaunay triangulation in the sense that */
11264 /* all arcs other than IN1-IN2 are locally optimal. */
11265 
11266 /*   A sequence of calls to EDGE may be used to force the */
11267 /* presence of a set of edges defining the boundary of a non- */
11268 /* convex and/or multiply connected region, or to introduce */
11269 /* barriers into the triangulation.  Note that Subroutine */
11270 /* GETNP will not necessarily return closest nodes if the */
11271 /* triangulation has been constrained by a call to EDGE. */
11272 /* However, this is appropriate in some applications, such */
11273 /* as triangle-based interpolation on a nonconvex domain. */
11274 
11275 
11276 /* On input: */
11277 
11278 /*       IN1,IN2 = Indexes (of X, Y, and Z) in the range 1 to */
11279 /*                 N defining a pair of nodes to be connected */
11280 /*                 by an arc. */
11281 
11282 /*       X,Y,Z = Arrays of length N containing the Cartesian */
11283 /*               coordinates of the nodes. */
11284 
11285 /* The above parameters are not altered by this routine. */
11286 
11287 /*       LWK = Number of columns reserved for IWK.  This must */
11288 /*             be at least NI -- the number of arcs that */
11289 /*             intersect IN1-IN2.  (NI is bounded by N-3.) */
11290 
11291 /*       IWK = int work array of length at least 2*LWK. */
11292 
11293 /*       LIST,LPTR,LEND = Data structure defining the trian- */
11294 /*                        gulation.  Refer to Subroutine */
11295 /*                        TRMESH. */
11296 
11297 /* On output: */
11298 
11299 /*       LWK = Number of arcs which intersect IN1-IN2 (but */
11300 /*             not more than the input value of LWK) unless */
11301 /*             IER = 1 or IER = 3.  LWK = 0 if and only if */
11302 /*             IN1 and IN2 were adjacent (or LWK=0) on input. */
11303 
11304 /*       IWK = Array containing the indexes of the endpoints */
11305 /*             of the new arcs other than IN1-IN2 unless */
11306 /*             IER > 0 or LWK = 0.  New arcs to the left of */
11307 /*             IN1->IN2 are stored in the first K-1 columns */
11308 /*             (left portion of IWK), column K contains */
11309 /*             zeros, and new arcs to the right of IN1->IN2 */
11310 /*             occupy columns K+1,...,LWK.  (K can be deter- */
11311 /*             mined by searching IWK for the zeros.) */
11312 
11313 /*       LIST,LPTR,LEND = Data structure updated if necessary */
11314 /*                        to reflect the presence of an arc */
11315 /*                        connecting IN1 and IN2 unless IER > */
11316 /*                        0.  The data structure has been */
11317 /*                        altered if IER >= 4. */
11318 
11319 /*       IER = Error indicator: */
11320 /*             IER = 0 if no errors were encountered. */
11321 /*             IER = 1 if IN1 < 1, IN2 < 1, IN1 = IN2, */
11322 /*                     or LWK < 0 on input. */
11323 /*             IER = 2 if more space is required in IWK. */
11324 /*                     Refer to LWK. */
11325 /*             IER = 3 if IN1 and IN2 could not be connected */
11326 /*                     due to either an invalid data struc- */
11327 /*                     ture or collinear nodes (and floating */
11328 /*                     point error). */
11329 /*             IER = 4 if an error flag other than IER = 1 */
11330 /*                     was returned by OPTIM. */
11331 /*             IER = 5 if error flag 1 was returned by OPTIM. */
11332 /*                     This is not necessarily an error, but */
11333 /*                     the arcs other than IN1-IN2 may not */
11334 /*                     be optimal. */
11335 
11336 /*   An error message is written to the standard output unit */
11337 /* in the case of IER = 3 or IER = 4. */
11338 
11339 /* Modules required by EDGE:  LEFT, LSTPTR, OPTIM, SWAP, */
11340 /*                              SWPTST */
11341 
11342 /* Intrinsic function called by EDGE:  ABS */
11343 
11344 /* *********************************************************** */
11345 
11346 
11347 /* Local parameters: */
11348 
11349 /* DPij =     Dot product <Ni,Nj> */
11350 /* I =        DO-loop index and column index for IWK */
11351 /* IERR =     Error flag returned by Subroutine OPTIM */
11352 /* IWC =      IWK index between IWF and IWL -- NL->NR is */
11353 /*              stored in IWK(1,IWC)->IWK(2,IWC) */
11354 /* IWCP1 =    IWC + 1 */
11355 /* IWEND =    Input or output value of LWK */
11356 /* IWF =      IWK (column) index of the first (leftmost) arc */
11357 /*              which intersects IN1->IN2 */
11358 /* IWL =      IWK (column) index of the last (rightmost) are */
11359 /*              which intersects IN1->IN2 */
11360 /* LFT =      Flag used to determine if a swap results in the */
11361 /*              new arc intersecting IN1-IN2 -- LFT = 0 iff */
11362 /*              N0 = IN1, LFT = -1 implies N0 LEFT IN1->IN2, */
11363 /*              and LFT = 1 implies N0 LEFT IN2->IN1 */
11364 /* LP =       List pointer (index for LIST and LPTR) */
11365 /* LP21 =     Unused parameter returned by SWAP */
11366 /* LPL =      Pointer to the last neighbor of IN1 or NL */
11367 /* N0 =       Neighbor of N1 or node opposite NR->NL */
11368 /* N1,N2 =    Local copies of IN1 and IN2 */
11369 /* N1FRST =   First neighbor of IN1 */
11370 /* N1LST =    (Signed) last neighbor of IN1 */
11371 /* NEXT =     Node opposite NL->NR */
11372 /* NIT =      Flag or number of iterations employed by OPTIM */
11373 /* NL,NR =    Endpoints of an arc which intersects IN1-IN2 */
11374 /*              with NL LEFT IN1->IN2 */
11375 /* X0,Y0,Z0 = Coordinates of N0 */
11376 /* X1,Y1,Z1 = Coordinates of IN1 */
11377 /* X2,Y2,Z2 = Coordinates of IN2 */
11378 
11379 
11380 /* Store IN1, IN2, and LWK in local variables and test for */
11381 /*   errors. */
11382 
11383     /* Parameter adjustments */
11384     --lend;
11385     --lptr;
11386     --list;
11387     iwk -= 3;
11388     --z__;
11389     --y;
11390     --x;
11391 
11392     /* Function Body */
11393     n1 = *in1;
11394     n2 = *in2;
11395     iwend = *lwk;
11396     if (n1 < 1 || n2 < 1 || n1 == n2 || iwend < 0) {
11397         goto L31;
11398     }
11399 
11400 /* Test for N2 as a neighbor of N1.  LPL points to the last */
11401 /*   neighbor of N1. */
11402 
11403     lpl = lend[n1];
11404     n0 = (i__1 = list[lpl], abs(i__1));
11405     lp = lpl;
11406 L1:
11407     if (n0 == n2) {
11408         goto L30;
11409     }
11410     lp = lptr[lp];
11411     n0 = list[lp];
11412     if (lp != lpl) {
11413         goto L1;
11414     }
11415 
11416 /* Initialize parameters. */
11417 
11418     iwl = 0;
11419     nit = 0;
11420 
11421 /* Store the coordinates of N1 and N2. */
11422 
11423 L2:
11424     x1 = x[n1];
11425     y1 = y[n1];
11426     z1 = z__[n1];
11427     x2 = x[n2];
11428     y2 = y[n2];
11429     z2 = z__[n2];
11430 
11431 /* Set NR and NL to adjacent neighbors of N1 such that */
11432 /*   NR LEFT N2->N1 and NL LEFT N1->N2, */
11433 /*   (NR Forward N1->N2 or NL Forward N1->N2), and */
11434 /*   (NR Forward N2->N1 or NL Forward N2->N1). */
11435 
11436 /*   Initialization:  Set N1FRST and N1LST to the first and */
11437 /*     (signed) last neighbors of N1, respectively, and */
11438 /*     initialize NL to N1FRST. */
11439 
11440     lpl = lend[n1];
11441     n1lst = list[lpl];
11442     lp = lptr[lpl];
11443     n1frst = list[lp];
11444     nl = n1frst;
11445     if (n1lst < 0) {
11446         goto L4;
11447     }
11448 
11449 /*   N1 is an interior node.  Set NL to the first candidate */
11450 /*     for NR (NL LEFT N2->N1). */
11451 
11452 L3:
11453     if (left_(&x2, &y2, &z2, &x1, &y1, &z1, &x[nl], &y[nl], &z__[nl])) {
11454         goto L4;
11455     }
11456     lp = lptr[lp];
11457     nl = list[lp];
11458     if (nl != n1frst) {
11459         goto L3;
11460     }
11461 
11462 /*   All neighbors of N1 are strictly left of N1->N2. */
11463 
11464     goto L5;
11465 
11466 /*   NL = LIST(LP) LEFT N2->N1.  Set NR to NL and NL to the */
11467 /*     following neighbor of N1. */
11468 
11469 L4:
11470     nr = nl;
11471     lp = lptr[lp];
11472     nl = (i__1 = list[lp], abs(i__1));
11473     if (left_(&x1, &y1, &z1, &x2, &y2, &z2, &x[nl], &y[nl], &z__[nl])) {
11474 
11475 /*   NL LEFT N1->N2 and NR LEFT N2->N1.  The Forward tests */
11476 /*     are employed to avoid an error associated with */
11477 /*     collinear nodes. */
11478 
11479         dp12 = x1 * x2 + y1 * y2 + z1 * z2;
11480         dp1l = x1 * x[nl] + y1 * y[nl] + z1 * z__[nl];
11481         dp2l = x2 * x[nl] + y2 * y[nl] + z2 * z__[nl];
11482         dp1r = x1 * x[nr] + y1 * y[nr] + z1 * z__[nr];
11483         dp2r = x2 * x[nr] + y2 * y[nr] + z2 * z__[nr];
11484         if ((dp2l - dp12 * dp1l >= 0. || dp2r - dp12 * dp1r >= 0.) && (dp1l -
11485                 dp12 * dp2l >= 0. || dp1r - dp12 * dp2r >= 0.)) {
11486             goto L6;
11487         }
11488 
11489 /*   NL-NR does not intersect N1-N2.  However, there is */
11490 /*     another candidate for the first arc if NL lies on */
11491 /*     the line N1-N2. */
11492 
11493         if (! left_(&x2, &y2, &z2, &x1, &y1, &z1, &x[nl], &y[nl], &z__[nl])) {
11494             goto L5;
11495         }
11496     }
11497 
11498 /*   Bottom of loop. */
11499 
11500     if (nl != n1frst) {
11501         goto L4;
11502     }
11503 
11504 /* Either the triangulation is invalid or N1-N2 lies on the */
11505 /*   convex hull boundary and an edge NR->NL (opposite N1 and */
11506 /*   intersecting N1-N2) was not found due to floating point */
11507 /*   error.  Try interchanging N1 and N2 -- NIT > 0 iff this */
11508 /*   has already been done. */
11509 
11510 L5:
11511     if (nit > 0) {
11512         goto L33;
11513     }
11514     nit = 1;
11515     n1 = n2;
11516     n2 = *in1;
11517     goto L2;
11518 
11519 /* Store the ordered sequence of intersecting edges NL->NR in */
11520 /*   IWK(1,IWL)->IWK(2,IWL). */
11521 
11522 L6:
11523     ++iwl;
11524     if (iwl > iwend) {
11525         goto L32;
11526     }
11527     iwk[(iwl << 1) + 1] = nl;
11528     iwk[(iwl << 1) + 2] = nr;
11529 
11530 /*   Set NEXT to the neighbor of NL which follows NR. */
11531 
11532     lpl = lend[nl];
11533     lp = lptr[lpl];
11534 
11535 /*   Find NR as a neighbor of NL.  The search begins with */
11536 /*     the first neighbor. */
11537 
11538 L7:
11539     if (list[lp] == nr) {
11540         goto L8;
11541     }
11542     lp = lptr[lp];
11543     if (lp != lpl) {
11544         goto L7;
11545     }
11546 
11547 /*   NR must be the last neighbor, and NL->NR cannot be a */
11548 /*     boundary edge. */
11549 
11550     if (list[lp] != nr) {
11551         goto L33;
11552     }
11553 
11554 /*   Set NEXT to the neighbor following NR, and test for */
11555 /*     termination of the store loop. */
11556 
11557 L8:
11558     lp = lptr[lp];
11559     next = (i__1 = list[lp], abs(i__1));
11560     if (next == n2) {
11561         goto L9;
11562     }
11563 
11564 /*   Set NL or NR to NEXT. */
11565 
11566     if (left_(&x1, &y1, &z1, &x2, &y2, &z2, &x[next], &y[next], &z__[next])) {
11567         nl = next;
11568     } else {
11569         nr = next;
11570     }
11571     goto L6;
11572 
11573 /* IWL is the number of arcs which intersect N1-N2. */
11574 /*   Store LWK. */
11575 
11576 L9:
11577     *lwk = iwl;
11578     iwend = iwl;
11579 
11580 /* Initialize for edge swapping loop -- all possible swaps */
11581 /*   are applied (even if the new arc again intersects */
11582 /*   N1-N2), arcs to the left of N1->N2 are stored in the */
11583 /*   left portion of IWK, and arcs to the right are stored in */
11584 /*   the right portion.  IWF and IWL index the first and last */
11585 /*   intersecting arcs. */
11586 
11587     iwf = 1;
11588 
11589 /* Top of loop -- set N0 to N1 and NL->NR to the first edge. */
11590 /*   IWC points to the arc currently being processed.  LFT */
11591 /*   .LE. 0 iff N0 LEFT N1->N2. */
11592 
11593 L10:
11594     lft = 0;
11595     n0 = n1;
11596     x0 = x1;
11597     y0 = y1;
11598     z0 = z1;
11599     nl = iwk[(iwf << 1) + 1];
11600     nr = iwk[(iwf << 1) + 2];
11601     iwc = iwf;
11602 
11603 /*   Set NEXT to the node opposite NL->NR unless IWC is the */
11604 /*     last arc. */
11605 
11606 L11:
11607     if (iwc == iwl) {
11608         goto L21;
11609     }
11610     iwcp1 = iwc + 1;
11611     next = iwk[(iwcp1 << 1) + 1];
11612     if (next != nl) {
11613         goto L16;
11614     }
11615     next = iwk[(iwcp1 << 1) + 2];
11616 
11617 /*   NEXT RIGHT N1->N2 and IWC .LT. IWL.  Test for a possible */
11618 /*     swap. */
11619 
11620     if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x[next], &y[next], &
11621             z__[next])) {
11622         goto L14;
11623     }
11624     if (lft >= 0) {
11625         goto L12;
11626     }
11627     if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x[next], &y[next], &
11628             z__[next])) {
11629         goto L14;
11630     }
11631 
11632 /*   Replace NL->NR with N0->NEXT. */
11633 
11634     swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11635     iwk[(iwc << 1) + 1] = n0;
11636     iwk[(iwc << 1) + 2] = next;
11637     goto L15;
11638 
11639 /*   Swap NL-NR for N0-NEXT, shift columns IWC+1,...,IWL to */
11640 /*     the left, and store N0-NEXT in the right portion of */
11641 /*     IWK. */
11642 
11643 L12:
11644     swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11645     i__1 = iwl;
11646     for (i__ = iwcp1; i__ <= i__1; ++i__) {
11647         iwk[(i__ - (1<<1)) + 1] = iwk[(i__ << 1) + 1];
11648         iwk[(i__ - (1<<1)) + 2] = iwk[(i__ << 1) + 2];
11649 /* L13: */
11650     }
11651     iwk[(iwl << 1) + 1] = n0;
11652     iwk[(iwl << 1) + 2] = next;
11653     --iwl;
11654     nr = next;
11655     goto L11;
11656 
11657 /*   A swap is not possible.  Set N0 to NR. */
11658 
11659 L14:
11660     n0 = nr;
11661     x0 = x[n0];
11662     y0 = y[n0];
11663     z0 = z__[n0];
11664     lft = 1;
11665 
11666 /*   Advance to the next arc. */
11667 
11668 L15:
11669     nr = next;
11670     ++iwc;
11671     goto L11;
11672 
11673 /*   NEXT LEFT N1->N2, NEXT .NE. N2, and IWC .LT. IWL. */
11674 /*     Test for a possible swap. */
11675 
11676 L16:
11677     if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x[next], &y[next], &
11678             z__[next])) {
11679         goto L19;
11680     }
11681     if (lft <= 0) {
11682         goto L17;
11683     }
11684     if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x[next], &y[next], &
11685             z__[next])) {
11686         goto L19;
11687     }
11688 
11689 /*   Replace NL->NR with NEXT->N0. */
11690 
11691     swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11692     iwk[(iwc << 1) + 1] = next;
11693     iwk[(iwc << 1) + 2] = n0;
11694     goto L20;
11695 
11696 /*   Swap NL-NR for N0-NEXT, shift columns IWF,...,IWC-1 to */
11697 /*     the right, and store N0-NEXT in the left portion of */
11698 /*     IWK. */
11699 
11700 L17:
11701     swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11702     i__1 = iwf;
11703     for (i__ = iwc - 1; i__ >= i__1; --i__) {
11704         iwk[(i__ + (1<<1)) + 1] = iwk[(i__ << 1) + 1];
11705         iwk[(i__ + (1<<1)) + 2] = iwk[(i__ << 1) + 2];
11706 /* L18: */
11707     }
11708     iwk[(iwf << 1) + 1] = n0;
11709     iwk[(iwf << 1) + 2] = next;
11710     ++iwf;
11711     goto L20;
11712 
11713 /*   A swap is not possible.  Set N0 to NL. */
11714 
11715 L19:
11716     n0 = nl;
11717     x0 = x[n0];
11718     y0 = y[n0];
11719     z0 = z__[n0];
11720     lft = -1;
11721 
11722 /*   Advance to the next arc. */
11723 
11724 L20:
11725     nl = next;
11726     ++iwc;
11727     goto L11;
11728 
11729 /*   N2 is opposite NL->NR (IWC = IWL). */
11730 
11731 L21:
11732     if (n0 == n1) {
11733         goto L24;
11734     }
11735     if (lft < 0) {
11736         goto L22;
11737     }
11738 
11739 /*   N0 RIGHT N1->N2.  Test for a possible swap. */
11740 
11741     if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x2, &y2, &z2)) {
11742         goto L10;
11743     }
11744 
11745 /*   Swap NL-NR for N0-N2 and store N0-N2 in the right */
11746 /*     portion of IWK. */
11747 
11748     swap_(&n2, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11749     iwk[(iwl << 1) + 1] = n0;
11750     iwk[(iwl << 1) + 2] = n2;
11751     --iwl;
11752     goto L10;
11753 
11754 /*   N0 LEFT N1->N2.  Test for a possible swap. */
11755 
11756 L22:
11757     if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x2, &y2, &z2)) {
11758         goto L10;
11759     }
11760 
11761 /*   Swap NL-NR for N0-N2, shift columns IWF,...,IWL-1 to the */
11762 /*     right, and store N0-N2 in the left portion of IWK. */
11763 
11764     swap_(&n2, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11765     i__ = iwl;
11766 L23:
11767     iwk[(i__ << 1) + 1] = iwk[(i__ - (1<<1)) + 1];
11768     iwk[(i__ << 1) + 2] = iwk[(i__ - (1<<1)) + 2];
11769     --i__;
11770     if (i__ > iwf) {
11771         goto L23;
11772     }
11773     iwk[(iwf << 1) + 1] = n0;
11774     iwk[(iwf << 1) + 2] = n2;
11775     ++iwf;
11776     goto L10;
11777 
11778 /* IWF = IWC = IWL.  Swap out the last arc for N1-N2 and */
11779 /*   store zeros in IWK. */
11780 
11781 L24:
11782     swap_(&n2, &n1, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21);
11783     iwk[(iwc << 1) + 1] = 0;
11784     iwk[(iwc << 1) + 2] = 0;
11785 
11786 /* Optimization procedure -- */
11787 
11788     *ier = 0;
11789     if (iwc > 1) {
11790 
11791 /*   Optimize the set of new arcs to the left of IN1->IN2. */
11792 
11793         nit = iwc - (1<<2);
11794         i__1 = iwc - 1;
11795         optim_(&x[1], &y[1], &z__[1], &i__1, &list[1], &lptr[1], &lend[1], &
11796                 nit, &iwk[3], &ierr);
11797         if (ierr != 0 && ierr != 1) {
11798             goto L34;
11799         }
11800         if (ierr == 1) {
11801             *ier = 5;
11802         }
11803     }
11804     if (iwc < iwend) {
11805 
11806 /*   Optimize the set of new arcs to the right of IN1->IN2. */
11807 
11808         nit = iwend - (iwc<<2);
11809         i__1 = iwend - iwc;
11810         optim_(&x[1], &y[1], &z__[1], &i__1, &list[1], &lptr[1], &lend[1], &
11811                 nit, &iwk[(iwc + (1<<1)) + 1], &ierr);
11812         if (ierr != 0 && ierr != 1) {
11813             goto L34;
11814         }
11815         if (ierr == 1) {
11816             goto L35;
11817         }
11818     }
11819     if (*ier == 5) {
11820         goto L35;
11821     }
11822 
11823 /* Successful termination (IER = 0). */
11824 
11825     return 0;
11826 
11827 /* IN1 and IN2 were adjacent on input. */
11828 
11829 L30:
11830     *ier = 0;
11831     return 0;
11832 
11833 /* Invalid input parameter. */
11834 
11835 L31:
11836     *ier = 1;
11837     return 0;
11838 
11839 /* Insufficient space reserved for IWK. */
11840 
11841 L32:
11842     *ier = 2;
11843     return 0;
11844 
11845 /* Invalid triangulation data structure or collinear nodes */
11846 /*   on convex hull boundary. */
11847 
11848 L33:
11849     *ier = 3;
11850 /*      WRITE (*,130) IN1, IN2 */
11851 /*  130 FORMAT (//5X,'*** Error in EDGE:  Invalid triangula', */
11852 /*     .        'tion or null triangles on boundary'/ */
11853 /*     .        9X,'IN1 =',I4,', IN2=',I4/) */
11854     return 0;
11855 
11856 /* Error flag (other than 1) returned by OPTIM. */
11857 
11858 L34:
11859     *ier = 4;
11860 /*      WRITE (*,140) NIT, IERR */
11861 /*  140 FORMAT (//5X,'*** Error in OPTIM (called from EDGE):', */
11862 /*     .        '  NIT = ',I4,', IER = ',I1,' ***'/) */
11863     return 0;
11864 
11865 /* Error flag 1 returned by OPTIM. */
11866 
11867 L35:
11868     *ier = 5;
11869     return 0;
11870 } /* edge_ */

int find_group ( int  ix,
int  iy,
int  iz,
int  grpid,
EMData mg,
EMData visited 
)

Definition at line 18696 of file util_sparx.cpp.

References EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), nx, ny, and EMAN::EMData::set_value_at().

Referenced by EMAN::Util::get_biggest_cluster().

18697 {
18698         int offs[][3] = { {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} };
18699         int noff = 6;
18700 
18701         int nx = visited->get_xsize();
18702         int ny = visited->get_ysize();
18703         int nz = visited->get_zsize();
18704 
18705         vector< point3d_t > pts;
18706         pts.push_back( point3d_t(ix, iy, iz) );
18707         visited->set_value_at( ix, iy, iz, (float)grpid );
18708 
18709         int start = 0;
18710         int end = pts.size();
18711 
18712         while( end > start ) {
18713                 for(int i=start; i < end; ++i ) {
18714                         int ix = pts[i].x;
18715                         int iy = pts[i].y;
18716                         int iz = pts[i].z;
18717 
18718                         for( int j=0; j < noff; ++j ) {
18719                                 int jx = ix + offs[j][0];
18720                                 int jy = iy + offs[j][1];
18721                                 int jz = iz + offs[j][2];
18722 
18723                                 if( jx < 0 || jx >= nx ) continue;
18724                                 if( jy < 0 || jy >= ny ) continue;
18725                                 if( jz < 0 || jz >= nz ) continue;
18726 
18727 
18728                                 if( (*mg)(jx, jy, jz)>0 && (*visited)(jx, jy, jz)==0.0 ) {
18729                                     pts.push_back( point3d_t(jx, jy, jz) );
18730                                     visited->set_value_at( jx, jy, jz, (float)grpid );
18731                                 }
18732 
18733                         }
18734                 }
18735 
18736                 start = end;
18737                 end = pts.size();
18738         }
18739         return pts.size();
18740 }

int getnp_ ( double *  x,
double *  y,
double *  z__,
int *  list,
int *  lptr,
int *  lend,
int *  l,
int *  npts,
double *  df,
int *  ier 
)

Definition at line 11872 of file util_sparx.cpp.

References abs.

11875 {
11876     /* System generated locals */
11877     int i__1, i__2;
11878 
11879     /* Local variables */
11880     static int i__, n1;
11881     static double x1, y1, z1;
11882     static int nb, ni, lp, np, lm1;
11883     static double dnb, dnp;
11884     static int lpl;
11885 
11886 
11887 /* *********************************************************** */
11888 
11889 /*                                              From STRIPACK */
11890 /*                                            Robert J. Renka */
11891 /*                                  Dept. of Computer Science */
11892 /*                                       Univ. of North Texas */
11893 /*                                           renka@cs.unt.edu */
11894 /*                                                   07/28/98 */
11895 
11896 /*   Given a Delaunay triangulation of N nodes on the unit */
11897 /* sphere and an array NPTS containing the indexes of L-1 */
11898 /* nodes ordered by angular distance from NPTS(1), this sub- */
11899 /* routine sets NPTS(L) to the index of the next node in the */
11900 /* sequence -- the node, other than NPTS(1),...,NPTS(L-1), */
11901 /* that is closest to NPTS(1).  Thus, the ordered sequence */
11902 /* of K closest nodes to N1 (including N1) may be determined */
11903 /* by K-1 calls to GETNP with NPTS(1) = N1 and L = 2,3,...,K */
11904 /* for K .GE. 2. */
11905 
11906 /*   The algorithm uses the property of a Delaunay triangula- */
11907 /* tion that the K-th closest node to N1 is a neighbor of one */
11908 /* of the K-1 closest nodes to N1. */
11909 
11910 
11911 /* On input: */
11912 
11913 /*       X,Y,Z = Arrays of length N containing the Cartesian */
11914 /*               coordinates of the nodes. */
11915 
11916 /*       LIST,LPTR,LEND = Triangulation data structure.  Re- */
11917 /*                        fer to Subroutine TRMESH. */
11918 
11919 /*       L = Number of nodes in the sequence on output.  2 */
11920 /*           .LE. L .LE. N. */
11921 
11922 /* The above parameters are not altered by this routine. */
11923 
11924 /*       NPTS = Array of length .GE. L containing the indexes */
11925 /*              of the L-1 closest nodes to NPTS(1) in the */
11926 /*              first L-1 locations. */
11927 
11928 /* On output: */
11929 
11930 /*       NPTS = Array updated with the index of the L-th */
11931 /*              closest node to NPTS(1) in position L unless */
11932 /*              IER = 1. */
11933 
11934 /*       DF = Value of an increasing function (negative cos- */
11935 /*            ine) of the angular distance between NPTS(1) */
11936 /*            and NPTS(L) unless IER = 1. */
11937 
11938 /*       IER = Error indicator: */
11939 /*             IER = 0 if no errors were encountered. */
11940 /*             IER = 1 if L < 2. */
11941 
11942 /* Modules required by GETNP:  None */
11943 
11944 /* Intrinsic function called by GETNP:  ABS */
11945 
11946 /* *********************************************************** */
11947 
11948 
11949 /* Local parameters: */
11950 
11951 /* DNB,DNP =  Negative cosines of the angular distances from */
11952 /*              N1 to NB and to NP, respectively */
11953 /* I =        NPTS index and DO-loop index */
11954 /* LM1 =      L-1 */
11955 /* LP =       LIST pointer of a neighbor of NI */
11956 /* LPL =      Pointer to the last neighbor of NI */
11957 /* N1 =       NPTS(1) */
11958 /* NB =       Neighbor of NI and candidate for NP */
11959 /* NI =       NPTS(I) */
11960 /* NP =       Candidate for NPTS(L) */
11961 /* X1,Y1,Z1 = Coordinates of N1 */
11962 
11963     /* Parameter adjustments */
11964     --x;
11965     --y;
11966     --z__;
11967     --list;
11968     --lptr;
11969     --lend;
11970     --npts;
11971 
11972     /* Function Body */
11973     lm1 = *l - 1;
11974     if (lm1 < 1) {
11975         goto L6;
11976     }
11977     *ier = 0;
11978 
11979 /* Store N1 = NPTS(1) and mark the elements of NPTS. */
11980 
11981     n1 = npts[1];
11982     x1 = x[n1];
11983     y1 = y[n1];
11984     z1 = z__[n1];
11985     i__1 = lm1;
11986     for (i__ = 1; i__ <= i__1; ++i__) {
11987         ni = npts[i__];
11988         lend[ni] = -lend[ni];
11989 /* L1: */
11990     }
11991 
11992 /* Candidates for NP = NPTS(L) are the unmarked neighbors */
11993 /*   of nodes in NPTS.  DNP is initially greater than -cos(PI) */
11994 /*   (the maximum distance). */
11995 
11996     dnp = 2.;
11997 
11998 /* Loop on nodes NI in NPTS. */
11999 
12000     i__1 = lm1;
12001     for (i__ = 1; i__ <= i__1; ++i__) {
12002         ni = npts[i__];
12003         lpl = -lend[ni];
12004         lp = lpl;
12005 
12006 /* Loop on neighbors NB of NI. */
12007 
12008 L2:
12009         nb = (i__2 = list[lp], abs(i__2));
12010         if (lend[nb] < 0) {
12011             goto L3;
12012         }
12013 
12014 /* NB is an unmarked neighbor of NI.  Replace NP if NB is */
12015 /*   closer to N1. */
12016 
12017         dnb = -(x[nb] * x1 + y[nb] * y1 + z__[nb] * z1);
12018         if (dnb >= dnp) {
12019             goto L3;
12020         }
12021         np = nb;
12022         dnp = dnb;
12023 L3:
12024         lp = lptr[lp];
12025         if (lp != lpl) {
12026             goto L2;
12027         }
12028 /* L4: */
12029     }
12030     npts[*l] = np;
12031     *df = dnp;
12032 
12033 /* Unmark the elements of NPTS. */
12034 
12035     i__1 = lm1;
12036     for (i__ = 1; i__ <= i__1; ++i__) {
12037         ni = npts[i__];
12038         lend[ni] = -lend[ni];
12039 /* L5: */
12040     }
12041     return 0;
12042 
12043 /* L is outside its valid range. */
12044 
12045 L6:
12046     *ier = 1;
12047     return 0;
12048 } /* getnp_ */

int i_dnnt ( double *  x  ) 

Definition at line 7512 of file util_sparx.cpp.

Referenced by trplot_(), and vrplot_().

07514 {
07515         return (int)(*x >= 0. ? floor(*x + .5) : -floor(.5 - *x));
07516 }

int insert_ ( int *  k,
int *  lp,
int *  list,
int *  lptr,
int *  lnew 
)

Definition at line 12050 of file util_sparx.cpp.

Referenced by bdyadd_(), covsph_(), and intadd_().

12052 {
12053     static int lsav;
12054 
12055 
12056 /* *********************************************************** */
12057 
12058 /*                                              From STRIPACK */
12059 /*                                            Robert J. Renka */
12060 /*                                  Dept. of Computer Science */
12061 /*                                       Univ. of North Texas */
12062 /*                                           renka@cs.unt.edu */
12063 /*                                                   07/17/96 */
12064 
12065 /*   This subroutine inserts K as a neighbor of N1 following */
12066 /* N2, where LP is the LIST pointer of N2 as a neighbor of */
12067 /* N1.  Note that, if N2 is the last neighbor of N1, K will */
12068 /* become the first neighbor (even if N1 is a boundary node). */
12069 
12070 /*   This routine is identical to the similarly named routine */
12071 /* in TRIPACK. */
12072 
12073 
12074 /* On input: */
12075 
12076 /*       K = Index of the node to be inserted. */
12077 
12078 /*       LP = LIST pointer of N2 as a neighbor of N1. */
12079 
12080 /* The above parameters are not altered by this routine. */
12081 
12082 /*       LIST,LPTR,LNEW = Data structure defining the trian- */
12083 /*                        gulation.  Refer to Subroutine */
12084 /*                        TRMESH. */
12085 
12086 /* On output: */
12087 
12088 /*       LIST,LPTR,LNEW = Data structure updated with the */
12089 /*                        addition of node K. */
12090 
12091 /* Modules required by INSERT:  None */
12092 
12093 /* *********************************************************** */
12094 
12095 
12096     /* Parameter adjustments */
12097     --lptr;
12098     --list;
12099 
12100     /* Function Body */
12101     lsav = lptr[*lp];
12102     lptr[*lp] = *lnew;
12103     list[*lnew] = *k;
12104     lptr[*lnew] = lsav;
12105     ++(*lnew);
12106     return 0;
12107 } /* insert_ */

long int inside_ ( double *  p,
int *  lv,
double *  xv,
double *  yv,
double *  zv,
int *  nv,
int *  listv,
int *  ier 
)

Definition at line 12109 of file util_sparx.cpp.

References b, ierr, intrsc_(), q, sqrt(), and TRUE_.

12111 {
12112     /* Initialized data */
12113 
12114     static double eps = .001;
12115 
12116     /* System generated locals */
12117     int i__1;
12118     long int ret_val = 0;
12119 
12120     /* Builtin functions */
12121     //double sqrt(double);
12122 
12123     /* Local variables */
12124     static double b[3], d__;
12125     static int k, n;
12126     static double q[3];
12127     static int i1, i2, k0;
12128     static double v1[3], v2[3], cn[3], bp, bq;
12129     static int ni;
12130     static double pn[3], qn[3], vn[3];
12131     static int imx;
12132     static long int lft1, lft2, even;
12133     static int ierr;
12134     static long int pinr, qinr;
12135     static double qnrm, vnrm;
12136     extern /* Subroutine */ int intrsc_(double *, double *,
12137             double *, double *, int *);
12138 
12139 
12140 /* *********************************************************** */
12141 
12142 /*                                              From STRIPACK */
12143 /*                                            Robert J. Renka */
12144 /*                                  Dept. of Computer Science */
12145 /*                                       Univ. of North Texas */
12146 /*                                           renka@cs.unt.edu */
12147 /*                                                   12/27/93 */
12148 
12149 /*   This function locates a point P relative to a polygonal */
12150 /* region R on the surface of the unit sphere, returning */
12151 /* INSIDE = TRUE if and only if P is contained in R.  R is */
12152 /* defined by a cyclically ordered sequence of vertices which */
12153 /* form a positively-oriented simple closed curve.  Adjacent */
12154 /* vertices need not be distinct but the curve must not be */
12155 /* self-intersecting.  Also, while polygon edges are by defi- */
12156 /* nition restricted to a single hemisphere, R is not so */
12157 /* restricted.  Its interior is the region to the left as the */
12158 /* vertices are traversed in order. */
12159 
12160 /*   The algorithm consists of selecting a point Q in R and */
12161 /* then finding all points at which the great circle defined */
12162 /* by P and Q intersects the boundary of R.  P lies inside R */
12163 /* if and only if there is an even number of intersection */
12164 /* points between Q and P.  Q is taken to be a point immedi- */
12165 /* ately to the left of a directed boundary edge -- the first */
12166 /* one that results in no consistency-check failures. */
12167 
12168 /*   If P is close to the polygon boundary, the problem is */
12169 /* ill-conditioned and the decision may be incorrect.  Also, */
12170 /* an incorrect decision may result from a poor choice of Q */
12171 /* (if, for example, a boundary edge lies on the great cir- */
12172 /* cle defined by P and Q).  A more reliable result could be */
12173 /* obtained by a sequence of calls to INSIDE with the ver- */
12174 /* tices cyclically permuted before each call (to alter the */
12175 /* choice of Q). */
12176 
12177 
12178 /* On input: */
12179 
12180 /*       P = Array of length 3 containing the Cartesian */
12181 /*           coordinates of the point (unit vector) to be */
12182 /*           located. */
12183 
12184 /*       LV = Length of arrays XV, YV, and ZV. */
12185 
12186 /*       XV,YV,ZV = Arrays of length LV containing the Carte- */
12187 /*                  sian coordinates of unit vectors (points */
12188 /*                  on the unit sphere).  These values are */
12189 /*                  not tested for validity. */
12190 
12191 /*       NV = Number of vertices in the polygon.  3 .LE. NV */
12192 /*            .LE. LV. */
12193 
12194 /*       LISTV = Array of length NV containing the indexes */
12195 /*               (for XV, YV, and ZV) of a cyclically-ordered */
12196 /*               (and CCW-ordered) sequence of vertices that */
12197 /*               define R.  The last vertex (indexed by */
12198 /*               LISTV(NV)) is followed by the first (indexed */
12199 /*               by LISTV(1)).  LISTV entries must be in the */
12200 /*               range 1 to LV. */
12201 
12202 /* Input parameters are not altered by this function. */
12203 
12204 /* On output: */
12205 
12206 /*       INSIDE = TRUE if and only if P lies inside R unless */
12207 /*                IER .NE. 0, in which case the value is not */
12208 /*                altered. */
12209 
12210 /*       IER = Error indicator: */
12211 /*             IER = 0 if no errors were encountered. */
12212 /*             IER = 1 if LV or NV is outside its valid */
12213 /*                     range. */
12214 /*             IER = 2 if a LISTV entry is outside its valid */
12215 /*                     range. */
12216 /*             IER = 3 if the polygon boundary was found to */
12217 /*                     be self-intersecti