#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>

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 abs | ( | x | ) | ((x) >= 0 ? (x) : -(x)) |
Definition at line 7502 of file util_sparx.cpp.
| #define AMAX1 | ( | i, | |||
| j | ) | i>j?i:j |
| #define AMIN1 | ( | i, | |||
| j | ) | i<j?i:j |
| #define assign | ( | i | ) | out[i] |
| #define B | ( | i, | |||
| j | ) | Bptr[i-1+((j-1)*NSAM)] |
Definition at line 5463 of file util_sparx.cpp.
Referenced by EMAN::Util::BPCQ(), EMAN::Util::histc(), EMAN::Util::im_diff(), and submatrix().
| #define b | ( | i | ) | b[i-1] |
Definition at line 3189 of file util_sparx.cpp.
| #define b | ( | i | ) | b[i-1] |
Definition at line 3189 of file util_sparx.cpp.
Referenced by EMAN::CtfCWautoAverager::add_image(), bmv_(), EMAN::Util::cml_line_insino(), EMAN::Util::cml_line_insino_all(), EMAN::OptVarianceCmp::cmp(), Derivatives(), Derivatives_G(), dpmeps_(), formk_(), GCVmin_Tik(), EMAN::TetrahedralSym::get_asym_unit_points(), EMAN::PlatonicSym::get_asym_unit_points(), EMAN::HSym::get_asym_unit_points(), EMAN::EMUtil::get_euler_names(), inside_(), EMAN::Matrix4::inverse(), main(), EMAN::Matrix4::operator*(), EMAN::Quaternion::operator*=(), EMAN::Quaternion::operator/=(), EMAN::Util::prb1d(), prb1d(), EMAN::TestImageEllipse::process_inplace(), EMAN::TestImageGradient::process_inplace(), EMAN::NormalizeToLeastSquareProcessor::process_inplace(), EMAN::GradientRemoverProcessor::process_inplace(), EMAN::Util::splint(), subsm_(), and varmx().
| #define bi | ( | i | ) | bi[i-1] |
Definition at line 2642 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), and EMAN::TestImageEllipse::process_inplace().
| #define br | ( | i | ) | br[i-1] |
Definition at line 2641 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::EMData::render_amp24(), and EMAN::EMData::render_ap24().
| #define CC | ( | i | ) | CC [i-1] |
| #define cent | ( | i | ) | out[i+N] |
| #define circ | ( | i | ) | circ[i-1] |
Definition at line 2159 of file util_sparx.cpp.
Referenced by EMAN::Util::alrl_ms(), alrq(), alrq_ms(), applyws(), EMAN::Util::Frngs(), frngs(), EMAN::Util::Frngs_inv(), EMAN::Util::Polar2D(), EMAN::Util::Polar2Dm(), and EMAN::Util::Polar2Dmi().
| #define circ1 | ( | i | ) | circ1[i-1] |
Definition at line 3185 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ns(), and EMAN::Util::Crosrng_sm_psi().
| #define circ1b | ( | i | ) | circ1b[i-1] |
Definition at line 3912 of file util_sparx.cpp.
| #define circ1b | ( | i | ) | circ1b[i-1] |
Definition at line 3912 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), and EMAN::Util::Crosrng_msg_vec().
| #define circ2 | ( | i | ) | circ2[i-1] |
Definition at line 3186 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ns(), and EMAN::Util::Crosrng_sm_psi().
| #define circ2b | ( | i | ) | circ2b[i-1] |
Definition at line 3913 of file util_sparx.cpp.
| #define circ2b | ( | i | ) | circ2b[i-1] |
Definition at line 3913 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), and EMAN::Util::Crosrng_msg_vec().
| #define CP | ( | i | ) | CP [i-1] |
| #define CUBE | ( | i, | |||
| j, | |||||
| k | ) | CUBEptr[(i-1)+((j-1)+((k-1)*NY3D))*NX3D] |
| #define data | ( | i, | |||
| j | ) | 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 |
Definition at line 4322 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_init_rot(), EMAN::Util::cml_line_in3d(), and EMAN::Util::cml_update_rot().
| #define deg_to_rad quadpi/180 |
Definition at line 6793 of file util_sparx.cpp.
| #define dgr_to_rad quadpi/180 |
Definition at line 6792 of file util_sparx.cpp.
Referenced by EMAN::Util::ang_to_xyz(), apmq(), aprq2d(), EMAN::Util::even_angles(), and EMAN::ChaoProjector::setdm().
| #define DGR_TO_RAD QUADPI/180 |
Definition at line 5415 of file util_sparx.cpp.
| #define DM | ( | I | ) | DM[I-1] |
Definition at line 5462 of file util_sparx.cpp.
| #define DM | ( | I | ) | DM [I-1] |
Definition at line 5462 of file util_sparx.cpp.
Referenced by EMAN::Util::BPCQ(), and EMAN::Util::CANG().
| #define dout | ( | i, | |||
| j | ) | dout[i+maxrin*j] |
Definition at line 3911 of file util_sparx.cpp.
| #define dout | ( | i, | |||
| j | ) | dout[i+maxrin*j] |
Definition at line 3911 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), and EMAN::Util::Crosrng_msg_s().
| #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, | |||
| j | ) | fdata[ i-1 + (j-1)*nxdata ] |
Definition at line 709 of file util_sparx.cpp.
| #define fdata | ( | i, | |||
| j | ) | 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().
Definition at line 18550 of file util_sparx.cpp.
Referenced by EMAN::Util::addn_img(), EMAN::Util::divn_filter(), EMAN::Util::divn_img(), EMAN::Util::madn_scalar(), EMAN::Util::move_points(), EMAN::Util::muln_img(), EMAN::Util::mult_scalar(), and EMAN::Util::subn_img().
Definition at line 18549 of file util_sparx.cpp.
| #define img_ptr | ( | i, | |||
| j, | |||||
| k | ) | img_ptr[2*(i-1)+((j-1)+((k-1)*ny))*nxo] |
Definition at line 18549 of file util_sparx.cpp.
Referenced by EMAN::Util::add_img(), EMAN::Util::add_img2(), EMAN::Util::addn_img(), EMAN::Util::compress_image_mask(), EMAN::Util::div_filter(), EMAN::Util::div_img(), EMAN::Util::divn_filter(), EMAN::Util::divn_img(), EMAN::Util::hist_comp_freq(), EMAN::Util::mad_scalar(), EMAN::Util::madn_scalar(), EMAN::Util::move_points(), EMAN::Util::mul_img(), EMAN::Util::mul_scalar(), EMAN::Util::muln_img(), EMAN::Util::mult_scalar(), EMAN::Util::pack_complex_to_real(), ReadStackandDist(), ReadStackandDist_Cart(), EMAN::Util::reconstitute_image_mask(), EMAN::Util::set_line(), EMAN::Util::sub_img(), and EMAN::Util::subn_img().
Definition at line 5049 of file util_sparx.cpp.
Definition at line 5049 of file util_sparx.cpp.
Referenced by EMAN::Util::pad(), and EMAN::Util::window().
| #define key | ( | i | ) | key [i-1] |
Definition at line 6806 of file util_sparx.cpp.
Referenced by EMAN::Dict::get(), EMAN::Util::hsortd(), mpi_comm_split(), EMAN::Log::vlog(), EMAN::Util::voronoi(), and EMAN::Util::vrdg().
| #define lband | ( | i | ) | lband [i-1] |
Definition at line 6803 of file util_sparx.cpp.
| #define mymax | ( | x, | |||
| y | ) | (((x)>(y))?(x):(y)) |
Definition at line 6786 of file util_sparx.cpp.
| #define mymin | ( | x, | |||
| y | ) | (((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] |
Definition at line 4945 of file util_sparx.cpp.
Referenced by EMAN::Util::compress_image_mask(), EMAN::Util::decimate(), and EMAN::Util::reconstitute_image_mask().
| #define numr | ( | i, | |||
| j | ) | numr[(j-1)*3 + i-1] |
Definition at line 2160 of file util_sparx.cpp.
Referenced by ali3d_d(), alprbs(), EMAN::Util::alrl_ms(), alrq(), alrq_ms(), apmd(), apmq(), applyws(), apring1(), aprq2d(), 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_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_sm_psi(), EMAN::Util::ener(), EMAN::Util::ener_tot(), EMAN::Util::Frngs(), frngs(), EMAN::Util::Frngs_inv(), numrinit(), Numrinit(), EMAN::Util::Polar2D(), EMAN::Util::Polar2Dm(), EMAN::Util::Polar2Dmi(), ringwe(), EMAN::Util::sub_fav(), and EMAN::Util::update_fav().
| #define outp | ( | i, | |||
| j, | |||||
| k | ) | 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, | |||||
| k | ) | 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 | ( | i | ) | phi [i-1] |
Definition at line 6801 of file util_sparx.cpp.
Referenced by EMAN::file_store::add_image(), EMAN::OrientationGenerator::add_orientation(), ali3d_d(), EMAN::Refine3DAligner::align(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), EMAN::Util::even_angles(), fcalc(), fgcalc(), EMAN::RandomOrientationGenerator::gen_orientations(), EMAN::file_store::get_image(), EMAN::Transform3D::get_rotation(), EMAN::Transform::get_rotation(), EMAN::Util::hsortd(), LBD_Cart(), main(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::TestImageSinewave::process_inplace(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), recons3d_4nn(), recons3d_CGLS_mpi_Cart(), recons3d_HyBR_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), refalifn3d(), EMAN::Transform3D::set_rotation(), EMAN::Transform::set_rotation(), EMAN::ChaoProjector::setdm(), slaed4_(), trans_(), unified(), EMAN::Util::vrdg(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
| #define PI2 QUADPI*2 |
Definition at line 4321 of file util_sparx.cpp.
| #define PI2 2*QUADPI |
Definition at line 4321 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_weights(), EMAN::Util::ener(), EMAN::Util::ener_tot(), EMAN::Util::sub_fav(), and EMAN::Util::update_fav().
| #define PROJ | ( | i, | |||
| j | ) | PROJptr [i-1+((j-1)*NNNN)] |
Definition at line 5610 of file util_sparx.cpp.
| #define PROJ | ( | i, | |||
| j | ) | 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 | ( | i | ) | q[i-1] |
Definition at line 3188 of file util_sparx.cpp.
Referenced by EMAN::Util::cluster_pairwise(), EMAN::Quaternion::create_inverse(), EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_sm_psi(), dcstep_(), GCVmin_Tik(), EMAN::EMData::get_pixel_conv(), EMAN::EMData::get_pixel_filtered(), EMAN::Util::getBaldwinGridWeights(), inside_(), EMAN::Quaternion::interpolate(), EMAN::operator*(), EMAN::operator+(), EMAN::operator-(), EMAN::operator/(), EMAN::Util::pw_extract(), EMAN::Quaternion::Quaternion(), recons3d_CGLS_mpi_Cart(), refalin3d_perturb(), EMAN::EMData::rot_scale_conv(), EMAN::Quaternion::to_angle(), EMAN::Quaternion::to_axis(), and trfind_().
| #define quadpi 3.141592653589793238462643383279502884197 |
| #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 |
Definition at line 4323 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_line_in3d(), EMAN::Util::cml_line_insino(), and EMAN::Util::cml_line_insino_all().
| #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, | |||
| j | ) | RI [(i-1) + ((j-1)*3)] |
| #define sign | ( | x, | |||
| y | ) | (((((y)>0)?(1):(-1))*(y!=0))*(x)) |
Definition at line 6788 of file util_sparx.cpp.
Referenced by EMAN::Processor::EMFourierFilterFunc(), EMAN::nnSSNR_ctfReconstructor::setup(), and EMAN::nn4_ctfReconstructor::setup().
| #define SS | ( | I, | |||
| J | ) | SS [I-1 + (J-1)*6] |
Definition at line 5611 of file util_sparx.cpp.
| #define SS | ( | I, | |||
| J | ) | SS [I-1 + (J-1)*6] |
Definition at line 5611 of file util_sparx.cpp.
| #define SS | ( | I | ) | 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 | ( | i | ) | 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 | ( | i | ) | t7[i-1] |
Definition at line 3190 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ns(), and EMAN::Util::Crosrng_sm_psi().
| #define tab1 | ( | i | ) | tab1[i-1] |
Definition at line 2639 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), and fftr_q().
| #define theta | ( | i | ) | theta [i-1] |
Definition at line 6800 of file util_sparx.cpp.
Referenced by ali3d_d(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), dcstep_(), EMAN::Util::even_angles(), fcalc(), fgcalc(), EMAN::file_store::get_image(), EMAN::Util::hsortd(), LBD_Cart(), main(), mainlb_(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), recons3d_4nn(), recons3d_CGLS_mpi_Cart(), recons3d_HyBR_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), EMAN::Transform::set_rotation(), EMAN::ChaoProjector::setdm(), trans_(), unified(), and EMAN::Util::vrdg().
| #define thetast | ( | i | ) | 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 | ( | i | ) | ts [i-1] |
Definition at line 6804 of file util_sparx.cpp.
| #define VP | ( | i | ) | VP [i-1] |
| #define VV | ( | i | ) | VV [i-1] |
| #define W | ( | i, | |||
| j | ) | Wptr [i-1+((j-1)*Wnx)] |
Definition at line 5609 of file util_sparx.cpp.
| #define W | ( | i, | |||
| j | ) | Wptr [i-1+((j-1)*Wnx)] |
Definition at line 5609 of file util_sparx.cpp.
Referenced by EMAN::Util::getBaldwinGridWeights(), EMAN::Util::WTF(), and EMAN::Util::WTM().
| #define weight | ( | i | ) | weight [i-1] |
Definition at line 6802 of file util_sparx.cpp.
Referenced by ali3d_d(), EMAN::FRCCmp::cmp(), EMAN::FourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::do_insert_slice_work(), EMAN::BaldwinWoolfordReconstructor::finish(), EMAN::BaldwinWoolfordReconstructor::insert_pixel(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), and EMAN::Util::vrdg().
| #define xcmplx | ( | i, | |||
| j | ) | 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, | |||
| j | ) | xim[(j-1)*nsam + i-1] |
Definition at line 2161 of file util_sparx.cpp.
Referenced by EMAN::Util::bilinear(), EMAN::Util::Polar2D(), and EMAN::Util::Polar2Dm().
| 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.
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.
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_ */
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 | ) |
| 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